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 6b44867..8489bc6 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,15 +16,12 @@ 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 suspend fun updateUser(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/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 82b5005..e9339c6 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( @@ -16,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() @@ -30,7 +35,96 @@ 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.getFromKey(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 +) + +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 new file mode 100644 index 0000000..9a952c6 --- /dev/null +++ b/src/main/kotlin/es/wokis/data/repository/invoices/InvoiceRepository.kt @@ -0,0 +1,25 @@ +package es.wokis.data.repository.invoices + +import es.wokis.data.bo.invoice.InvoiceBO +import es.wokis.data.datasource.invoice.InvoiceLocalDataSource + +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 invoiceLocalDataSource: InvoiceLocalDataSource) : InvoiceRepository { + override suspend fun getInvoicesOfUser(id: String): List = + invoiceLocalDataSource.getInvoicesOfUser(id) + + override suspend fun addInvoices(id: String, invoices: List): Boolean = + invoiceLocalDataSource.addInvoices(id, invoices) + + override suspend fun updateInvoices(id: String, invoices: List): Boolean = + invoiceLocalDataSource.updateInvoices(id, invoices) + + 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/data/repository/user/UserRepository.kt b/src/main/kotlin/es/wokis/data/repository/user/UserRepository.kt index 26eb4b7..1e770d2 100644 --- a/src/main/kotlin/es/wokis/data/repository/user/UserRepository.kt +++ b/src/main/kotlin/es/wokis/data/repository/user/UserRepository.kt @@ -7,14 +7,13 @@ import com.google.api.client.json.gson.GsonFactory import es.wokis.data.bo.user.UserBO import es.wokis.data.constants.ServerConstants.DEFAULT_LANG import es.wokis.data.constants.ServerConstants.EMPTY_TEXT -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.config import es.wokis.plugins.makeToken import es.wokis.utils.HashGenerator -import es.wokis.utils.generatePassword import org.mindrot.jbcrypt.BCrypt interface UserRepository { @@ -29,7 +28,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 { @@ -82,7 +80,7 @@ class UserRepositoryImpl(private val userLocalDataSource: UserLocalDataSource) : ) ) } - token + token } else { login( @@ -120,7 +118,6 @@ class UserRepositoryImpl(private val userLocalDataSource: UserLocalDataSource) : userLocalDataSource.getUserByUsername(it) } - override suspend fun getUserByEmail(email: String?): UserBO? = email?.let { userLocalDataSource.getUserByEmail(it) } 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..ce51bfc 100644 --- a/src/main/kotlin/es/wokis/routing/InvoicesRouting.kt +++ b/src/main/kotlin/es/wokis/routing/InvoicesRouting.kt @@ -1,12 +1,56 @@ 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.mapper.invoice.toDTO +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("/invoices") { + val user = call.user + user?.id?.let { + val invoices = invoiceRepository.getInvoicesOfUser(it) + call.respond(HttpStatusCode.OK, invoices.toDTO()) + } ?: call.respond(HttpStatusCode.Unauthorized) + } + + post("/invoices") { + 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("/invoices") { + 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("/invoices") { + 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