Compare commits

...

14 Commits

Author SHA1 Message Date
8af255bea0 Merge branch 'main' of https://git-repo.eu/maiora/backend-api-DSU
# Conflicts:
#	src/main/kotlin/eu/maiora/plugins/Routing.kt
2025-04-01 08:57:18 +02:00
e0e93f93d0 Merge pull request '0002358-endpoint-composizioni' (#5) from 0002358-endpoint-composizioni into dev
Reviewed-on: #5
2025-04-01 06:55:19 +00:00
a633d1aac6 Merge branch '0002358-endpoint-composizioni' of https://git-repo.eu/maiora/backend-api-DSU into 0002358-endpoint-composizioni
# Conflicts:
#	src/main/kotlin/eu/maiora/plugins/Routing.kt
2025-04-01 08:53:27 +02:00
3585ec9ad6 implementazione endpoint composizioni
recupero senza filtri, viene restituita la lista di tutte le composizioni dei vassoi
2025-04-01 08:52:41 +02:00
5ae17aa8a8 Merge remote-tracking branch 'upstream/dev' into dev 2025-04-01 08:48:19 +02:00
dfa518383a Merge pull request '0002393-endpoint-valorePasti' (#3) from 0002393-endpoint-valorePasti into dev
Reviewed-on: #3
2025-04-01 06:47:44 +00:00
3f8ecb0370 recupero prezzo e punti
dati una tessera, un vassoio e una data
2025-04-01 08:45:33 +02:00
0e061c9eca ripristino plugin CallLogging
permette di stampare nei log la risposta HTTP inviata da Ktor
2025-03-27 17:35:19 +01:00
7b8eaa6261 rimozione plugin CallLogging
non utilizzato (usiamo logback)
2025-03-27 17:04:17 +01:00
7f6e1fc6cb gestione rolling logs
di default ogni file di log è giornaliero e può essere al max 100MB. Il totale dei files di log può essere di 5GB e i files verranno cancellati ogni 15 giorni
2025-03-27 16:08:25 +01:00
71443ff6f3 implementazione endpoint composizioni
recupero senza filtri, viene restituita la lista di tutte le composizioni dei vassoi
2025-03-26 10:10:02 +01:00
57597c3d94 Merge remote-tracking branch 'upstream/dev' into dev
# Conflicts:
#	src/main/kotlin/eu/maiora/plugins/Routing.kt
2025-03-24 11:47:52 +01:00
28a9ec86af Merge remote-tracking branch 'upstream/dev' into dev 2025-03-05 11:59:38 +01:00
ea4edcdcee Merge remote-tracking branch 'upstream/dev' into dev 2025-03-05 09:52:55 +01:00
12 changed files with 214 additions and 10 deletions

View File

@ -1,9 +1,6 @@
package eu.maiora.db
import eu.maiora.model.Accounts
import eu.maiora.model.Movimenti
import eu.maiora.model.Parametri
import eu.maiora.model.Tessere
import eu.maiora.model.*
import kotlinx.coroutines.Dispatchers
import org.jetbrains.exposed.dao.IntEntity
import org.jetbrains.exposed.dao.IntEntityClass
@ -62,6 +59,15 @@ object MovimentiTable : IdTable<Long>("view_movimenti_api"){
val puntiPost = integer("punti_post")
}
object ComposizioniTable : IdTable<Long>("view_composizioni"){
override val id = long("id").entityId()
val idVassoio = long("id_vassoio")
val vassoio = varchar("vassoio", 255)
val idCategoria = long("id_categoria")
val categoria = varchar("categoria", 255)
val quantita = integer("quantita")
}
class AccountsDAO(id: EntityID<Int>) :IntEntity(id) {
companion object : IntEntityClass<AccountsDAO>(AccountsTable)
@ -104,6 +110,16 @@ class MovimentiDao(id: EntityID<Long>) :LongEntity(id) {
var puntiPost by MovimentiTable.puntiPost
}
class ComposizioniDao(id: EntityID<Long>) :LongEntity(id){
companion object : LongEntityClass<ComposizioniDao>(ComposizioniTable)
var idVassoio by ComposizioniTable.idVassoio
var vassoio by ComposizioniTable.vassoio
var idCategoria by ComposizioniTable.idCategoria
var categoria by ComposizioniTable.categoria
var quantita by ComposizioniTable.quantita
}
fun accountsDaoToModel(dao: AccountsDAO) = Accounts(
dao.id.value,
@ -148,6 +164,15 @@ fun movimentiDaoToModel(dao: MovimentiDao) :Movimenti{
)
}
fun composizioniDaoToModel(dao: ComposizioniDao) =Composizioni(
dao.id.value,
dao.idVassoio,
dao.vassoio,
dao.idCategoria,
dao.categoria,
dao.quantita
)

View File

@ -0,0 +1,13 @@
package eu.maiora.model
import kotlinx.serialization.Serializable
@Serializable
data class Composizioni(
val id: Long,
val idVassoio : Long,
val vassoio : String,
val idCategoria : Long,
val categoria : String,
val quantita : Int
)

View File

@ -0,0 +1,5 @@
package eu.maiora.model
interface ComposizioniRepository {
suspend fun listaComposizioni(): List<Composizioni>
}

View File

@ -0,0 +1,14 @@
package eu.maiora.model
import eu.maiora.db.*
import org.jetbrains.exposed.sql.SortOrder
class ComposizioniRepositoryImpl : ComposizioniRepository {
override suspend fun listaComposizioni(): List<Composizioni> = suspendTransaction {
// Cerca la lista di composizioni
ComposizioniDao.all()
.toList()
.map { composizioniDaoToModel(it) } // Converte il DAO in un oggetto Composizioni
}
}

View File

@ -0,0 +1,12 @@
package eu.maiora.model
import kotlinx.serialization.Serializable
@Serializable
data class ValorePasti(
val idTessera : Long,
val idVassoio : Long,
val data : String,
val prezzo : Double,
val punti : Int
)

View File

@ -0,0 +1,5 @@
package eu.maiora.model
interface ValorePastiRepository {
suspend fun valorePastoByTessVassData(idTessera : String, idVassoio : String, data : String): String
}

View File

@ -0,0 +1,31 @@
package eu.maiora.model
import eu.maiora.db.*
import org.jetbrains.exposed.sql.LongColumnType
import org.jetbrains.exposed.sql.SqlExpressionBuilder
import org.jetbrains.exposed.sql.VarCharColumnType
class ValorePastiRepositoryImpl : ValorePastiRepository {
override suspend fun valorePastoByTessVassData(idTessera : String, idVassoio : String, data : String): String = suspendTransaction {
// Cerca valore del pasto e punti in base alla tessera, al vassoio e al giorno
val result = exec("SELECT SIR.trova_tariffa(?, ?, ?) FROM dual",
listOf(
Pair(LongColumnType(), idTessera),
Pair(LongColumnType(), idVassoio),
Pair(VarCharColumnType(), data)
)){ rs ->
var resultString: String? = null
// Processiamo il ResultSet restituito dalla query
if (rs.next()) {
resultString = rs.getString(1) // Leggiamo il primo risultato
}
resultString
}
result ?: "Nessun risultato"
}
}

View File

@ -1,12 +1,15 @@
package eu.maiora.plugins
import eu.maiora.model.*
import eu.maiora.model.AccountsRepositoryImpl
import eu.maiora.model.MovimentiRepositoryImpl
import eu.maiora.model.ParametriRepositoryImpl
import eu.maiora.model.TessereRepositoryImpl
import eu.maiora.routes.auth
import eu.maiora.routes.composizioni
import eu.maiora.routes.movimenti
import eu.maiora.routes.tessere
import eu.maiora.routes.valorePasti
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
@ -20,5 +23,7 @@ fun Application.configureRouting() {
auth(AccountsRepositoryImpl())
tessere(TessereRepositoryImpl())
movimenti(MovimentiRepositoryImpl())
composizioni(ComposizioniRepositoryImpl())
valorePasti(ValorePastiRepositoryImpl())
}
}

View File

@ -31,7 +31,7 @@ fun Route.auth(accountsRepository: AccountsRepositoryImpl) {
logger.info(
"param: " +
receivedResponse.param
);
)
// Decodifica la stringa da Base64 a oggetto Credentials
val decodedBytes = Base64.getDecoder().decode(receivedResponse.param)

View File

@ -0,0 +1,20 @@
package eu.maiora.routes
import eu.maiora.model.ComposizioniRepositoryImpl
import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
fun Route.composizioni(composizioniRepository: ComposizioniRepositoryImpl){
route("/api/composizioni"){
authenticate("auth-jwt") {
get(){
val listaComposizioni = composizioniRepository.listaComposizioni()
call.respond(listaComposizioni)
}
}
}
}

View File

@ -0,0 +1,50 @@
package eu.maiora.routes
import eu.maiora.model.TessereRepositoryImpl
import eu.maiora.model.ValorePasti
import eu.maiora.model.ValorePastiRepository
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
fun Route.valorePasti(valorePastiRepository: ValorePastiRepository){
route("/api/valorePasti"){
authenticate("auth-jwt") {
get(){
// Ottieni i parametri dal percorso
val idTessera = call.parameters["idTessera"]
val idVassoio = call.parameters["idVassoio"]
val data = call.parameters["data"]
if (idTessera == null) {
call.respondText("ID tessera non valido", status = HttpStatusCode.BadRequest)
return@get
}
if (idVassoio == null) {
call.respondText("ID vassoio non valido", status = HttpStatusCode.BadRequest)
return@get
}
if (data == null) {
call.respondText("data non valida", status = HttpStatusCode.BadRequest)
return@get
}
// Cerca la tessera per codice fiscale
val valorePasto = valorePastiRepository.valorePastoByTessVassData(idTessera, idVassoio, data)
val prezzo = valorePasto.split("#").get(0)
val punti = valorePasto.split("#").get(1)
call.respond( ValorePasti(idTessera.toLong(),
idVassoio.toLong(), data,
prezzo.replace(',', '.').toDouble(),
punti.toInt()))
}
}
}
}

View File

@ -1,19 +1,43 @@
<configuration>
<!-- Appender per la console -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>./logFile.log</file>
<!-- Appender per il file di log con rotazione basata su tempo e dimensione -->
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>./log/logFile.log</file> <!-- File di log principale -->
<append>true</append>
<!-- RollingPolicy per dimensione e tempo -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- Pattern per il nome dei file ruotati: include la data -->
<FileNamePattern>./log/logFile.%d{yyyy-MM-dd}.%i.log</FileNamePattern> <!-- %i è il numero di file generato -->
<!-- Limita la dimensione del file a 100MB -->
<maxFileSize>100MB</maxFileSize> <!-- Ruota il file quando raggiunge 100MB -->
<!-- Conserva i log per due settimane -->
<maxHistory>15</maxHistory> <!-- Limita a 15 giorni i log archiviati -->
<!-- Limita la dimensione totale dei file di log a 5GB -->
<totalSizeCap>5GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="trace">
<appender-ref ref="FILE"/>
<!-- Configurazione del livello di log -->
<root level="DEBUG">
<appender-ref ref="ROLLING_FILE"/>
<appender-ref ref="STDOUT"/>
</root>
<logger name="io.netty" level="INFO"/>
</configuration>
</configuration>