From 90e0dc6d738eaad49311ff6499fe0ec774eebfaa Mon Sep 17 00:00:00 2001 From: Wikijito7 Date: Wed, 7 Dec 2022 19:09:46 +0100 Subject: [PATCH 1/2] Finished invoices routing --- .../invoice/InvoiceLocalDataSource.kt | 58 +++++++++++++++++ .../{ => user}/UserLocalDataSource.kt | 5 +- .../data/mapper/invoice/InvoiceMapper.kt | 65 +++++++++++++++++++ .../es/wokis/data/mapper/user/UserMapper.kt | 2 +- .../repository/invoices/InvoiceRepository.kt | 29 +++++++++ .../data/repository/user/UserRepository.kt | 7 +- .../kotlin/es/wokis/di/DataSourceModule.kt | 7 +- .../kotlin/es/wokis/di/RepositoryModule.kt | 3 + .../es/wokis/routing/InvoicesRouting.kt | 47 +++++++++++++- .../kotlin/es/wokis/utils/CredentialsUtils.kt | 7 ++ 10 files changed, 215 insertions(+), 15 deletions(-) create mode 100644 src/main/kotlin/es/wokis/data/datasource/invoice/InvoiceLocalDataSource.kt rename src/main/kotlin/es/wokis/data/datasource/{ => user}/UserLocalDataSource.kt (98%) create mode 100644 src/main/kotlin/es/wokis/data/repository/invoices/InvoiceRepository.kt create mode 100644 src/main/kotlin/es/wokis/utils/CredentialsUtils.kt diff --git a/src/main/kotlin/es/wokis/data/datasource/invoice/InvoiceLocalDataSource.kt b/src/main/kotlin/es/wokis/data/datasource/invoice/InvoiceLocalDataSource.kt new file mode 100644 index 0000000..90757eb --- /dev/null +++ b/src/main/kotlin/es/wokis/data/datasource/invoice/InvoiceLocalDataSource.kt @@ -0,0 +1,58 @@ +package es.wokis.data.datasource.invoice + +import com.mongodb.client.MongoCollection +import es.wokis.data.bo.invoice.InvoiceBO +import es.wokis.data.dbo.invoice.InvoiceDBO +import es.wokis.data.mapper.invoice.toBO +import es.wokis.data.mapper.invoice.toDBO +import org.litote.kmongo.eq +import org.litote.kmongo.updateOne +import java.util.regex.Pattern + +interface InvoiceLocalDataSource { + suspend fun getInvoicesOfUser(id: String): List + suspend fun addInvoices(id: String, invoices: List): Boolean + suspend fun updateInvoices(id: String, invoices: List): Boolean + suspend fun deleteInvoices(id: String, invoices: List): Boolean +} + +class InvoiceLocalDataSourceImpl(private val invoiceCollection: MongoCollection) : InvoiceLocalDataSource { + + private val getCaseInsensitive: (element: String) -> Pattern = { + Pattern.compile(it, Pattern.CASE_INSENSITIVE) + } + + override suspend fun getInvoicesOfUser(id: String): List = + invoiceCollection.find(InvoiceDBO::userId eq id).map { + it.toBO() + }.toList() + + override suspend fun addInvoices(id: String, invoices: List): Boolean = try { + invoiceCollection.insertMany(invoices.toDBO()).wasAcknowledged() + + } catch (e: Throwable) { + println(e.stackTraceToString()) + false + } + + override suspend fun updateInvoices(id: String, invoices: List): Boolean = try { + invoices.toDBO().map { + invoiceCollection.updateOne(InvoiceDBO::id eq it.id, it).wasAcknowledged() + }.all { it } + + } catch (e: Throwable) { + println(e.stackTraceToString()) + false + } + + override suspend fun deleteInvoices(id: String, invoices: List): Boolean = try { + invoices.toDBO().map { + invoiceCollection.deleteOne(InvoiceDBO::id eq it.id).wasAcknowledged() + }.all { it } + + } catch (e: Throwable) { + println(e.stackTraceToString()) + false + } + +} \ No newline at end of file diff --git a/src/main/kotlin/es/wokis/data/datasource/UserLocalDataSource.kt b/src/main/kotlin/es/wokis/data/datasource/user/UserLocalDataSource.kt similarity index 98% rename from src/main/kotlin/es/wokis/data/datasource/UserLocalDataSource.kt rename to src/main/kotlin/es/wokis/data/datasource/user/UserLocalDataSource.kt index 12e6e5f..48ce452 100644 --- a/src/main/kotlin/es/wokis/data/datasource/UserLocalDataSource.kt +++ b/src/main/kotlin/es/wokis/data/datasource/user/UserLocalDataSource.kt @@ -1,4 +1,4 @@ -package es.wokis.data.datasource +package es.wokis.data.datasource.user import com.mongodb.client.MongoCollection import es.wokis.data.bo.user.UserBO @@ -16,14 +16,11 @@ interface UserLocalDataSource { suspend fun getUserById(id: String): UserBO? suspend fun getUserByEmail(email: String): UserBO? suspend fun getUserByUsername(username: String): UserBO? - suspend fun getUserByUsernameOrEmail(username: String, email: String = EMPTY_TEXT): UserBO? - suspend fun createUser(user: UserBO): Boolean } class UserLocalDataSourceImpl(private val userCollection: MongoCollection) : UserLocalDataSource { - private val getCaseInsensitive: (element: String) -> Pattern = { Pattern.compile(it, Pattern.CASE_INSENSITIVE) } diff --git a/src/main/kotlin/es/wokis/data/mapper/invoice/InvoiceMapper.kt b/src/main/kotlin/es/wokis/data/mapper/invoice/InvoiceMapper.kt index 82b5005..25e23c1 100644 --- a/src/main/kotlin/es/wokis/data/mapper/invoice/InvoiceMapper.kt +++ b/src/main/kotlin/es/wokis/data/mapper/invoice/InvoiceMapper.kt @@ -4,9 +4,14 @@ import es.wokis.data.bo.invoice.CategoryBO import es.wokis.data.bo.invoice.InvoiceBO import es.wokis.data.bo.invoice.InvoiceType import es.wokis.data.bo.invoice.ReactionBO +import es.wokis.data.dbo.invoice.CategoryDBO +import es.wokis.data.dbo.invoice.InvoiceDBO +import es.wokis.data.dbo.invoice.ReactionDBO import es.wokis.data.dto.invoice.CategoryDTO import es.wokis.data.dto.invoice.InvoiceDTO import es.wokis.data.dto.invoice.ReactionDTO +import org.bson.types.ObjectId +import org.litote.kmongo.id.toId import java.util.* fun InvoiceDTO.toBO() = InvoiceBO( @@ -30,7 +35,67 @@ fun CategoryDTO.toBO() = CategoryBO( fun List?.toBO() = this?.map { it.toBO() }.orEmpty() +@JvmName("invoiceDTOToBO") +fun List.toBO() = this.map { it.toBO() } + fun ReactionDTO.toBO() = ReactionBO( id = id, unicode = unicode +) + +fun InvoiceDBO.toBO() = InvoiceBO( + id = id?.toString(), + idApp = idApp, + title = title, + description = description, + quantity = quantity, + date = Date(date), + type = InvoiceType.valueOf(type.orEmpty()), + userId = userId.orEmpty(), + category = category?.toBO(), + reactions = reactions.toBO() +) + +fun CategoryDBO.toBO() = CategoryBO( + id = id, + title = title, + color = color +) + +@JvmName("reactionDBOToBO") +fun List?.toBO() = this?.map { it.toBO() }.orEmpty() + +fun ReactionDBO.toBO() = ReactionBO( + id = id, + unicode = unicode +) + +fun InvoiceBO.toDBO() = InvoiceDBO( + id = id?.let { ObjectId(it).toId() }, + idApp = idApp, + title = title, + description = description, + quantity = quantity, + date = date.time, + type = type.key, + userId = userId, + category = category?.toDBO(), + reactions = reactions.toDBO() +) + +fun CategoryBO.toDBO() = CategoryDBO( + id = id, + title = title, + color = color +) + +@JvmName("reactionBOToDBO") +fun List?.toDBO() = this?.map { it.toDBO() }.orEmpty() + +@JvmName("invoicesBOToDBO") +fun List?.toDBO(): List = this?.map { it.toDBO() }.orEmpty() + +fun ReactionBO.toDBO() = ReactionDBO( + id = id, + unicode = unicode ) \ No newline at end of file diff --git a/src/main/kotlin/es/wokis/data/mapper/user/UserMapper.kt b/src/main/kotlin/es/wokis/data/mapper/user/UserMapper.kt index c49d80e..3b9df6d 100644 --- a/src/main/kotlin/es/wokis/data/mapper/user/UserMapper.kt +++ b/src/main/kotlin/es/wokis/data/mapper/user/UserMapper.kt @@ -34,7 +34,7 @@ fun UserBO.toDBO() = UserDBO( id = id?.let { ObjectId(it).toId() }, username = username, email = email, - password = password.orEmpty(), + password = password, devices = devices ) diff --git a/src/main/kotlin/es/wokis/data/repository/invoices/InvoiceRepository.kt b/src/main/kotlin/es/wokis/data/repository/invoices/InvoiceRepository.kt new file mode 100644 index 0000000..e8de7bf --- /dev/null +++ b/src/main/kotlin/es/wokis/data/repository/invoices/InvoiceRepository.kt @@ -0,0 +1,29 @@ +package es.wokis.data.repository.invoices + +import es.wokis.data.bo.invoice.InvoiceBO +import es.wokis.data.datasource.user.UserLocalDataSource + +interface InvoiceRepository { + suspend fun getInvoicesOfUser(id: String): List + suspend fun addInvoices(id: String, invoices: List): Boolean + suspend fun updateInvoices(id: String, invoices: List): Boolean + suspend fun deleteInvoices(id: String, invoices: List): Boolean +} + +class InvoiceRepositoryImpl(private val userLocalDataSource: UserLocalDataSource) : InvoiceRepository { + override suspend fun getInvoicesOfUser(id: String): List { + TODO("Not yet implemented") + } + + override suspend fun addInvoices(id: String, invoices: List): Boolean { + TODO("Not yet implemented") + } + + override suspend fun updateInvoices(id: String, invoices: List): Boolean { + TODO("Not yet implemented") + } + + override suspend fun deleteInvoices(id: String, invoices: List): Boolean { + TODO("Not yet implemented") + } +} \ No newline at end of file diff --git a/src/main/kotlin/es/wokis/data/repository/user/UserRepository.kt b/src/main/kotlin/es/wokis/data/repository/user/UserRepository.kt index 721f59b..72d802d 100644 --- a/src/main/kotlin/es/wokis/data/repository/user/UserRepository.kt +++ b/src/main/kotlin/es/wokis/data/repository/user/UserRepository.kt @@ -1,14 +1,12 @@ package es.wokis.data.repository.user -import com.google.firebase.auth.hash.Bcrypt import es.wokis.data.bo.user.UserBO -import es.wokis.data.datasource.UserLocalDataSource +import es.wokis.data.datasource.user.UserLocalDataSource import es.wokis.data.dto.user.auth.LoginDTO import es.wokis.data.dto.user.auth.RegisterDTO import es.wokis.data.mapper.user.toBO import es.wokis.plugins.makeToken import org.mindrot.jbcrypt.BCrypt -import kotlin.math.log interface UserRepository { suspend fun login(login: LoginDTO): String? @@ -20,7 +18,6 @@ interface UserRepository { } class UserRepositoryImpl(private val userLocalDataSource: UserLocalDataSource) : UserRepository { - override suspend fun login(login: LoginDTO): String? { val user = userLocalDataSource.getUserByUsernameOrEmail(login.username) return user?.let { @@ -60,9 +57,7 @@ class UserRepositoryImpl(private val userLocalDataSource: UserLocalDataSource) : userLocalDataSource.getUserByUsername(it) } - override suspend fun getUserByEmail(email: String?): UserBO? = email?.let { userLocalDataSource.getUserByEmail(it) } - } \ No newline at end of file diff --git a/src/main/kotlin/es/wokis/di/DataSourceModule.kt b/src/main/kotlin/es/wokis/di/DataSourceModule.kt index 4d39a30..a96a6cc 100644 --- a/src/main/kotlin/es/wokis/di/DataSourceModule.kt +++ b/src/main/kotlin/es/wokis/di/DataSourceModule.kt @@ -2,8 +2,10 @@ package es.wokis.di import com.mongodb.client.MongoCollection import es.wokis.data.database.AppDataBase -import es.wokis.data.datasource.UserLocalDataSource -import es.wokis.data.datasource.UserLocalDataSourceImpl +import es.wokis.data.datasource.invoice.InvoiceLocalDataSource +import es.wokis.data.datasource.invoice.InvoiceLocalDataSourceImpl +import es.wokis.data.datasource.user.UserLocalDataSource +import es.wokis.data.datasource.user.UserLocalDataSourceImpl import es.wokis.data.dbo.invoice.InvoiceDBO import es.wokis.data.dbo.user.UserDBO import org.koin.core.qualifier.named @@ -14,6 +16,7 @@ val dataSourceModule = module { single(named("usersCollection")) { getUsersCollection(get()) as MongoCollection } single(named("invoicesCollection")) { getInvoicesCollection(get()) as MongoCollection } single { UserLocalDataSourceImpl(get(named("usersCollection"))) as UserLocalDataSource } + single { InvoiceLocalDataSourceImpl(get(named("invoicesCollection"))) as InvoiceLocalDataSource } } private fun getUsersCollection(database: AppDataBase) = database.usersCollection diff --git a/src/main/kotlin/es/wokis/di/RepositoryModule.kt b/src/main/kotlin/es/wokis/di/RepositoryModule.kt index b425df8..9e2f45d 100644 --- a/src/main/kotlin/es/wokis/di/RepositoryModule.kt +++ b/src/main/kotlin/es/wokis/di/RepositoryModule.kt @@ -1,9 +1,12 @@ package es.wokis.di +import es.wokis.data.repository.invoices.InvoiceRepository +import es.wokis.data.repository.invoices.InvoiceRepositoryImpl import es.wokis.data.repository.user.UserRepository import es.wokis.data.repository.user.UserRepositoryImpl import org.koin.dsl.module val repositoryModule = module { single { UserRepositoryImpl(get()) as UserRepository } + single { InvoiceRepositoryImpl(get()) as InvoiceRepository } } \ No newline at end of file diff --git a/src/main/kotlin/es/wokis/routing/InvoicesRouting.kt b/src/main/kotlin/es/wokis/routing/InvoicesRouting.kt index c67d2f2..3dc6a99 100644 --- a/src/main/kotlin/es/wokis/routing/InvoicesRouting.kt +++ b/src/main/kotlin/es/wokis/routing/InvoicesRouting.kt @@ -1,12 +1,55 @@ package es.wokis.routing -import es.wokis.data.repository.user.UserRepository +import es.wokis.data.dto.invoice.InvoiceDTO +import es.wokis.data.mapper.invoice.toBO +import es.wokis.data.repository.invoices.InvoiceRepository +import es.wokis.utils.user +import io.ktor.http.* import io.ktor.server.application.* +import io.ktor.server.auth.* +import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* import org.koin.ktor.ext.inject fun Routing.setUpInvoicesRouting() { - val userRepository by inject() // TODO: change to invoices repository + val invoiceRepository by inject() + + authenticate { + get { + val user = call.user + user?.id?.let { + val invoices = invoiceRepository.getInvoicesOfUser(it) + call.respond(HttpStatusCode.OK, invoices) + } ?: call.respond(HttpStatusCode.Unauthorized) + } + + post { + val user = call.user + val invoices = call.receive>() + user?.id?.let { + val userInvoices = invoiceRepository.addInvoices(it, invoices.toBO()) + call.respond(HttpStatusCode.OK, userInvoices) + } ?: call.respond(HttpStatusCode.Unauthorized) + } + + put { + val user = call.user + val invoices = call.receive>() + user?.id?.let { + val userInvoices = invoiceRepository.updateInvoices(it, invoices.toBO()) + call.respond(HttpStatusCode.OK, userInvoices) + } ?: call.respond(HttpStatusCode.Unauthorized) + } + + delete { + val user = call.user + val invoices = call.receive>() + user?.id?.let { + val userInvoices = invoiceRepository.deleteInvoices(it, invoices.toBO()) + call.respond(HttpStatusCode.OK, userInvoices) + } ?: call.respond(HttpStatusCode.Unauthorized) + } + } } \ No newline at end of file diff --git a/src/main/kotlin/es/wokis/utils/CredentialsUtils.kt b/src/main/kotlin/es/wokis/utils/CredentialsUtils.kt new file mode 100644 index 0000000..5ec7484 --- /dev/null +++ b/src/main/kotlin/es/wokis/utils/CredentialsUtils.kt @@ -0,0 +1,7 @@ +package es.wokis.utils + +import es.wokis.data.bo.user.UserBO +import io.ktor.server.application.* +import io.ktor.server.auth.* + +val ApplicationCall.user: UserBO? get() = authentication.principal() \ No newline at end of file From 4c7daa16166d19e0ffd293be489420c1f8d6490a Mon Sep 17 00:00:00 2001 From: Wikijito7 Date: Mon, 19 Dec 2022 11:27:05 +0100 Subject: [PATCH 2/2] Tidy things up --- .../es/wokis/data/dbo/invoice/InvoiceDBO.kt | 2 ++ .../data/mapper/invoice/InvoiceMapper.kt | 35 +++++++++++++++++-- .../repository/invoices/InvoiceRepository.kt | 24 ++++++------- .../es/wokis/routing/InvoicesRouting.kt | 11 +++--- 4 files changed, 50 insertions(+), 22 deletions(-) diff --git a/src/main/kotlin/es/wokis/data/dbo/invoice/InvoiceDBO.kt b/src/main/kotlin/es/wokis/data/dbo/invoice/InvoiceDBO.kt index 5366524..2d7ec1b 100644 --- a/src/main/kotlin/es/wokis/data/dbo/invoice/InvoiceDBO.kt +++ b/src/main/kotlin/es/wokis/data/dbo/invoice/InvoiceDBO.kt @@ -1,9 +1,11 @@ package es.wokis.data.dbo.invoice import es.wokis.data.constants.ServerConstants +import org.bson.codecs.pojo.annotations.BsonId import org.litote.kmongo.Id data class InvoiceDBO( + @BsonId val id: Id? = null, val idApp: Long = 0L, val title: String = ServerConstants.EMPTY_TEXT, diff --git a/src/main/kotlin/es/wokis/data/mapper/invoice/InvoiceMapper.kt b/src/main/kotlin/es/wokis/data/mapper/invoice/InvoiceMapper.kt index 25e23c1..e9339c6 100644 --- a/src/main/kotlin/es/wokis/data/mapper/invoice/InvoiceMapper.kt +++ b/src/main/kotlin/es/wokis/data/mapper/invoice/InvoiceMapper.kt @@ -21,7 +21,7 @@ fun InvoiceDTO.toBO() = InvoiceBO( description = description, quantity = quantity, date = Date(date), - type = InvoiceType.valueOf(type.orEmpty()), + type = InvoiceType.getFromKey(type.orEmpty()), userId = userId.orEmpty(), category = category?.toBO(), reactions = reactions.toBO() @@ -44,13 +44,13 @@ fun ReactionDTO.toBO() = ReactionBO( ) fun InvoiceDBO.toBO() = InvoiceBO( - id = id?.toString(), + id = id.toString(), idApp = idApp, title = title, description = description, quantity = quantity, date = Date(date), - type = InvoiceType.valueOf(type.orEmpty()), + type = InvoiceType.getFromKey(type.orEmpty()), userId = userId.orEmpty(), category = category?.toBO(), reactions = reactions.toBO() @@ -98,4 +98,33 @@ fun List?.toDBO(): List = this?.map { it.toDBO() }.orEmpt fun ReactionBO.toDBO() = ReactionDBO( id = id, unicode = unicode +) + +fun List.toDTO(): List = this.map { it.toDTO() } + +fun InvoiceBO.toDTO() = InvoiceDTO( + id = id.toString(), + idApp = idApp, + title = title, + description = description, + quantity = quantity, + date = date.time, + type = type.key, + userId = userId, + category = category?.toDTO(), + reactions = reactions.toDTO() +) + +fun CategoryBO.toDTO() = CategoryDTO( + id = id, + title = title, + color = color +) + +@JvmName("reactionBOToDTO") +fun List.toDTO(): List = this.map { it.toDTO() } + +fun ReactionBO.toDTO() = ReactionDTO( + id = id, + unicode = unicode ) \ No newline at end of file diff --git a/src/main/kotlin/es/wokis/data/repository/invoices/InvoiceRepository.kt b/src/main/kotlin/es/wokis/data/repository/invoices/InvoiceRepository.kt index e8de7bf..9a952c6 100644 --- a/src/main/kotlin/es/wokis/data/repository/invoices/InvoiceRepository.kt +++ b/src/main/kotlin/es/wokis/data/repository/invoices/InvoiceRepository.kt @@ -1,7 +1,7 @@ package es.wokis.data.repository.invoices import es.wokis.data.bo.invoice.InvoiceBO -import es.wokis.data.datasource.user.UserLocalDataSource +import es.wokis.data.datasource.invoice.InvoiceLocalDataSource interface InvoiceRepository { suspend fun getInvoicesOfUser(id: String): List @@ -10,20 +10,16 @@ interface InvoiceRepository { suspend fun deleteInvoices(id: String, invoices: List): Boolean } -class InvoiceRepositoryImpl(private val userLocalDataSource: UserLocalDataSource) : InvoiceRepository { - override suspend fun getInvoicesOfUser(id: String): List { - TODO("Not yet implemented") - } +class InvoiceRepositoryImpl(private val invoiceLocalDataSource: InvoiceLocalDataSource) : InvoiceRepository { + override suspend fun getInvoicesOfUser(id: String): List = + invoiceLocalDataSource.getInvoicesOfUser(id) - override suspend fun addInvoices(id: String, invoices: List): Boolean { - TODO("Not yet implemented") - } + override suspend fun addInvoices(id: String, invoices: List): Boolean = + invoiceLocalDataSource.addInvoices(id, invoices) - override suspend fun updateInvoices(id: String, invoices: List): Boolean { - TODO("Not yet implemented") - } + override suspend fun updateInvoices(id: String, invoices: List): Boolean = + invoiceLocalDataSource.updateInvoices(id, invoices) - override suspend fun deleteInvoices(id: String, invoices: List): Boolean { - TODO("Not yet implemented") - } + override suspend fun deleteInvoices(id: String, invoices: List): Boolean = + invoiceLocalDataSource.deleteInvoices(id, invoices) } \ No newline at end of file diff --git a/src/main/kotlin/es/wokis/routing/InvoicesRouting.kt b/src/main/kotlin/es/wokis/routing/InvoicesRouting.kt index 3dc6a99..ce51bfc 100644 --- a/src/main/kotlin/es/wokis/routing/InvoicesRouting.kt +++ b/src/main/kotlin/es/wokis/routing/InvoicesRouting.kt @@ -2,6 +2,7 @@ package es.wokis.routing import es.wokis.data.dto.invoice.InvoiceDTO import es.wokis.data.mapper.invoice.toBO +import es.wokis.data.mapper.invoice.toDTO import es.wokis.data.repository.invoices.InvoiceRepository import es.wokis.utils.user import io.ktor.http.* @@ -16,15 +17,15 @@ fun Routing.setUpInvoicesRouting() { val invoiceRepository by inject() authenticate { - get { + get("/invoices") { val user = call.user user?.id?.let { val invoices = invoiceRepository.getInvoicesOfUser(it) - call.respond(HttpStatusCode.OK, invoices) + call.respond(HttpStatusCode.OK, invoices.toDTO()) } ?: call.respond(HttpStatusCode.Unauthorized) } - post { + post("/invoices") { val user = call.user val invoices = call.receive>() user?.id?.let { @@ -33,7 +34,7 @@ fun Routing.setUpInvoicesRouting() { } ?: call.respond(HttpStatusCode.Unauthorized) } - put { + put("/invoices") { val user = call.user val invoices = call.receive>() user?.id?.let { @@ -42,7 +43,7 @@ fun Routing.setUpInvoicesRouting() { } ?: call.respond(HttpStatusCode.Unauthorized) } - delete { + delete("/invoices") { val user = call.user val invoices = call.receive>() user?.id?.let {