feature: lab5 almost done, save commit

This commit is contained in:
Danil Markov 2023-12-19 13:58:28 +04:00
parent 21597aebe4
commit 6b9b374c48
53 changed files with 1157 additions and 484 deletions

150
.idea/workspace.xml generated
View File

@ -10,40 +10,60 @@
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="7c94e195-a540-483e-9a1c-11797aeb1741" name="Changes" comment="feature: lab4 maybe done"> <list default="true" id="7c94e195-a540-483e-9a1c-11797aeb1741" name="Changes" comment="feature: lab4 maybe done">
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/ServerService.kt" afterDir="false" /> <change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/model/BasketRemote.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/ServiceRemoteMediator.kt" afterDir="false" /> <change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/model/BasketServiceRemote.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/repository/RestBasketRepository.kt" afterDir="false" /> <change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/model/OrderRemote.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/repository/RestOrderRepository.kt" afterDir="false" /> <change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/model/OrderServiceRemote.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/repository/RestServiceRepository.kt" afterDir="false" /> <change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/model/ServiceRemote.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/repository/RestUserRepository.kt" afterDir="false" /> <change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/model/UserRemote.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/dao/RemoteKeysDao.kt" afterDir="false" /> <change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/model/UserRemoteSignIn.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/repository/RemoteKeysRepository.kt" afterDir="false" /> <change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/businessLogic/repository/BasketRepository.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/model/RemoteKeys.kt" afterDir="false" /> <change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/businessLogic/repository/OrderRepository.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/businessLogic/repository/RemoteKeyRepository.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/businessLogic/repository/ServiceRepository.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/businessLogic/repository/UserRepository.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/build.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/app/build.gradle.kts" afterDir="false" /> <change beforePath="$PROJECT_DIR$/app/build.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/app/build.gradle.kts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/App.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/App.kt" afterDir="false" /> <change beforePath="$PROJECT_DIR$/app/src/main/AndroidManifest.xml" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/AndroidManifest.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/AppContainer.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/di/AppContainer.kt" afterDir="false" /> <change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/ServerService.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/ServerService.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/AppDataContainer.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/di/AppDataContainer.kt" afterDir="false" /> <change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/ServiceRemoteMediator.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/ServiceRemoteMediator.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/dao/BasketDao.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/dao/BasketDao.kt" afterDir="false" /> <change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/repository/RestBasketRepository.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/repository/RestBasketRepository.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/dao/OrderDao.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/dao/OrderDao.kt" afterDir="false" /> <change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/repository/RestOrderRepository.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/repository/RestOrderRepository.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/dao/ServiceDao.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/dao/ServiceDao.kt" afterDir="false" /> <change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/repository/RestServiceRepository.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/repository/RestServiceRepository.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/dao/UserDao.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/dao/UserDao.kt" afterDir="false" /> <change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/repository/RestUserRepository.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/api/repository/RestUserRepository.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/composeui/Basket/Basket.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/composeui/Basket/Basket.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/composeui/Basket/BasketItemUI.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/composeui/Basket/BasketItemUI.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/composeui/List_of_Services/AddService.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/composeui/List_of_Services/AddService.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/composeui/List_of_Services/ListOfServices.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/composeui/List_of_Services/ListOfServices.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/composeui/List_of_Services/Service.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/composeui/List_of_Services/Service.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/composeui/Orders/Orders.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/composeui/Orders/Orders.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/composeui/Profile/Login.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/composeui/Profile/Login.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/composeui/Profile/ProfileChange.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/composeui/Profile/ProfileChange.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/composeui/Profile/Registration.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/composeui/Profile/Registration.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/AppDatabase.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/AppDatabase.kt" afterDir="false" /> <change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/AppDatabase.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/AppDatabase.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/repository/BasketRepository.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/repository/BasketRepository.kt" afterDir="false" /> <change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/dao/ServiceDao.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/dao/ServiceDao.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/repository/OrderRepository.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/repository/OrderRepository.kt" afterDir="false" /> <change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/dao/UserDao.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/dao/UserDao.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/repository/ServiceRepository.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/repository/ServiceRepository.kt" afterDir="false" /> <change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/repository/BasketRepository.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/repository/BasketRepositoryImpl.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/repository/UserRepository.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/repository/UserRepository.kt" afterDir="false" /> <change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/repository/OrderRepository.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/repository/OrderRepositoryImpl.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/viewmodel/BasketViewModel.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/viewmodel/BasketViewModel.kt" afterDir="false" /> <change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/repository/RemoteKeysRepository.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/repository/RemoteKeysRepositoryImpl.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/viewmodel/OrderViewModel.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/viewmodel/OrderViewModel.kt" afterDir="false" /> <change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/repository/ServiceRepository.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/repository/ServiceRepositoryImpl.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/viewmodel/ServiceViewModel.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/viewmodel/ServiceViewModel.kt" afterDir="false" /> <change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/repository/UserRepository.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/database/repository/UserRepositoryImpl.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/viewmodel/UserViewModel.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/viewmodel/UserViewModel.kt" afterDir="false" /> <change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/di/AppContainer.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/di/AppContainer.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/di/AppDataContainer.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/di/AppDataContainer.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/model/RemoteKeys.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/model/RemoteKeys.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/model/User.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/model/User.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/viewmodel/AppViewModelProvider.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/businessLogic/viewmodel/AppViewModelProvider.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/viewmodel/BasketViewModel.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/businessLogic/viewmodel/BasketViewModel.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/viewmodel/OrderViewModel.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/businessLogic/viewmodel/OrderViewModel.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/viewmodel/ServiceViewModel.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/businessLogic/viewmodel/ServiceViewModel.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/viewmodel/UserViewModel.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/myapplication/businessLogic/viewmodel/UserViewModel.kt" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" /> <option name="LAST_RESOLUTION" value="IGNORE" />
</component> </component>
<component name="ExecutionTargetManager" SELECTED_TARGET="device_and_snapshot_combo_box_target[C:\Users\Danil\.android\avd\Pixel_3a_API_34_extension_level_7_x86_64.avd]" /> <component name="ExecutionTargetManager" SELECTED_TARGET="device_and_snapshot_combo_box_target[adb-6681ed71-4kOMN8._adb-tls-connect._tcp]" />
<component name="ExternalProjectsData"> <component name="ExternalProjectsData">
<projectState path="$PROJECT_DIR$"> <projectState path="$PROJECT_DIR$">
<ProjectState /> <ProjectState />
@ -54,8 +74,8 @@
<list> <list>
<option value="resourceFile" /> <option value="resourceFile" />
<option value="Class" /> <option value="Class" />
<option value="Kotlin Interface" />
<option value="Kotlin Class" /> <option value="Kotlin Class" />
<option value="Kotlin Interface" />
</list> </list>
</option> </option>
</component> </component>
@ -83,34 +103,35 @@
<option name="hideEmptyMiddlePackages" value="true" /> <option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" /> <option name="showLibraryContents" value="true" />
</component> </component>
<component name="PropertiesComponent"><![CDATA[{ <component name="PropertiesComponent">{
"keyToString": { &quot;keyToString&quot;: {
"ApkExportedModule": "My_Application.app", &quot;ApkExportedModule&quot;: &quot;My_Application.app&quot;,
"ExportApk.ApkPathForMy_Application.app": "C:\\Users\\Danil\\Desktop\\MDP\\labs\\app", &quot;ExportApk.ApkPathForMy_Application.app&quot;: &quot;C:\\Users\\Danil\\Desktop\\MDP\\labs\\app&quot;,
"PROJECT_TRUSTED_KEY": "true", &quot;PROJECT_TRUSTED_KEY&quot;: &quot;true&quot;,
"RunOnceActivity.OpenProjectViewOnStart": "true", &quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
"RunOnceActivity.ShowReadmeOnStart": "true", &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
"RunOnceActivity.cidr.known.project.marker": "true", &quot;RunOnceActivity.cidr.known.project.marker&quot;: &quot;true&quot;,
"cidr.known.project.marker": "true", &quot;ToolWindowLogcat.ShowToolbar&quot;: &quot;false&quot;,
"com.android.tools.idea.devicemanager.tab": "Physical", &quot;cidr.known.project.marker&quot;: &quot;true&quot;,
"last_opened_file_path": "C:/Users/Danil/Downloads/test", &quot;com.android.tools.idea.devicemanager.tab&quot;: &quot;Physical&quot;,
"project.structure.last.edited": "Modules", &quot;last_opened_file_path&quot;: &quot;C:/Users/Danil/Downloads/test&quot;,
"project.structure.proportion": "0.17", &quot;project.structure.last.edited&quot;: &quot;Modules&quot;,
"project.structure.side.proportion": "0.2", &quot;project.structure.proportion&quot;: &quot;0.17&quot;,
"settings.editor.selected.configurable": "emulator" &quot;project.structure.side.proportion&quot;: &quot;0.2&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;emulator&quot;
}, },
"keyToStringList": { &quot;keyToStringList&quot;: {
"ExportApk.BuildVariants": [ &quot;ExportApk.BuildVariants&quot;: [
"release" &quot;release&quot;
], ],
"com.android.tools.idea.sqlite.queryhistory": [ &quot;com.android.tools.idea.sqlite.queryhistory&quot;: [
"insert into tbl_user values (1, \"Danil\", \"Markov\", \"danil@mail.ru\", \"123\", \"ADMIN\", null)", &quot;insert into tbl_user values (1, \&quot;Danil\&quot;, \&quot;Markov\&quot;, \&quot;danil@mail.ru\&quot;, \&quot;123\&quot;, \&quot;ADMIN\&quot;, null)&quot;,
"delete from tbl_user where userId = 6", &quot;delete from tbl_user where userId = 6&quot;,
"delete from tbl_user where userId = 4", &quot;delete from tbl_user where userId = 4&quot;,
"delete from tbl_user where userId = 2" &quot;delete from tbl_user where userId = 2&quot;
] ]
} }
}]]></component> }</component>
<component name="PsdUISettings"> <component name="PsdUISettings">
<option name="MODULE_TAB" value="Signing Configs" /> <option name="MODULE_TAB" value="Signing Configs" />
<option name="LAST_EDITED_SIGNING_CONFIG" value="debug" /> <option name="LAST_EDITED_SIGNING_CONFIG" value="debug" />
@ -126,11 +147,12 @@
<recent name="C:\Users\Danil\Desktop\MDP\labs\app\src\main\java\com\example\myapplication\UIComponents" /> <recent name="C:\Users\Danil\Desktop\MDP\labs\app\src\main\java\com\example\myapplication\UIComponents" />
</key> </key>
<key name="MoveKotlinTopLevelDeclarationsDialog.RECENTS_KEY"> <key name="MoveKotlinTopLevelDeclarationsDialog.RECENTS_KEY">
<recent name="com.example.myapplication.businessLogic.repository" />
<recent name="com.example.myapplication.di" /> <recent name="com.example.myapplication.di" />
</key> </key>
</component> </component>
<component name="RunManager" selected="Android App.app"> <component name="RunManager" selected="Android App.app">
<configuration name="App" type="AndroidRunConfigurationType" factoryName="Android App" temporary="true"> <configuration name="MainActivity" type="AndroidRunConfigurationType" factoryName="Android App" temporary="true">
<module name="My_Application.app.main" /> <module name="My_Application.app.main" />
<option name="DEPLOY" value="true" /> <option name="DEPLOY" value="true" />
<option name="DEPLOY_APK_FROM_BUNDLE" value="false" /> <option name="DEPLOY_APK_FROM_BUNDLE" value="false" />
@ -189,7 +211,7 @@
<option name="NATIVE_MEMORY_SAMPLE_RATE_BYTES" value="2048" /> <option name="NATIVE_MEMORY_SAMPLE_RATE_BYTES" value="2048" />
</Profilers> </Profilers>
<option name="DEEP_LINK" value="" /> <option name="DEEP_LINK" value="" />
<option name="ACTIVITY_CLASS" value="com.example.myapplication.App" /> <option name="ACTIVITY_CLASS" value="com.example.myapplication.MainActivity" />
<option name="SEARCH_ACTIVITY_IN_GLOBAL_SCOPE" value="false" /> <option name="SEARCH_ACTIVITY_IN_GLOBAL_SCOPE" value="false" />
<option name="SKIP_ACTIVITY_VALIDATION" value="false" /> <option name="SKIP_ACTIVITY_VALIDATION" value="false" />
<method v="2"> <method v="2">
@ -271,8 +293,9 @@
</configuration> </configuration>
<recent_temporary> <recent_temporary>
<list> <list>
<item itemvalue="Android App.MainActivity" />
<item itemvalue="Kotlin script (Beta).build.gradle.kts" />
<item itemvalue="Kotlin script (Beta).build.gradle.kts" /> <item itemvalue="Kotlin script (Beta).build.gradle.kts" />
<item itemvalue="Android App.App" />
</list> </list>
</recent_temporary> </recent_temporary>
</component> </component>
@ -367,25 +390,20 @@
<component name="XDebuggerManager"> <component name="XDebuggerManager">
<breakpoint-manager> <breakpoint-manager>
<breakpoints> <breakpoints>
<line-breakpoint enabled="true" type="kotlin-line">
<url>file://$PROJECT_DIR$/app/src/main/java/com/example/myapplication/viewmodel/OrderViewModel.kt</url>
<line>38</line>
<option name="timeStamp" value="18" />
</line-breakpoint>
<line-breakpoint enabled="true" type="kotlin-line">
<url>file://$PROJECT_DIR$/app/src/main/java/com/example/myapplication/viewmodel/OrderViewModel.kt</url>
<line>36</line>
<option name="timeStamp" value="19" />
</line-breakpoint>
<line-breakpoint enabled="true" type="kotlin-line"> <line-breakpoint enabled="true" type="kotlin-line">
<url>file://$PROJECT_DIR$/app/src/main/java/com/example/myapplication/composeui/Navbar/NavController.kt</url> <url>file://$PROJECT_DIR$/app/src/main/java/com/example/myapplication/composeui/Navbar/NavController.kt</url>
<line>63</line> <line>63</line>
<option name="timeStamp" value="23" /> <option name="timeStamp" value="23" />
</line-breakpoint> </line-breakpoint>
<line-breakpoint enabled="true" type="kotlin-line"> <line-breakpoint enabled="true" type="kotlin-line">
<url>file://$PROJECT_DIR$/app/src/main/java/com/example/myapplication/viewmodel/ServiceViewModel.kt</url> <url>file://$PROJECT_DIR$/app/src/main/java/com/example/myapplication/businessLogic/viewmodel/BasketViewModel.kt</url>
<line>30</line> <line>97</line>
<option name="timeStamp" value="25" /> <option name="timeStamp" value="39" />
</line-breakpoint>
<line-breakpoint enabled="true" type="kotlin-line">
<url>file://$PROJECT_DIR$/app/src/main/java/com/example/myapplication/businessLogic/viewmodel/OrderViewModel.kt</url>
<line>48</line>
<option name="timeStamp" value="47" />
</line-breakpoint> </line-breakpoint>
</breakpoints> </breakpoints>
</breakpoint-manager> </breakpoint-manager>

View File

@ -79,8 +79,9 @@ dependencies {
implementation ("io.coil-kt:coil-compose:1.4.0") implementation ("io.coil-kt:coil-compose:1.4.0")
implementation ("com.google.code.gson:gson:2.9.0") implementation ("com.google.code.gson:gson:2.9.0")
implementation("androidx.navigation:navigation-compose:2.7.5") implementation("androidx.navigation:navigation-compose:2.7.5")
implementation ("androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0-beta01") implementation ("androidx.lifecycle:lifecycle-viewmodel-compose:2.4.0-alpha03")
//Paging
implementation ("androidx.paging:paging-compose:3.2.1") implementation ("androidx.paging:paging-compose:3.2.1")
implementation ("androidx.paging:paging-runtime:3.2.1") implementation ("androidx.paging:paging-runtime:3.2.1")
@ -91,4 +92,12 @@ dependencies {
kapt("androidx.room:room-compiler:$room_version") kapt("androidx.room:room-compiler:$room_version")
implementation("androidx.room:room-ktx:$room_version") implementation("androidx.room:room-ktx:$room_version")
implementation("androidx.room:room-paging:$room_version") implementation("androidx.room:room-paging:$room_version")
// retrofit
val retrofitVersion = "2.9.0"
implementation("com.squareup.retrofit2:retrofit:$retrofitVersion")
implementation("com.squareup.okhttp3:logging-interceptor:4.11.0")
implementation("androidx.paging:paging-compose:3.2.1")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1")
implementation("com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0")
} }

View File

@ -2,6 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<application <application
android:name=".App" android:name=".App"

View File

@ -1,10 +1,147 @@
package com.example.myapplication.api package com.example.myapplication.api
import com.example.myapplication.api.model.BasketServiceRemote
import com.example.myapplication.api.model.OrderRemote
import com.example.myapplication.api.model.OrderServiceRemote
import com.example.myapplication.api.model.ServiceRemote
import com.example.myapplication.api.model.UserRemote
import com.example.myapplication.api.model.UserRemoteSignIn
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import kotlinx.serialization.json.Json
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Path
import retrofit2.http.Query
interface ServerService { interface ServerService {
//SNEAKER
@GET("service/get/{id}")
suspend fun getService(
@Path("id") id: Int,
): ServiceRemote
@GET("service/getAll")
suspend fun getServices(
@Query("page") page: Int,
@Query("size") size: Int,
): List<ServiceRemote>
@POST("service/create")
suspend fun createService(
@Body service: ServiceRemote,
): ServiceRemote
@PUT("service/update/{id}")
suspend fun updateService(
@Path("id") id: Int,
@Body service: ServiceRemote
): ServiceRemote
@DELETE("service/delete/{id}")
suspend fun deleteService(
@Path("id") id: Int
)
//USER
@POST("user/signup")
suspend fun SignUp(
@Body user: UserRemote,
): UserRemote
@POST("user/signin")
suspend fun SignIn(
@Body user: UserRemoteSignIn
): UserRemote
//BASKET
@POST("basket/addServiceToBasket")
suspend fun addServiceToBasket(
@Body basketService: BasketServiceRemote
)
@GET("basket/getUserBasketServices/{id}")
suspend fun getUserBasketServices(
@Path("id") id: Int
): List<ServiceRemote>
@GET("basket/getUserBasket/{id}")
suspend fun getUserBasket(
@Path("id") id: Int
): Int
@GET("basket/getQuantity/{basketId}/{serviceId}")
suspend fun getQuantity(
@Path("basketId") basketId: Int,
@Path("serviceId") serviceId: Int,
): Int
@PUT("basket/incrementQuantity/{basketId}/{serviceId}")
suspend fun increment(
@Path("basketId") basketId: Int,
@Path("serviceId") serviceId: Int,
)
@PUT("basket/decrementQuantity/{basketId}/{serviceId}")
suspend fun decrement(
@Path("basketId") basketId: Int,
@Path("serviceId") serviceId: Int,
)
@GET("basket/getService/{basketId}/{serviceId}")
suspend fun getService(
@Path("basketId") basketId: Int,
@Path("serviceId") serviceId: Int,
): Boolean
@GET("basket/removeService/{basketId}/{serviceId}")
suspend fun deleteServiceFromBasket(
@Path("basketId") basketId: Int,
@Path("serviceId") serviceId: Int,
)
@GET("basket/getUserPrice/{userId}")
suspend fun getTotalPriceForUserBasket(
@Path("userId") userId: Int
): Double
@GET("basket/deleteAllServiceFromBasket/{basketId}")
suspend fun deleteAllServiceFromBasket(
@Path("basketId") basketId: Int
)
//ORDER
@POST("order/addServiceToOrder")
suspend fun addServiceToOrder(
@Body orderService: OrderServiceRemote
)
@POST("order/create")
suspend fun createOrder(
@Body order: OrderRemote
): Long
@GET("order/getUserOrders/{userId}")
suspend fun getUserOrders(
@Path("userId") userId: Int
) : List<OrderRemote>
@GET("order/getServiceFromOrder/{orderId}")
suspend fun getServiceFromOrder(
@Path("orderId") orderId: Int
) : List<ServiceRemote>
@GET("order/deleteOrder/{orderId}")
suspend fun deleteOrder(
@Path("orderId") orderId: Int
)
companion object { companion object {
private const val BASE_URL = "https://localhost:8080/api/" private const val BASE_URL = "https://ftkfjb1l-8080.euw.devtunnels.ms/api/"
@Volatile @Volatile
private var INSTANCE: ServerService? = null private var INSTANCE: ServerService? = null
@ -18,7 +155,7 @@ interface ServerService {
.client(client) .client(client)
.addConverterFactory(Json.asConverterFactory("application/json".toMediaType())) .addConverterFactory(Json.asConverterFactory("application/json".toMediaType()))
.build() .build()
.create(BackendService::class.java) .create(ServerService::class.java)
.also { INSTANCE = it } .also { INSTANCE = it }
} }
} }

View File

@ -1,20 +1,36 @@
package com.example.myapplication.api package com.example.myapplication.api
import android.net.http.HttpException
import android.os.Build
import androidx.annotation.RequiresExtension
import androidx.paging.ExperimentalPagingApi
import androidx.paging.LoadType
import androidx.paging.PagingState
import androidx.paging.RemoteMediator
import androidx.room.withTransaction
import com.example.myapplication.api.model.toService
import com.example.myapplication.database.AppDatabase import com.example.myapplication.database.AppDatabase
import com.example.myapplication.database.repository.RemoteKeysRepositoryImpl
import com.example.myapplication.database.repository.ServiceRepositoryImpl
import com.example.myapplication.model.RemoteKeyType
import com.example.myapplication.model.RemoteKeys
import com.example.myapplication.model.Service
import java.io.IOException
@OptIn(ExperimentalPagingApi::class) @OptIn(ExperimentalPagingApi::class)
class ServiceRemoteMediator( class ServiceRemoteMediator(
private val service: ServerService, private val service: ServerService,
private val sneakerRepository: SneakerRepoImpl, private val serviceRepository: ServiceRepositoryImpl,
private val database: AppDatabase, private val database: AppDatabase,
private val dbRemoteKeyRepository: RemoteKeysRepositoryImpl private val dbRemoteKeyRepository: RemoteKeysRepositoryImpl
) : RemoteMediator<Int, Sneaker>() { ) : RemoteMediator<Int, Service>() {
override suspend fun initialize(): InitializeAction { override suspend fun initialize(): InitializeAction {
return InitializeAction.LAUNCH_INITIAL_REFRESH return InitializeAction.LAUNCH_INITIAL_REFRESH
} }
@RequiresExtension(extension = Build.VERSION_CODES.S, version = 7)
override suspend fun load( override suspend fun load(
loadType: LoadType, loadType: LoadType,
state: PagingState<Int, Sneaker> state: PagingState<Int, Service>
): MediatorResult { ): MediatorResult {
val page = when (loadType) { val page = when (loadType) {
LoadType.REFRESH -> { LoadType.REFRESH -> {
@ -36,25 +52,25 @@ class ServiceRemoteMediator(
} }
try { try {
val sneakers = service.getSneakers(page, state.config.pageSize).map { it.toSneaker() } val services = service.getServices(page, state.config.pageSize).map { it.toService() }
val endOfPaginationReached = sneakers.isEmpty() val endOfPaginationReached = services.isEmpty()
database.withTransaction { database.withTransaction {
if (loadType == LoadType.REFRESH) { if (loadType == LoadType.REFRESH) {
dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.SNEAKER) dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.SERVICE)
sneakerRepository.clearSneakers() serviceRepository.clearServices()
} }
val prevKey = if (page == 1) null else page - 1 val prevKey = if (page == 1) null else page - 1
val nextKey = if (endOfPaginationReached) null else page + 1 val nextKey = if (endOfPaginationReached) null else page + 1
val keys = sneakers.map { val keys = services.map {
RemoteKeys( RemoteKeys(
entityId = it.sneakerId!!, entityId = it.serviceId!!,
type = RemoteKeyType.SNEAKER, type = RemoteKeyType.SERVICE,
prevKey = prevKey, prevKey = prevKey,
nextKey = nextKey nextKey = nextKey
) )
} }
dbRemoteKeyRepository.createRemoteKeys(keys) dbRemoteKeyRepository.createRemoteKeys(keys)
sneakerRepository.insertSneakers(sneakers) serviceRepository.insertServices(services)
} }
return MediatorResult.Success(endOfPaginationReached = endOfPaginationReached) return MediatorResult.Success(endOfPaginationReached = endOfPaginationReached)
} catch (exception: IOException) { } catch (exception: IOException) {
@ -64,26 +80,26 @@ class ServiceRemoteMediator(
} }
} }
private suspend fun getRemoteKeyForLastItem(state: PagingState<Int, Sneaker>): RemoteKeys? { private suspend fun getRemoteKeyForLastItem(state: PagingState<Int, Service>): RemoteKeys? {
return state.pages.lastOrNull { it.data.isNotEmpty() }?.data?.lastOrNull() return state.pages.lastOrNull { it.data.isNotEmpty() }?.data?.lastOrNull()
?.let { sneaker -> ?.let { service ->
sneaker.sneakerId?.let { dbRemoteKeyRepository.getAllRemoteKeys(it, RemoteKeyType.SNEAKER) } service.serviceId?.let { dbRemoteKeyRepository.getAllRemoteKeys(it, RemoteKeyType.SERVICE) }
} }
} }
private suspend fun getRemoteKeyForFirstItem(state: PagingState<Int, Sneaker>): RemoteKeys? { private suspend fun getRemoteKeyForFirstItem(state: PagingState<Int, Service>): RemoteKeys? {
return state.pages.firstOrNull { it.data.isNotEmpty() }?.data?.firstOrNull() return state.pages.firstOrNull { it.data.isNotEmpty() }?.data?.firstOrNull()
?.let { sneaker -> ?.let { service ->
sneaker.sneakerId?.let { dbRemoteKeyRepository.getAllRemoteKeys(it, RemoteKeyType.SNEAKER) } service.serviceId?.let { dbRemoteKeyRepository.getAllRemoteKeys(it, RemoteKeyType.SERVICE) }
} }
} }
private suspend fun getRemoteKeyClosestToCurrentPosition( private suspend fun getRemoteKeyClosestToCurrentPosition(
state: PagingState<Int, Sneaker> state: PagingState<Int, Service>
): RemoteKeys? { ): RemoteKeys? {
return state.anchorPosition?.let { position -> return state.anchorPosition?.let { position ->
state.closestItemToPosition(position)?.sneakerId?.let { sneakerUid -> state.closestItemToPosition(position)?.serviceId?.let { serviceUid ->
dbRemoteKeyRepository.getAllRemoteKeys(sneakerUid, RemoteKeyType.SNEAKER) dbRemoteKeyRepository.getAllRemoteKeys(serviceUid, RemoteKeyType.SERVICE)
} }
} }
} }

View File

@ -0,0 +1,9 @@
package com.example.myapplication.api.model
import kotlinx.serialization.Serializable
@Serializable
data class BasketRemote (
val id: Int? = 0,
val userId: Int = 0,
)

View File

@ -0,0 +1,23 @@
package com.example.myapplication.api.model
import com.example.myapplication.model.BasketService
import kotlinx.serialization.Serializable
@Serializable
data class BasketServiceRemote (
val basketId: Int = 0,
val serviceId: Int = 0,
val quantity: Int = 0
)
fun BasketServiceRemote.toBasketService(): BasketService = BasketService(
basketId,
serviceId,
quantity
)
fun BasketService.toBasketServiceRemote():BasketServiceRemote = BasketServiceRemote(
basketId,
serviceId,
quantity
)

View File

@ -0,0 +1,26 @@
package com.example.myapplication.api.model
import com.example.myapplication.model.Order
import kotlinx.serialization.Serializable
@Serializable
data class OrderRemote(
val id: Int? = 0,
val date: Long = 0L,
val total: Double = 0.0,
val creatorUserId: Int = 0
)
fun OrderRemote.toOrder(): Order = Order(
id,
date,
total,
creatorUserId
)
fun Order.toOrderRemote():OrderRemote = OrderRemote(
orderId,
date,
total,
creatorUserId
)

View File

@ -0,0 +1,23 @@
package com.example.myapplication.api.model
import com.example.myapplication.model.OrderService
import kotlinx.serialization.Serializable
@Serializable
data class OrderServiceRemote (
val orderId: Int = 0,
val serviceId: Int = 0,
val quantity: Int = 0
)
fun OrderServiceRemote.toOrderService(): OrderService = OrderService(
orderId,
serviceId,
quantity
)
fun OrderService.toOrderServiceRemote():OrderServiceRemote = OrderServiceRemote(
orderId,
serviceId,
quantity
)

View File

@ -0,0 +1,26 @@
package com.example.myapplication.api.model
import com.example.myapplication.model.Service
import kotlinx.serialization.Serializable
@Serializable
data class ServiceRemote (
val id: Int? = 0,
val name: String = "",
val price: Double = 0.0,
val photo: Int? = 0
)
fun ServiceRemote.toService(): Service = Service(
id,
name,
price,
photo
)
fun Service.toServiceRemote():ServiceRemote = ServiceRemote(
serviceId,
name,
price,
photo
)

View File

@ -0,0 +1,40 @@
package com.example.myapplication.api.model
import com.example.myapplication.model.RoleEnum
import com.example.myapplication.model.User
import kotlinx.serialization.Serializable
@Serializable
data class UserRemote (
val id: Int? = 0,
val name: String = "",
val surname: String = "",
val email: String = "",
val password: String = "",
val role: RoleEnum = RoleEnum.User,
val photo: Int? = 0,
val basketId: Int? = 0
)
fun UserRemote.toUser(): User = User(
id,
name,
surname,
email,
password,
role,
photo,
basketId
)
fun User.toUserRemote():UserRemote = UserRemote(
userId,
name,
surname,
email,
password,
role,
photo,
basketId
)

View File

@ -0,0 +1,9 @@
package com.example.myapplication.api.model
import kotlinx.serialization.Serializable
@Serializable
data class UserRemoteSignIn(
val email: String = "",
val password: String = "",
)

View File

@ -1,4 +1,76 @@
package com.example.myapplication.api.repository package com.example.myapplication.api.repository
class RestBasketRepository { import com.example.myapplication.api.ServerService
import com.example.myapplication.api.model.toBasketServiceRemote
import com.example.myapplication.api.model.toService
import com.example.myapplication.businessLogic.repository.BasketRepository
import com.example.myapplication.model.BasketService
import com.example.myapplication.model.Service
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
class RestBasketRepository(
private var service: ServerService
): BasketRepository {
override suspend fun insertBasketService(basketService: BasketService) {
service.addServiceToBasket(basketService.toBasketServiceRemote())
}
override suspend fun getBasketWithServices(id: Int): Flow<List<Service>> {
val servicesRemoteList = service.getUserBasketServices(id)
val servicesList = servicesRemoteList.map { it.toService() }
return flowOf(servicesList.toList())
}
override suspend fun getUserBasketId(id: Int): Flow<Int> {
return flowOf(service.getUserBasket(id))
}
override suspend fun getQuantity(basketId: Int, serviceId: Int): Int? {
return service.getQuantity(basketId, serviceId)
}
//
// override fun getAllBasket(): Flow<List<Basket>> {
// TODO("Not yet implemented")
// }
//
// override suspend fun delete(basket: Basket) {
// TODO("Not yet implemented")
// }
//
// override suspend fun createBasket(basket: Basket): Long {
// TODO("Not yet implemented")
// }
//
override suspend fun removeServiceFromBasket(basketId: Int, serviceId: Int) {
service.deleteServiceFromBasket(basketId, serviceId)
}
//
// override suspend fun updateServiceQuantity(basketId: Int, serviceId: Int, quantity: Int) {
// TODO("Not yet implemented")
// }
//
override suspend fun incrementServiceQuantity(basketId: Int, serviceId: Int) {
service.increment(basketId, serviceId)
}
override suspend fun decrementServiceQuantity(basketId: Int, serviceId: Int) {
service.decrement(basketId, serviceId)
}
//
// override suspend fun getQuantity(basketId: Int, serviceId: Int): Int? {
// TODO("Not yet implemented")
// }
//
override suspend fun existService(basketId: Int, serviceId: Int): Boolean {
return service.getService(basketId, serviceId)
}
override suspend fun getTotalPriceForUser(userId: Int): Double? {
return service.getTotalPriceForUserBasket(userId)
}
override suspend fun deleteAllServiceFromBasket(basketId: Int) {
service.deleteAllServiceFromBasket(basketId)
}
} }

View File

@ -1,4 +1,39 @@
package com.example.myapplication.api.repository package com.example.myapplication.api.repository
class RestOrderRepository { import com.example.myapplication.api.ServerService
import com.example.myapplication.api.model.toOrder
import com.example.myapplication.api.model.toOrderRemote
import com.example.myapplication.api.model.toOrderServiceRemote
import com.example.myapplication.api.model.toService
import com.example.myapplication.businessLogic.repository.OrderRepository
import com.example.myapplication.model.Order
import com.example.myapplication.model.OrderService
import com.example.myapplication.model.Service
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
class RestOrderRepository(private val server: ServerService): OrderRepository {
override suspend fun insert(order: Order): Long {
return server.createOrder(order.toOrderRemote())
}
override suspend fun addServiceToOrder(orderService: OrderService) {
server.addServiceToOrder(orderService.toOrderServiceRemote())
}
override suspend fun delete(order: Order) {
order.orderId?.let { this.server.deleteOrder(it) }
}
override suspend fun getServiceFromOrder(id: Int): Flow<List<Service>> {
val servicesRemoteList = server.getServiceFromOrder(id)
val servicesList = servicesRemoteList.map { it.toService() }
return flowOf(servicesList.toList())
}
override suspend fun getUserOrders(id: Int): Flow<List<Order>> {
val ordersRemoteList = server.getUserOrders(id)
val ordersList = ordersRemoteList.map { it.toOrder() }
return flowOf(ordersList.toList())
}
} }

View File

@ -1,4 +1,60 @@
package com.example.myapplication.api.repository package com.example.myapplication.api.repository
class RestServiceRepository { import androidx.paging.ExperimentalPagingApi
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import com.example.myapplication.api.ServerService
import com.example.myapplication.api.ServiceRemoteMediator
import com.example.myapplication.api.model.toService
import com.example.myapplication.api.model.toServiceRemote
import com.example.myapplication.businessLogic.repository.ServiceRepository
import com.example.myapplication.database.AppDatabase
import com.example.myapplication.database.repository.RemoteKeysRepositoryImpl
import com.example.myapplication.database.repository.ServiceRepositoryImpl
import com.example.myapplication.di.AppContainer
import com.example.myapplication.model.Service
import kotlinx.coroutines.flow.Flow
class RestServiceRepository(
private val service: ServerService,
private val dbServiceRepository: ServiceRepositoryImpl,
private val database: AppDatabase,
private val dbRemoteKeyRepository: RemoteKeysRepositoryImpl
) : ServiceRepository {
override suspend fun getAllServices(): Flow<PagingData<Service>> {
val pagingSourceFactory = {
dbServiceRepository.getAllServicesPagingSource()
}
@OptIn(ExperimentalPagingApi::class)
return Pager(
config = PagingConfig(
pageSize = AppContainer.LIMIT,
enablePlaceholders = false
),
remoteMediator = ServiceRemoteMediator(
service,
dbServiceRepository,
database,
dbRemoteKeyRepository,
),
pagingSourceFactory = pagingSourceFactory
).flow
}
override suspend fun getServiceById(id: Int): Service = service.getService(id).toService()
override suspend fun insert(service: Service) {
this.service.createService(service.toServiceRemote())
}
override suspend fun update(service: Service) {
service.serviceId?.let { this.service.updateService(it, service.toServiceRemote()) }
}
override suspend fun delete(service: Service) {
service.serviceId?.let { this.service.deleteService(it) }
}
} }

View File

@ -1,13 +1,27 @@
package com.example.myapplication.api.repository package com.example.myapplication.api.repository
import com.example.myapplication.api.ServerService import com.example.myapplication.api.ServerService
import com.example.myapplication.api.model.UserRemoteSignIn
import com.example.myapplication.api.model.toUser
import com.example.myapplication.api.model.toUserRemote
import com.example.myapplication.businessLogic.repository.UserRepository
import com.example.myapplication.model.User import com.example.myapplication.model.User
import com.example.myapplication.database.repository.UserRepository
class RestUserRepository( class RestUserRepository(
private var server: ServerService private var service: ServerService
): UserRepository { ): UserRepository {
override suspend fun createUser(user: User){ override suspend fun insert(user: User) {
server.SignUp(user.toUserRemote()) service.SignUp(user.toUserRemote())
}
override suspend fun update(user: User) {
println()
}
override suspend fun delete(user: User) {
println()
}
override suspend fun authUser(user: UserRemoteSignIn): User {
return service.SignIn(user).toUser()
} }
} }

View File

@ -0,0 +1,18 @@
package com.example.myapplication.businessLogic.repository
import com.example.myapplication.model.BasketService
import com.example.myapplication.model.Service
import kotlinx.coroutines.flow.Flow
interface BasketRepository {
suspend fun insertBasketService(basketService: BasketService)
suspend fun getBasketWithServices(id: Int): Flow<List<Service>>
suspend fun getUserBasketId(id: Int): Flow<Int>
suspend fun removeServiceFromBasket(basketId: Int, serviceId: Int)
suspend fun incrementServiceQuantity(basketId: Int, serviceId: Int)
suspend fun decrementServiceQuantity(basketId: Int, serviceId: Int)
suspend fun getQuantity(basketId: Int, serviceId: Int): Int?
suspend fun existService(basketId: Int, serviceId: Int): Boolean
suspend fun getTotalPriceForUser(userId: Int): Double?
suspend fun deleteAllServiceFromBasket(basketId: Int)
}

View File

@ -0,0 +1,14 @@
package com.example.myapplication.businessLogic.repository
import com.example.myapplication.model.Order
import com.example.myapplication.model.OrderService
import com.example.myapplication.model.Service
import kotlinx.coroutines.flow.Flow
interface OrderRepository {
suspend fun insert(order: Order): Long
suspend fun addServiceToOrder(orderService: OrderService)
suspend fun delete(order: Order)
suspend fun getServiceFromOrder(id: Int): Flow<List<Service>>
suspend fun getUserOrders(id: Int) : Flow<List<Order>>
}

View File

@ -0,0 +1,10 @@
package com.example.myapplication.businessLogic.repository
import com.example.myapplication.model.RemoteKeyType
import com.example.myapplication.model.RemoteKeys
interface RemoteKeyRepository {
suspend fun getAllRemoteKeys(id: Int, type: RemoteKeyType): RemoteKeys?
suspend fun createRemoteKeys(remoteKeys: List<RemoteKeys>)
suspend fun deleteRemoteKey(type: RemoteKeyType)
}

View File

@ -0,0 +1,13 @@
package com.example.myapplication.businessLogic.repository
import androidx.paging.PagingData
import com.example.myapplication.model.Service
import kotlinx.coroutines.flow.Flow
interface ServiceRepository {
suspend fun insert(service: Service)
suspend fun update(service: Service)
suspend fun delete(service: Service)
suspend fun getServiceById(id: Int): Service
suspend fun getAllServices(): Flow<PagingData<Service>>
}

View File

@ -0,0 +1,11 @@
package com.example.myapplication.businessLogic.repository
import com.example.myapplication.api.model.UserRemoteSignIn
import com.example.myapplication.model.User
interface UserRepository {
suspend fun insert(user: User)
suspend fun update(user: User)
suspend fun delete(user: User)
suspend fun authUser(user: UserRemoteSignIn): User
}

View File

@ -1,4 +1,4 @@
package com.example.myapplication.viewmodel package com.example.myapplication.businessLogic.viewmodel
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.CreationExtras import androidx.lifecycle.viewmodel.CreationExtras

View File

@ -0,0 +1,133 @@
package com.example.myapplication.businessLogic.viewmodel
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableDoubleStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.myapplication.GlobalUser
import com.example.myapplication.businessLogic.repository.BasketRepository
import com.example.myapplication.businessLogic.repository.OrderRepository
import com.example.myapplication.model.BasketService
import com.example.myapplication.model.Service
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
data class ServiceWithQuantity(val service: Service, val quantityStateFlow: MutableStateFlow<Int>)
class BasketViewModel(private val basketRepository: BasketRepository, private val orderRepository: OrderRepository) : ViewModel() {
private val _quantityMap = MutableStateFlow<Map<Int, MutableStateFlow<Int>>>(emptyMap())
val quantityMap: StateFlow<Map<Int, MutableStateFlow<Int>>> get() = _quantityMap
private val _total = mutableDoubleStateOf(0.00)
val total: State<Double> get() = _total
private val _myList = MutableStateFlow<List<Service>>(emptyList())
val myList: StateFlow<List<Service>> get() = _myList
private var _basketId = MutableStateFlow(0)
val basketId: StateFlow<Int> get() = _basketId
fun getQuantityState(basketId: Int, serviceId: Int): Flow<Int> {
val quantityMap = _quantityMap.value.toMutableMap()
val quantityStateFlow = quantityMap.getOrPut(serviceId) {
MutableStateFlow(0)
}
viewModelScope.launch {
val quantityFromDb = basketRepository.getQuantity(basketId, serviceId)
quantityFromDb?.let { quantityStateFlow.value = it }
}
_quantityMap.value = quantityMap.toMap()
return quantityStateFlow
}
suspend fun isServiceInBasket(basketId: Int, serviceId: Int): Boolean {
return basketRepository.existService(basketId, serviceId)
}
suspend fun addToBasket(serviceId: Int, quantity: Int) = viewModelScope.launch {
val basketId = GlobalUser.getInstance().getUser()?.basketId
val isServiceInBasket = isServiceInBasket(basketId!!, serviceId)
if (isServiceInBasket) {
incrementServiceQuantity(basketId, serviceId)
} else {
basketRepository.insertBasketService(BasketService(basketId, serviceId, quantity))
}
}
fun getBasketServices() {
viewModelScope.launch {
val basketId = GlobalUser.getInstance().getUser()?.basketId!!
basketRepository.getBasketWithServices(basketId)
.collect{services ->
_myList.value = services
}
}
}
fun getUsersBasket(id: Int) {
viewModelScope.launch{
val userBasketId = basketRepository.getUserBasketId(id).first()
withContext(Dispatchers.Main) {
_basketId.value = userBasketId
}
}
}
fun deleteServiceFromBasket(basketId: Int, serviceId: Int) {
viewModelScope.launch {
basketRepository.removeServiceFromBasket(basketId, serviceId)
_quantityMap.value.toMutableMap().apply {
remove(serviceId)
}
withContext(Dispatchers.Main){
updateSubTotal(GlobalUser.getInstance().getUser()?.userId!!)
}
}
}
fun incrementServiceQuantity(basketId: Int, serviceId: Int) {
viewModelScope.launch {
basketRepository.incrementServiceQuantity(basketId, serviceId)
val currentQuantity = getQuantityState(basketId, serviceId).first()
_quantityMap.value.toMutableMap().apply {
put(serviceId, MutableStateFlow(currentQuantity + 1))
}
updateSubTotal(GlobalUser.getInstance().getUser()?.userId!!)
}
}
fun decrementOrRemoveServiceQuantity(basketId: Int, serviceId: Int) {
viewModelScope.launch {
val currentQuantity = getQuantityState(basketId, serviceId).first()
if (currentQuantity > 1) {
basketRepository.decrementServiceQuantity(basketId, serviceId)
_quantityMap.value.toMutableMap().apply {
put(serviceId, MutableStateFlow(currentQuantity - 1))
}
}
else{
basketRepository.removeServiceFromBasket(basketId, serviceId)
_quantityMap.value.toMutableMap().apply {
remove(serviceId, MutableStateFlow(currentQuantity - 1))
}
getBasketServices()
}
updateSubTotal(GlobalUser.getInstance().getUser()?.userId!!)
}
}
fun updateSubTotal(userId: Int) {
viewModelScope.launch {
_total.doubleValue = getTotal(userId)
}
}
suspend fun getTotal(userId: Int): Double {
return basketRepository.getTotalPriceForUser(userId) ?: 0.00
}
}

View File

@ -1,4 +1,4 @@
package com.example.myapplication.viewmodel package com.example.myapplication.businessLogic.viewmodel
import androidx.compose.runtime.State import androidx.compose.runtime.State
import androidx.compose.runtime.mutableDoubleStateOf import androidx.compose.runtime.mutableDoubleStateOf
@ -6,13 +6,11 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.example.myapplication.GlobalUser import com.example.myapplication.GlobalUser
import com.example.myapplication.businessLogic.repository.BasketRepository
import com.example.myapplication.businessLogic.repository.OrderRepository
import com.example.myapplication.model.Order import com.example.myapplication.model.Order
import com.example.myapplication.model.OrderService import com.example.myapplication.model.OrderService
import com.example.myapplication.model.OrderWithServices
import com.example.myapplication.model.Service import com.example.myapplication.model.Service
import com.example.myapplication.model.UserWithOrder
import com.example.myapplication.database.repository.BasketRepository
import com.example.myapplication.database.repository.OrderRepository
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.util.Date import java.util.Date
@ -27,28 +25,23 @@ class OrderViewModel(private val orderRepository: OrderRepository, private val b
val userId = GlobalUser.getInstance().getUser()?.userId!! val userId = GlobalUser.getInstance().getUser()?.userId!!
val order = Order( val order = Order(
date = Date().time, date = Date().time,
total = getTotal(basketRepository.getUsersBasket(userId).basketId!!), total = getTotal(userId),
creatorUserId = GlobalUser.getInstance().getUser()?.userId!! creatorUserId = userId
) )
var orderId = orderRepository.insert(order) var orderId = orderRepository.insert(order)
for(service in selectedItems.value!!){ for(service in selectedItems.value!!){
val quantity = basketRepository.getQuantity(basketRepository.getUsersBasket(userId).basketId!!, service.serviceId!!) val orderService = OrderService( orderId.toInt(), service.serviceId!!, 1)
val orderService = OrderService( orderId.toInt(), service.serviceId!!, quantity!!) orderRepository.addServiceToOrder(orderService)
if (orderService != null) {
orderRepository.insertOrderService(orderService)
} }
} }
basketRepository.clearBasket(basketRepository.getUsersBasket(userId).basketId!!) suspend fun getOrderWithServices(id: Int) : Flow<List<Service>> {
return orderRepository.getServiceFromOrder(id)
} }
fun getOrderWithServices(id: Int) : Flow<OrderWithServices> { suspend fun getUserOrders(id: Int): Flow<List<Order>> {
return orderRepository.getOrderWithServices(id)
}
fun getUserOrders(id: Int): Flow<UserWithOrder> {
return orderRepository.getUserOrders(id) return orderRepository.getUserOrders(id)
} }
@ -65,6 +58,6 @@ class OrderViewModel(private val orderRepository: OrderRepository, private val b
} }
suspend fun getTotal(basketId: Int): Double { suspend fun getTotal(basketId: Int): Double {
return basketRepository.getTotalPriceForBasket(basketId) ?: 0.00 return basketRepository.getTotalPriceForUser(basketId) ?: 0.00
} }
} }

View File

@ -0,0 +1,53 @@
package com.example.myapplication.businessLogic.viewmodel
import androidx.compose.runtime.mutableDoubleStateOf
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.PagingData
import com.example.myapplication.R
import com.example.myapplication.businessLogic.repository.ServiceRepository
import com.example.myapplication.model.Service
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
class ServiceViewModel(private val serviceRepository: ServiceRepository): ViewModel() {
var name = mutableStateOf("")
var price = mutableDoubleStateOf(0.00)
var photo = mutableIntStateOf(R.drawable.image_service)
var service = mutableStateOf<Service>(Service(null,"", 0.0, null))
private val _serviceList = MutableStateFlow<PagingData<Service>>(PagingData.empty())
val serviceList: StateFlow<PagingData<Service>> get() = _serviceList
fun insertService() = viewModelScope.launch {
val service = Service(
name = name.value,
price = price.doubleValue,
photo = photo.intValue
)
serviceRepository.insert(service)
}
fun deleteService(service : Service) = viewModelScope.launch {
serviceRepository.delete(service)
}
fun updateService() = viewModelScope.launch {
val service = Service(
name = name.value,
price = price.doubleValue,
photo = R.drawable.image_service
)
serviceRepository.update(service)
}
fun getServiceList(){
viewModelScope.launch {
serviceRepository.getAllServices()
.collect{services ->
_serviceList.value = services
}
}
}
}

View File

@ -1,16 +1,18 @@
package com.example.myapplication.viewmodel package com.example.myapplication.businessLogic.viewmodel
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.example.myapplication.GlobalUser import com.example.myapplication.GlobalUser
import com.example.myapplication.R import com.example.myapplication.R
import com.example.myapplication.model.Basket import com.example.myapplication.api.model.UserRemoteSignIn
import com.example.myapplication.businessLogic.repository.BasketRepository
import com.example.myapplication.businessLogic.repository.UserRepository
import com.example.myapplication.model.RoleEnum import com.example.myapplication.model.RoleEnum
import com.example.myapplication.model.User import com.example.myapplication.model.User
import com.example.myapplication.database.repository.BasketRepository
import com.example.myapplication.database.repository.UserRepository
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class UserViewModel(private val userRepository: UserRepository, private val basketRepository: BasketRepository): ViewModel() { class UserViewModel(private val userRepository: UserRepository, private val basketRepository: BasketRepository): ViewModel() {
@ -19,32 +21,35 @@ class UserViewModel(private val userRepository: UserRepository, private val bask
var email = mutableStateOf("") var email = mutableStateOf("")
var password = mutableStateOf("") var password = mutableStateOf("")
var photo = mutableIntStateOf(R.drawable.icon_profile) var photo = mutableIntStateOf(R.drawable.icon_profile)
var isLoggedIn by mutableStateOf(false)
var isBusy by mutableStateOf(false)
// private val _loggedUser = MutableStateFlow(User(null,"null","null","null","null",RoleEnum.User))
// val loggedUser: StateFlow<User> = _loggedUser.asStateFlow()
fun createUser() = viewModelScope.launch { fun createUser() = viewModelScope.launch {
var user = User( val user = User(
name = name.value, name = name.value,
surname = surname.value, surname = surname.value,
email = email.value, email = email.value,
password = password.value, password = password.value,
role = RoleEnum.User role = RoleEnum.User,
photo = R.drawable.icon_profile
) )
// isBusy = true
userRepository.insert(user) userRepository.insert(user)
// isBusy = false
} }
fun authUser() = viewModelScope.launch { fun authUser() = viewModelScope.launch {
val user = userRepository.getUserByEmail(email.value) // isBusy = true
if(password.value.isNotEmpty() && user.password == password.value){ val user = userRepository.authUser(UserRemoteSignIn(email.value, password.value))
val globalUser = GlobalUser.getInstance() // isLoggedIn = true
globalUser.setUser(user) // isBusy = false
val basket = basketRepository.getUsersBasket(user.userId!!) GlobalUser.getInstance().setUser(user)
if(basket == null){
basketRepository.createBasket(Basket(null, user.userId))
}
}
} }
fun updateUser() = viewModelScope.launch { fun updateUser() = viewModelScope.launch {
var updateUser = GlobalUser.getInstance().getUser() val updateUser = GlobalUser.getInstance().getUser()
if(email.value != "") if(email.value != "")
updateUser?.email = email.value updateUser?.email = email.value
else else
@ -71,3 +76,4 @@ class UserViewModel(private val userRepository: UserRepository, private val bask
return android.util.Patterns.EMAIL_ADDRESS.matcher(email.value).matches() return android.util.Patterns.EMAIL_ADDRESS.matcher(email.value).matches()
} }
} }

View File

@ -17,6 +17,7 @@ import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
@ -27,16 +28,17 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import com.example.myapplication.GlobalUser import com.example.myapplication.GlobalUser
import com.example.myapplication.businessLogic.viewmodel.AppViewModelProvider
import com.example.myapplication.businessLogic.viewmodel.BasketViewModel
import com.example.myapplication.businessLogic.viewmodel.OrderViewModel
import com.example.myapplication.composeui.Profile.Login import com.example.myapplication.composeui.Profile.Login
import com.example.myapplication.model.Service
import com.example.myapplication.ui.theme.BlueMain import com.example.myapplication.ui.theme.BlueMain
import com.example.myapplication.ui.theme.GreenBtn import com.example.myapplication.ui.theme.GreenBtn
import com.example.myapplication.viewmodel.AppViewModelProvider
import com.example.myapplication.viewmodel.BasketViewModel
import com.example.myapplication.viewmodel.OrderViewModel
@Composable @Composable
fun Basket(navController : NavHostController, basketViewModel: BasketViewModel = viewModel(factory = AppViewModelProvider.Factory), orderViewModel: OrderViewModel = viewModel(factory = AppViewModelProvider.Factory)){ fun Basket(navController : NavHostController,
basketViewModel: BasketViewModel = viewModel(factory = AppViewModelProvider.Factory),
orderViewModel: OrderViewModel = viewModel(factory = AppViewModelProvider.Factory)){
val user = GlobalUser.getInstance().getUser() val user = GlobalUser.getInstance().getUser()
if (user == null){ if (user == null){
@ -44,7 +46,11 @@ fun Basket(navController : NavHostController, basketViewModel: BasketViewModel =
}else{ }else{
basketViewModel.updateSubTotal(user.userId!!) basketViewModel.updateSubTotal(user.userId!!)
val total = basketViewModel.total.value val total = basketViewModel.total.value
val basketList by basketViewModel.getBasketServices(user.userId).collectAsState(initial = null) LaunchedEffect(basketViewModel){
basketViewModel.getBasketServices()
}
val serviceList by basketViewModel.myList.collectAsState()
orderViewModel.updateSelectedItems(serviceList)
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
@ -53,13 +59,9 @@ fun Basket(navController : NavHostController, basketViewModel: BasketViewModel =
.padding(bottom = 60.dp), .padding(bottom = 60.dp),
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
val serviceList: List<Service>? = basketList?.services
if (serviceList != null){
orderViewModel.updateSelectedItems(serviceList)
for (item in serviceList){ for (item in serviceList){
BasketItemUI(item = item) BasketItemUI(item = item)
} }
}
Box(modifier = Modifier Box(modifier = Modifier
.clip(RoundedCornerShape(15.dp, 15.dp, 0.dp, 0.dp)) .clip(RoundedCornerShape(15.dp, 15.dp, 0.dp, 0.dp))
.background(Color.Transparent) .background(Color.Transparent)

View File

@ -21,11 +21,9 @@ import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
@ -35,28 +33,23 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.myapplication.GlobalUser import com.example.myapplication.GlobalUser
import com.example.myapplication.businessLogic.viewmodel.AppViewModelProvider
import com.example.myapplication.businessLogic.viewmodel.BasketViewModel
import com.example.myapplication.businessLogic.viewmodel.OrderViewModel
import com.example.myapplication.model.Service import com.example.myapplication.model.Service
import com.example.myapplication.ui.theme.GreenBtn import com.example.myapplication.ui.theme.GreenBtn
import com.example.myapplication.ui.theme.TextPrimary import com.example.myapplication.ui.theme.TextPrimary
import com.example.myapplication.viewmodel.AppViewModelProvider import kotlinx.coroutines.launch
import com.example.myapplication.viewmodel.BasketViewModel
import com.example.myapplication.viewmodel.OrderViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Composable @Composable
fun BasketItemUI(item: Service, basketViewModel: BasketViewModel = viewModel(factory = AppViewModelProvider.Factory), orderViewModel: OrderViewModel = viewModel(factory = AppViewModelProvider.Factory)) { fun BasketItemUI(item: Service, basketViewModel: BasketViewModel = viewModel(factory = AppViewModelProvider.Factory), orderViewModel: OrderViewModel = viewModel(factory = AppViewModelProvider.Factory)) {
val userId = GlobalUser.getInstance().getUser()?.userId!! val user = GlobalUser.getInstance().getUser()
val basketStateId = remember { mutableIntStateOf(0) } val basketId = user?.basketId!!
LaunchedEffect(Unit) { val quantityState: Int by basketViewModel.getQuantityState(basketId, item.serviceId!!).collectAsState(0)
withContext(Dispatchers.IO) { val coroutineScope = rememberCoroutineScope()
basketStateId.value = basketViewModel.getUsersBasket(userId).basketId!!
}
}
val quantityState by basketViewModel.getQuantityState(basketStateId.value, item.serviceId!!).collectAsState()
Box( Box(
modifier = Modifier modifier = Modifier
.padding(0.dp, 0.dp, 0.dp, 10.dp) .padding(0.dp, 0.dp, 0.dp, 10.dp)
@ -121,7 +114,9 @@ fun BasketItemUI(item: Service, basketViewModel: BasketViewModel = viewModel(fac
Column(verticalArrangement = Arrangement.SpaceAround) { Column(verticalArrangement = Arrangement.SpaceAround) {
Button( Button(
onClick = { onClick = {
basketViewModel.incrementQuantity(basketStateId.intValue, item.serviceId!!) coroutineScope.launch {
basketViewModel.incrementServiceQuantity(basketId, item.serviceId!!)
}
}, },
modifier = Modifier modifier = Modifier
.size(42.dp) .size(42.dp)
@ -137,10 +132,9 @@ fun BasketItemUI(item: Service, basketViewModel: BasketViewModel = viewModel(fac
} }
Button( Button(
onClick = { onClick = {
if (quantityState == 1) basketViewModel.deleteServiceFromBasket(basketStateId.intValue, basketViewModel.viewModelScope.launch{
item.serviceId!! basketViewModel.decrementOrRemoveServiceQuantity(basketId, item.serviceId!!)
) }
basketViewModel.decrementQuantity(basketStateId.intValue, item.serviceId!!)
}, },
modifier = Modifier modifier = Modifier
.size(42.dp) .size(42.dp)

View File

@ -33,14 +33,14 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController import androidx.navigation.NavController
import com.example.myapplication.businessLogic.viewmodel.AppViewModelProvider
import com.example.myapplication.businessLogic.viewmodel.ServiceViewModel
import com.example.myapplication.composeui.Navbar.NavItem import com.example.myapplication.composeui.Navbar.NavItem
import com.example.myapplication.composeui.UIComponents.MyTextField import com.example.myapplication.composeui.UIComponents.MyTextField
import com.example.myapplication.model.Service import com.example.myapplication.model.Service
import com.example.myapplication.ui.theme.BlueMain import com.example.myapplication.ui.theme.BlueMain
import com.example.myapplication.ui.theme.GreenBtn import com.example.myapplication.ui.theme.GreenBtn
import com.example.myapplication.ui.theme.TextPrimary import com.example.myapplication.ui.theme.TextPrimary
import com.example.myapplication.viewmodel.AppViewModelProvider
import com.example.myapplication.viewmodel.ServiceViewModel
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@Composable @Composable
@ -188,7 +188,7 @@ fun AddService (navController: NavController, service: Service, serviceViewModel
Button( Button(
onClick = { onClick = {
if (create) if (create)
serviceViewModel.createService() serviceViewModel.insertService()
else else
serviceViewModel.service.let { serviceViewModel.updateService() } serviceViewModel.service.let { serviceViewModel.updateService() }
navController.navigate(NavItem.ListOfServices.route) navController.navigate(NavItem.ListOfServices.route)

View File

@ -7,19 +7,23 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.paging.compose.collectAsLazyPagingItems import androidx.paging.compose.collectAsLazyPagingItems
import androidx.paging.compose.itemKey import androidx.paging.compose.itemKey
import com.example.myapplication.businessLogic.viewmodel.AppViewModelProvider
import com.example.myapplication.businessLogic.viewmodel.ServiceViewModel
import com.example.myapplication.model.Service import com.example.myapplication.model.Service
import com.example.myapplication.ui.theme.BlueMain import com.example.myapplication.ui.theme.BlueMain
import com.example.myapplication.viewmodel.AppViewModelProvider
import com.example.myapplication.viewmodel.ServiceViewModel
@Composable @Composable
fun ListOfServices(navController: NavHostController, serviceViewModel: ServiceViewModel = viewModel(factory = AppViewModelProvider.Factory)){ fun ListOfServices(navController: NavHostController, serviceViewModel: ServiceViewModel = viewModel(factory = AppViewModelProvider.Factory)){
LaunchedEffect(serviceViewModel){
serviceViewModel.getServiceList()
}
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()

View File

@ -25,6 +25,9 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
@ -34,25 +37,28 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import com.example.myapplication.GlobalUser import com.example.myapplication.GlobalUser
import com.example.myapplication.model.BasketService import com.example.myapplication.businessLogic.viewmodel.AppViewModelProvider
import com.example.myapplication.businessLogic.viewmodel.BasketViewModel
import com.example.myapplication.businessLogic.viewmodel.ServiceViewModel
import com.example.myapplication.composeui.Navbar.NavItem
import com.example.myapplication.model.RoleEnum import com.example.myapplication.model.RoleEnum
import com.example.myapplication.model.Service import com.example.myapplication.model.Service
import com.example.myapplication.ui.theme.GreenBtn import com.example.myapplication.ui.theme.GreenBtn
import com.example.myapplication.ui.theme.TextPrimary import com.example.myapplication.ui.theme.TextPrimary
import com.example.myapplication.viewmodel.AppViewModelProvider
import com.example.myapplication.viewmodel.BasketViewModel
import com.example.myapplication.viewmodel.ServiceViewModel
import com.google.gson.Gson import com.google.gson.Gson
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
@Composable @Composable
fun Service(navController: NavHostController, item: Service, basketViewModel: BasketViewModel = viewModel(factory = AppViewModelProvider.Factory), serviceViewModel: ServiceViewModel = viewModel(factory = AppViewModelProvider.Factory)){ fun Service(navController: NavHostController, item: Service, basketViewModel: BasketViewModel = viewModel(factory = AppViewModelProvider.Factory), serviceViewModel: ServiceViewModel = viewModel(factory = AppViewModelProvider.Factory)){
val user = GlobalUser.getInstance().getUser() val user = GlobalUser.getInstance().getUser()
val basketId by basketViewModel.basketId.collectAsState()
LaunchedEffect(basketViewModel){
if(user!=null && basketId == 0) basketViewModel.getUsersBasket(user.userId!!)
}
Box( Box(
modifier = Modifier modifier = Modifier
.padding(0.dp, 0.dp, 0.dp, 10.dp) .padding(0.dp, 0.dp, 0.dp, 10.dp)
@ -97,11 +103,9 @@ fun Service(navController: NavHostController, item: Service, basketViewModel: Ba
if(user?.role == RoleEnum.Admin){ if(user?.role == RoleEnum.Admin){
Button( Button(
onClick = { onClick = {
runBlocking { basketViewModel.viewModelScope.launch {
launch(Dispatchers.Default){
serviceViewModel.deleteService(item) serviceViewModel.deleteService(item)
} }
}
}, },
modifier = Modifier modifier = Modifier
.size(42.dp) .size(42.dp)
@ -130,11 +134,12 @@ fun Service(navController: NavHostController, item: Service, basketViewModel: Ba
) )
Button( Button(
onClick = { onClick = {
runBlocking{ if(user != null)
launch(Dispatchers.Default){ basketViewModel.viewModelScope.launch {
basketViewModel.addToBasket(BasketService(basketViewModel.getUsersBasket(user?.userId!!).basketId!!, item.serviceId!!, 1)) basketViewModel.addToBasket(item.serviceId!!, 1)
}
} }
else
navController.navigate(NavItem.Login.route)
}, },
modifier = Modifier modifier = Modifier
.size(42.dp) .size(42.dp)

View File

@ -15,10 +15,10 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController import androidx.navigation.NavController
import com.example.myapplication.GlobalUser import com.example.myapplication.GlobalUser
import com.example.myapplication.businessLogic.viewmodel.AppViewModelProvider
import com.example.myapplication.businessLogic.viewmodel.OrderViewModel
import com.example.myapplication.model.Order import com.example.myapplication.model.Order
import com.example.myapplication.ui.theme.BlueMain import com.example.myapplication.ui.theme.BlueMain
import com.example.myapplication.viewmodel.AppViewModelProvider
import com.example.myapplication.viewmodel.OrderViewModel
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -30,7 +30,7 @@ fun Orders (navController: NavController, orderViewModel: OrderViewModel = viewM
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
orderViewModel.getUserOrders(user?.userId!!).collect { data -> orderViewModel.getUserOrders(user?.userId!!).collect { data ->
ordersList.clear() ordersList.clear()
ordersList.addAll(data.orders) ordersList.addAll(data)
} }
} }
} }

View File

@ -29,16 +29,20 @@ import androidx.compose.ui.unit.TextUnitType
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController import androidx.navigation.NavController
import com.example.myapplication.businessLogic.viewmodel.AppViewModelProvider
import com.example.myapplication.businessLogic.viewmodel.BasketViewModel
import com.example.myapplication.businessLogic.viewmodel.UserViewModel
import com.example.myapplication.composeui.Navbar.NavItem import com.example.myapplication.composeui.Navbar.NavItem
import com.example.myapplication.composeui.UIComponents.MyTextField import com.example.myapplication.composeui.UIComponents.MyTextField
import com.example.myapplication.ui.theme.BlueMain import com.example.myapplication.ui.theme.BlueMain
import com.example.myapplication.ui.theme.GreenBtn import com.example.myapplication.ui.theme.GreenBtn
import com.example.myapplication.ui.theme.TextSecondary import com.example.myapplication.ui.theme.TextSecondary
import com.example.myapplication.viewmodel.AppViewModelProvider import kotlinx.coroutines.CoroutineScope
import com.example.myapplication.viewmodel.UserViewModel import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@Composable @Composable
fun Login (navController: NavController, userViewModel: UserViewModel = viewModel(factory = AppViewModelProvider.Factory)){ fun Login (navController: NavController, userViewModel: UserViewModel = viewModel(factory = AppViewModelProvider.Factory), basketViewModel: BasketViewModel = viewModel(factory = AppViewModelProvider.Factory)){
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
@ -98,8 +102,10 @@ fun Login (navController: NavController, userViewModel: UserViewModel = viewMode
} }
Button( Button(
onClick = { onClick = {
CoroutineScope(Dispatchers.Main).launch {
userViewModel.authUser() userViewModel.authUser()
navController.navigate(NavItem.Profile.route) navController.navigate(NavItem.Profile.route)
}
}, },
modifier = Modifier modifier = Modifier
.height(60.dp) .height(60.dp)

View File

@ -38,8 +38,8 @@ import com.example.myapplication.composeui.Navbar.NavItem
import com.example.myapplication.composeui.UIComponents.MyTextField import com.example.myapplication.composeui.UIComponents.MyTextField
import com.example.myapplication.ui.theme.BlueMain import com.example.myapplication.ui.theme.BlueMain
import com.example.myapplication.ui.theme.GreenBtn import com.example.myapplication.ui.theme.GreenBtn
import com.example.myapplication.viewmodel.AppViewModelProvider import com.example.myapplication.businessLogic.viewmodel.AppViewModelProvider
import com.example.myapplication.viewmodel.UserViewModel import com.example.myapplication.businessLogic.viewmodel.UserViewModel
@Composable @Composable
fun ProfileChange (navController: NavHostController, userViewModel: UserViewModel = viewModel(factory = AppViewModelProvider.Factory)){ fun ProfileChange (navController: NavHostController, userViewModel: UserViewModel = viewModel(factory = AppViewModelProvider.Factory)){

View File

@ -34,8 +34,8 @@ import com.example.myapplication.composeui.UIComponents.MyTextField
import com.example.myapplication.ui.theme.BlueMain import com.example.myapplication.ui.theme.BlueMain
import com.example.myapplication.ui.theme.GreenBtn import com.example.myapplication.ui.theme.GreenBtn
import com.example.myapplication.ui.theme.TextSecondary import com.example.myapplication.ui.theme.TextSecondary
import com.example.myapplication.viewmodel.AppViewModelProvider import com.example.myapplication.businessLogic.viewmodel.AppViewModelProvider
import com.example.myapplication.viewmodel.UserViewModel import com.example.myapplication.businessLogic.viewmodel.UserViewModel
@Composable @Composable
fun Registration (navController: NavController, userViewModel: UserViewModel = viewModel(factory = AppViewModelProvider.Factory)){ fun Registration (navController: NavController, userViewModel: UserViewModel = viewModel(factory = AppViewModelProvider.Factory)){

View File

@ -7,6 +7,7 @@ import androidx.room.RoomDatabase
import androidx.sqlite.db.SupportSQLiteDatabase import androidx.sqlite.db.SupportSQLiteDatabase
import com.example.myapplication.database.dao.BasketDao import com.example.myapplication.database.dao.BasketDao
import com.example.myapplication.database.dao.OrderDao import com.example.myapplication.database.dao.OrderDao
import com.example.myapplication.database.dao.RemoteKeysDao
import com.example.myapplication.database.dao.ServiceDao import com.example.myapplication.database.dao.ServiceDao
import com.example.myapplication.database.dao.UserDao import com.example.myapplication.database.dao.UserDao
import com.example.myapplication.model.Basket import com.example.myapplication.model.Basket
@ -21,7 +22,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@Database(entities = [User::class, Service::class, Order::class, OrderService::class, Basket::class, BasketService::class, RemoteKeys::class], version = 8) @Database(entities = [User::class, Service::class, Order::class, OrderService::class, Basket::class, BasketService::class, RemoteKeys::class], version = 9)
abstract class AppDatabase : RoomDatabase(){ abstract class AppDatabase : RoomDatabase(){
abstract fun serviceDao(): ServiceDao abstract fun serviceDao(): ServiceDao
abstract fun userDao(): UserDao abstract fun userDao(): UserDao

View File

@ -7,23 +7,21 @@ import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import androidx.room.Update import androidx.room.Update
import com.example.myapplication.model.Service import com.example.myapplication.model.Service
import kotlinx.coroutines.flow.Flow
@Dao @Dao
interface ServiceDao { interface ServiceDao {
@Insert @Insert
suspend fun insert(service: Service) : Long suspend fun insert(vararg service: Service)
@Update @Update
suspend fun update(service: Service) suspend fun update(service: Service)
@Delete @Delete
suspend fun delete(service: Service) suspend fun delete(service: Service)
@Query("SELECT*FROM tbl_service")
fun getAllServices(): Flow<List<Service>>
@Query("SELECT*FROM tbl_service") @Query("SELECT*FROM tbl_service")
fun getAllServicesPaged(): PagingSource<Int, Service> fun getAllServicesPaged(): PagingSource<Int, Service>
@Query("select * from tbl_service")
fun getAll(): PagingSource<Int, Service>
@Query("SELECT * FROM tbl_service WHERE serviceId = :id") @Query("SELECT * FROM tbl_service WHERE serviceId = :id")
suspend fun getServiceById(id: Int): Service suspend fun getServiceById(id: Int): Service
@Query("DELETE FROM tbl_service")
suspend fun deleteAll()
} }

View File

@ -6,8 +6,6 @@ import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import androidx.room.Update import androidx.room.Update
import com.example.myapplication.model.User import com.example.myapplication.model.User
import com.example.myapplication.model.UserWithOrder
import kotlinx.coroutines.flow.Flow
@Dao @Dao
interface UserDao { interface UserDao {
@ -25,7 +23,4 @@ interface UserDao {
@Query("SELECT * FROM tbl_user WHERE email = :email") @Query("SELECT * FROM tbl_user WHERE email = :email")
suspend fun getUserByEmail(email: String): User suspend fun getUserByEmail(email: String): User
@Query("SELECT * FROM tbl_user WHERE userId =:id")
fun getUserOrders(id: Int) : Flow<UserWithOrder>
} }

View File

@ -1,24 +0,0 @@
package com.example.myapplication.database.repository
import com.example.myapplication.database.dao.BasketDao
import com.example.myapplication.model.Basket
import com.example.myapplication.model.BasketService
import com.example.myapplication.model.BasketWithServices
import kotlinx.coroutines.flow.Flow
class BasketRepository(private val basketDao: BasketDao) {
suspend fun createBasket(basket: Basket): Long = basketDao.insert(basket)
suspend fun getUsersBasket(userId: Int): Basket = basketDao.getUsersBasket(userId)
suspend fun removeServiceFromBasket(basketId: Int, serviceId: Int) = basketDao.removeServiceFromBasket(basketId, serviceId)
suspend fun updateServiceQuantity(basketId: Int, serviceId: Int, quantity: Int) = basketDao.updateServiceQuantity(basketId, serviceId, quantity)
suspend fun incrementServiceQuantity(basketId: Int, serviceId: Int) = basketDao.incrementServiceQuantity(basketId, serviceId)
suspend fun decrementServiceQuantity(basketId: Int, serviceId: Int) = basketDao.decrementServiceQuantity(basketId, serviceId)
suspend fun insertBasketService(basketService: BasketService) = basketDao.insertBasketService(basketService)
fun getBasketWithServices(id: Int): Flow<BasketWithServices> = basketDao.getBasketWithServices(id)
fun getAllBasket(): Flow<List<Basket>> = basketDao.getAllBaskets()
suspend fun delete(basket: Basket) = basketDao.delete(basket)
suspend fun getQuantity(basketId: Int, serviceId: Int): Int? = basketDao.getQuantity(basketId, serviceId)
suspend fun getService(basketId: Int, serviceId: Int): BasketService? = basketDao.getService(basketId, serviceId)
suspend fun getTotalPriceForBasket(basketId: Int): Double? = basketDao.getTotalPriceForBasket(basketId)
suspend fun clearBasket(basketId: Int) = basketDao.clearBasket(basketId)
}

View File

@ -0,0 +1,41 @@
package com.example.myapplication.database.repository
import com.example.myapplication.businessLogic.repository.BasketRepository
import com.example.myapplication.database.dao.BasketDao
import com.example.myapplication.model.Basket
import com.example.myapplication.model.BasketService
import com.example.myapplication.model.Service
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow
class BasketRepositoryImpl(private val basketDao: BasketDao): BasketRepository {
suspend fun createBasket(basket: Basket): Long = basketDao.insert(basket)
suspend fun getUsersBasket(userId: Int): Basket = basketDao.getUsersBasket(userId)
override suspend fun removeServiceFromBasket(basketId: Int, serviceId: Int) = basketDao.removeServiceFromBasket(basketId, serviceId)
suspend fun updateServiceQuantity(basketId: Int, serviceId: Int, quantity: Int) = basketDao.updateServiceQuantity(basketId, serviceId, quantity)
override suspend fun incrementServiceQuantity(basketId: Int, serviceId: Int) = basketDao.incrementServiceQuantity(basketId, serviceId)
override suspend fun decrementServiceQuantity(basketId: Int, serviceId: Int) = basketDao.decrementServiceQuantity(basketId, serviceId)
override suspend fun insertBasketService(basketService: BasketService) = basketDao.insertBasketService(basketService)
override suspend fun getBasketWithServices(id: Int): Flow<List<Service>> = flow {basketDao.getBasketWithServices(id).first().services}
override suspend fun getUserBasketId(id: Int): Flow<Int> {
TODO("Not yet implemented")
}
suspend fun delete(basket: Basket) = basketDao.delete(basket)
override suspend fun getQuantity(basketId: Int, serviceId: Int): Int? = basketDao.getQuantity(basketId, serviceId)
override suspend fun existService(basketId: Int, serviceId: Int): Boolean {
TODO("Not yet implemented")
}
override suspend fun getTotalPriceForUser(userId: Int): Double? {
TODO("Not yet implemented")
}
override suspend fun deleteAllServiceFromBasket(basketId: Int) {
TODO("Not yet implemented")
}
suspend fun getService(basketId: Int, serviceId: Int): BasketService? = basketDao.getService(basketId, serviceId)
suspend fun getTotalPriceForBasket(basketId: Int): Double? = basketDao.getTotalPriceForBasket(basketId)
suspend fun clearBasket(basketId: Int) = basketDao.clearBasket(basketId)
}

View File

@ -1,14 +0,0 @@
package com.example.myapplication.database.repository
import com.example.myapplication.database.dao.OrderDao
import com.example.myapplication.model.Order
import com.example.myapplication.model.OrderService
class OrderRepository(private val orderDao: OrderDao) {
suspend fun insert(order: Order) = orderDao.insert(order)
suspend fun insertOrderService(orderService: OrderService) = orderDao.insertOrderService(orderService)
suspend fun delete(order: Order) = orderDao.delete(order)
fun getOrderWithServices(id: Int) = orderDao.getOrderWithServices(id)
fun getAllOrders() = orderDao.getAllOrders()
fun getUserOrders(id: Int) = orderDao.getUserOrders(id)
}

View File

@ -0,0 +1,22 @@
package com.example.myapplication.database.repository
import com.example.myapplication.businessLogic.repository.OrderRepository
import com.example.myapplication.database.dao.OrderDao
import com.example.myapplication.model.Order
import com.example.myapplication.model.OrderService
import com.example.myapplication.model.Service
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow
class OrderRepositoryImpl(private val orderDao: OrderDao): OrderRepository {
override suspend fun insert(order: Order) = orderDao.insert(order)
override suspend fun addServiceToOrder(orderService: OrderService) = orderDao.insertOrderService(orderService)
override suspend fun delete(order: Order) = orderDao.delete(order)
override suspend fun getServiceFromOrder(id: Int): Flow<List<Service>> {
TODO("Not yet implemented")
}
suspend fun getOrderWithServices(id: Int) = orderDao.getOrderWithServices(id)
suspend fun getAllOrders() = orderDao.getAllOrders()
override suspend fun getUserOrders(id: Int): Flow<List<Order>> = flow { orderDao.getUserOrders(id).first().orders }
}

View File

@ -1,23 +0,0 @@
package com.example.myapplication.database.repository
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import com.example.myapplication.database.dao.ServiceDao
import com.example.myapplication.model.Service
import kotlinx.coroutines.flow.Flow
class ServiceRepository(private val serviceDao: ServiceDao) {
suspend fun insert(service: Service) = serviceDao.insert(service)
suspend fun update(service: Service) = serviceDao.update(service)
suspend fun delete(service: Service) = serviceDao.delete(service)
suspend fun getServiceById(id: Int) = serviceDao.getServiceById(id)
fun getAllServices() = serviceDao.getAllServices()
fun call(): Flow<PagingData<Service>> {
return Pager(
PagingConfig(pageSize = 5)
){
serviceDao.getAllServicesPaged()
}.flow
}
}

View File

@ -0,0 +1,30 @@
package com.example.myapplication.database.repository
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.PagingSource
import com.example.myapplication.businessLogic.repository.ServiceRepository
import com.example.myapplication.database.dao.ServiceDao
import com.example.myapplication.di.AppContainer
import com.example.myapplication.model.Service
import kotlinx.coroutines.flow.Flow
class ServiceRepositoryImpl(private val serviceDao: ServiceDao): ServiceRepository {
override suspend fun insert(service: Service) = serviceDao.insert(service)
override suspend fun update(service: Service) = serviceDao.update(service)
override suspend fun delete(service: Service) = serviceDao.delete(service)
override suspend fun getServiceById(id: Int): Service = serviceDao.getServiceById(id)
override suspend fun getAllServices(): Flow<PagingData<Service>> = Pager(
config = PagingConfig(
pageSize = AppContainer.LIMIT,
enablePlaceholders = false
),
pagingSourceFactory = serviceDao::getAll
).flow
suspend fun clearServices() = serviceDao.deleteAll()
suspend fun insertServices(services: List<Service>) =
serviceDao.insert(*services.toTypedArray())
fun getAllServicesPagingSource(): PagingSource<Int, Service> = serviceDao.getAll()
}

View File

@ -1,12 +0,0 @@
package com.example.myapplication.database.repository
import com.example.myapplication.database.dao.UserDao
import com.example.myapplication.model.User
class UserRepository(private val userDao: UserDao) {
suspend fun insert(user: User) = userDao.insert(user)
suspend fun update(user: User) = userDao.update(user)
suspend fun delete(user: User) = userDao.delete(user)
suspend fun getUserById(id: Int) = userDao.getUserById(id)
suspend fun getUserByEmail(email: String) = userDao.getUserByEmail(email)
}

View File

@ -0,0 +1,17 @@
package com.example.myapplication.database.repository
import com.example.myapplication.api.model.UserRemoteSignIn
import com.example.myapplication.businessLogic.repository.UserRepository
import com.example.myapplication.database.dao.UserDao
import com.example.myapplication.model.User
class UserRepositoryImpl(private val userDao: UserDao): UserRepository {
override suspend fun insert(user: User) = userDao.insert(user)
override suspend fun update(user: User) = userDao.update(user)
override suspend fun delete(user: User) = userDao.delete(user)
override suspend fun authUser(user: UserRemoteSignIn): User {
TODO("Not yet implemented")
}
suspend fun getUserById(id: Int) = userDao.getUserById(id)
suspend fun getUserByEmail(email: String) = userDao.getUserByEmail(email)
}

View File

@ -1,9 +1,9 @@
package com.example.myapplication.di package com.example.myapplication.di
import com.example.myapplication.database.repository.BasketRepository import com.example.myapplication.businessLogic.repository.BasketRepository
import com.example.myapplication.database.repository.OrderRepository import com.example.myapplication.businessLogic.repository.OrderRepository
import com.example.myapplication.database.repository.ServiceRepository import com.example.myapplication.businessLogic.repository.ServiceRepository
import com.example.myapplication.database.repository.UserRepository import com.example.myapplication.businessLogic.repository.UserRepository
interface AppContainer { interface AppContainer {
val serviceRepo: ServiceRepository val serviceRepo: ServiceRepository

View File

@ -6,14 +6,16 @@ import com.example.myapplication.api.repository.RestBasketRepository
import com.example.myapplication.api.repository.RestOrderRepository import com.example.myapplication.api.repository.RestOrderRepository
import com.example.myapplication.api.repository.RestServiceRepository import com.example.myapplication.api.repository.RestServiceRepository
import com.example.myapplication.api.repository.RestUserRepository import com.example.myapplication.api.repository.RestUserRepository
import com.example.myapplication.businessLogic.repository.BasketRepository
import com.example.myapplication.businessLogic.repository.OrderRepository
import com.example.myapplication.businessLogic.repository.ServiceRepository
import com.example.myapplication.businessLogic.repository.UserRepository
import com.example.myapplication.database.AppDatabase import com.example.myapplication.database.AppDatabase
import com.example.myapplication.database.repository.BasketRepository import com.example.myapplication.database.repository.RemoteKeysRepositoryImpl
import com.example.myapplication.database.repository.OrderRepository import com.example.myapplication.database.repository.ServiceRepositoryImpl
import com.example.myapplication.database.repository.ServiceRepository
import com.example.myapplication.database.repository.UserRepository
class AppDataContainer(context: Context) : AppContainer { class AppDataContainer(context: Context) : AppContainer {
override val serviceRepo = ServiceRepository by lazy { override val serviceRepo: ServiceRepository by lazy {
RestServiceRepository( RestServiceRepository(
ServerService.getInstance(), ServerService.getInstance(),
serviceRepository, serviceRepository,
@ -21,20 +23,20 @@ class AppDataContainer(context: Context) : AppContainer {
remoteKeyRepository remoteKeyRepository
) )
} }
override val userRepo = UserRepository by lazy{ override val userRepo: UserRepository by lazy{
RestUserRepository(ServerService.getInstance()) RestUserRepository(ServerService.getInstance())
} }
override val orderRepo = OrderRepository by lazy { override val orderRepo: OrderRepository by lazy {
RestOrderRepository(ServerService.getInstance()) RestOrderRepository(ServerService.getInstance())
} }
override val basketRepo = BasketRepository by lazy{ override val basketRepo: BasketRepository by lazy{
RestBasketRepository(ServerService.getInstance()) RestBasketRepository(ServerService.getInstance())
} }
private val serviceRepository: ServiceRepository by lazy { private val serviceRepository: ServiceRepositoryImpl by lazy {
ServiceRepository(AppDatabase.getInstance(context).serviceDao()) ServiceRepositoryImpl(AppDatabase.getInstance(context).serviceDao())
} }
private val remoteKeyRepository: RemoteKeysRepository by lazy{ private val remoteKeyRepository: RemoteKeysRepositoryImpl by lazy{
RemoteKeysRepository(AppDatabase.getInstance(context).remoteKeysDao()) RemoteKeysRepositoryImpl(AppDatabase.getInstance(context).remoteKeysDao())
} }
} }

View File

@ -6,7 +6,7 @@ import androidx.room.TypeConverter
import androidx.room.TypeConverters import androidx.room.TypeConverters
enum class RemoteKeyType(private val type: String) { enum class RemoteKeyType(private val type: String) {
SNEAKER(Service::class.simpleName ?: "Sneaker"); SERVICE(Service::class.simpleName ?: "Service");
@TypeConverter @TypeConverter
fun toRemoteKeyType(value: String) = RemoteKeyType.values().first { it.type == value } fun toRemoteKeyType(value: String) = RemoteKeyType.values().first { it.type == value }
@TypeConverter @TypeConverter

View File

@ -12,5 +12,6 @@ data class User(
var email: String, var email: String,
var password: String, var password: String,
val role: RoleEnum, val role: RoleEnum,
val photo: Int? = null val photo: Int? = null,
val basketId: Int? = null
) )

View File

@ -1,92 +0,0 @@
package com.example.myapplication.viewmodel
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableDoubleStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.myapplication.GlobalUser
import com.example.myapplication.model.Basket
import com.example.myapplication.model.BasketService
import com.example.myapplication.model.BasketWithServices
import com.example.myapplication.database.repository.BasketRepository
import com.example.myapplication.database.repository.OrderRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
class BasketViewModel(private val basketRepository: BasketRepository, private val orderRepository: OrderRepository) : ViewModel() {
private val _quantityStateMap = mutableMapOf<Int, MutableStateFlow<Int>>()
private val _total = mutableDoubleStateOf(0.00)
val total: State<Double> get() = _total
fun getQuantityState(basketId: Int, serviceId: Int): StateFlow<Int> {
val quantityStateFlow = _quantityStateMap.getOrPut(serviceId) {
MutableStateFlow(0)
}
viewModelScope.launch {
val quantityFromDb = basketRepository.getQuantity(basketId, serviceId)
quantityFromDb?.let { quantityStateFlow.value = it }
}
return quantityStateFlow
}
suspend fun isServiceInBasket(basketId: Int, serviceId: Int): Boolean {
return basketRepository.getService(basketId, serviceId) != null
}
fun addToBasket(basketServices: BasketService) = viewModelScope.launch {
val isServiceInBasket = isServiceInBasket(basketServices.basketId, basketServices.serviceId)
if (isServiceInBasket) {
incrementQuantity(basketServices.basketId, basketServices.serviceId)
} else {
basketRepository.insertBasketService(basketServices)
}
}
fun getBasketServices(id: Int): Flow<BasketWithServices> {
return basketRepository.getBasketWithServices(id)
}
suspend fun getUsersBasket(id: Int): Basket {
return basketRepository.getUsersBasket(id)
}
fun deleteServiceFromBasket(basketId: Int, serviceId: Int) = viewModelScope.launch {
basketRepository.removeServiceFromBasket(basketId, serviceId)
}
fun incrementQuantity(basketId: Int, serviceId: Int) {
val currentQuantity = _quantityStateMap[serviceId]?.value ?: 1
_quantityStateMap[serviceId]?.value = currentQuantity + 1
viewModelScope.launch {
basketRepository.incrementServiceQuantity(basketId, serviceId)
updateSubTotal(GlobalUser.getInstance().getUser()?.userId!!)
}
}
fun decrementQuantity(basketId: Int, serviceId: Int) {
val currentQuantity = _quantityStateMap[serviceId]?.value ?: 1
if (currentQuantity > 1) {
_quantityStateMap[serviceId]?.value = currentQuantity - 1
viewModelScope.launch {
basketRepository.decrementServiceQuantity(basketId, serviceId)
updateSubTotal(GlobalUser.getInstance().getUser()?.userId!!)
}
}
}
fun updateSubTotal(userId: Int) {
viewModelScope.launch {
_total.value = getTotal(userId)
}
}
suspend fun getTotal(userId: Int): Double {
return basketRepository.getTotalPriceForBasket(basketRepository.getUsersBasket(userId!!).basketId!!) ?: 0.00
}
}

View File

@ -1,45 +0,0 @@
package com.example.myapplication.viewmodel
import androidx.compose.runtime.mutableDoubleStateOf
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.cachedIn
import com.example.myapplication.R
import com.example.myapplication.model.Service
import com.example.myapplication.database.repository.ServiceRepository
import kotlinx.coroutines.launch
class ServiceViewModel(private val serviceRepository: ServiceRepository): ViewModel() {
var name = mutableStateOf("")
var price = mutableDoubleStateOf(0.00)
var photo = mutableIntStateOf(R.drawable.image_service)
var service = mutableStateOf<Service>(Service(null,"", 0.0, null))
val serviceList = serviceRepository.call().cachedIn(viewModelScope)
fun createService() = viewModelScope.launch {
val service = Service(
name = name.value,
price = price.doubleValue,
photo = photo.intValue
)
serviceRepository.insert(service)
}
fun updateService() = viewModelScope.launch {
serviceRepository.update(service.value)
}
fun deleteService(service: Service) = viewModelScope.launch {
serviceRepository.delete(service)
}
fun getServiceById(id: Int) = viewModelScope.launch {
serviceRepository.getServiceById(id)
}
fun getAllServices() = viewModelScope.launch {
serviceRepository.getAllServices()
}
}