Compare commits

...

16 Commits

Author SHA1 Message Date
4b788d7d1f Merge branch 'main' of https://git-repo.eu/maiora/backend-api-DSU 2025-04-30 12:03:55 +02:00
f88167d87e Merge pull request '0002429-endpoint-prenotazioni' (#14) from 0002429-endpoint-prenotazioni into dev
Reviewed-on: #14
2025-04-30 10:03:04 +00:00
4c80fdcdb3 aggiunta campo codice ristocloud 2025-04-30 12:01:33 +02:00
73e46947cd Merge pull request '0002430-endpoint-annullaPrenotazioni' (#13) from 0002430-endpoint-annullaPrenotazioni into 0002429-endpoint-prenotazioni
Reviewed-on: #13
2025-04-30 09:18:23 +00:00
635b19e17a PATCH annulla prenotazione 2025-04-30 11:16:46 +02:00
fbcef1af3e /POST prenotazioni
inserimento nuova prenotazione, con i relativi prodotti
2025-04-29 14:43:16 +02:00
4c3ea7fbf0 Merge pull request '0002441-endpoint-residenze' (#12) from 0002441-endpoint-residenze into dev
Reviewed-on: #12
2025-04-28 09:14:11 +00:00
d5db89f5c2 /GET residenze 2025-04-28 11:13:20 +02:00
3fe10dfcdb Merge pull request '0002440-endpoint-prodottiDisponibili' (#11) from 0002440-endpoint-prodottiDisponibili into dev
Reviewed-on: #11
2025-04-28 08:52:03 +00:00
213d7fdd74 GET prodotti prenotabili 2025-04-14 17:03:57 +02:00
3995d993e5 Merge pull request '0002438-endpoint-puntiDistribuzione' (#10) from 0002438-endpoint-puntiDistribuzione into dev
Reviewed-on: #10
2025-04-14 09:58:43 +00:00
eae52617a3 modifica controlli sui parametri 2025-04-14 11:57:30 +02:00
837914f913 Merge pull request '0002439-endpoint-slotOrari' (#9) from 0002439-endpoint-slotOrari into dev
Reviewed-on: #9
2025-04-14 09:51:03 +00:00
10d2fefa24 GET recupero slot orari 2025-04-14 11:47:55 +02:00
1adb9c5f0e Merge pull request '0002438-endpoint-puntiDistribuzione' (#8) from 0002438-endpoint-puntiDistribuzione into dev
Reviewed-on: #8
2025-04-11 14:29:17 +00:00
5c169dcfdd GET recupero punti distribuzione 2025-04-11 16:28:18 +02:00
30 changed files with 927 additions and 0 deletions

View File

@ -2,6 +2,7 @@ package eu.maiora.db
import eu.maiora.model.*
import kotlinx.coroutines.Dispatchers
import kotlinx.datetime.toKotlinLocalDateTime
import org.jetbrains.exposed.dao.IntEntity
import org.jetbrains.exposed.dao.IntEntityClass
import org.jetbrains.exposed.dao.LongEntity
@ -9,6 +10,7 @@ import org.jetbrains.exposed.dao.LongEntityClass
import org.jetbrains.exposed.dao.id.EntityID
import org.jetbrains.exposed.dao.id.IdTable
import org.jetbrains.exposed.sql.Transaction
import org.jetbrains.exposed.sql.javatime.date
import org.jetbrains.exposed.sql.javatime.datetime
import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
import java.time.format.DateTimeFormatter
@ -76,6 +78,73 @@ object RicaricheTable : IdTable<Long>("ricariche_app"){
val importo = double("importo")
}
object SlotPrenotabiliTable : IdTable<Long>("view_slot_prenotabili"){
override val id = long("id").entityId()
val giorno = date("giorno")
val dataInizio = datetime("data_inizio")
val dataFine = datetime("data_fine")
val dataLimiteCancellazione = datetime("data_limite_cancellazione")
val idModalita = long("id_modalita")
val modalitaPrenotazione = varchar("modalita_prenotazione", 255)
val idPuntoDistribuzione = long("id_punto_distribuzione")
val puntoDistribuzione = varchar("punto_distribuzione", 255)
val idPuntoCassa = long("id_punto_cassa")
val puntoCassa = varchar("punto_cassa", 255)
val idTurno = long("id_turno")
val turno = varchar("turno", 255)
val idResidenza = long("id_residenza").nullable()
val residenza = varchar("residenza", 255).nullable()
}
object ProdottiPrenotabiliTable : IdTable<Long>("view_prodotti_prenotabili"){
override val id = long("id").entityId()
val giorno = date("giorno")
val idPuntoDistribuzione = long("id_punto_distribuzione")
val puntoDistribuzione = varchar("punto_distribuzione", 255)
val idTurno = long("id_turno")
val turno = varchar("turno", 255)
val idProdotto = long("id_prodotto")
val prodotto = varchar("prodotto", 255)
val codiceProdotto = varchar("codice_prodotto", 255)
val descrizioneProdotto = varchar("descrizione_prodotto", 255)
val idCategoria = long("id_categoria")
val categoria = varchar("categoria", 255)
val idModalita = long("id_modalita")
val modalitaPrenotazione = varchar("modalita_prenotazione", 255)
}
object ResidenzeTable : IdTable<Long>("residenze"){
override val id = long("id").entityId()
val idPuntoDistribuzione = long("id_punto_distribuzione")
val nome = varchar("nome", 255)
}
object PrenotazioniPastiTable : IdTable<Long>("prenotazioni_pasti"){
override val id = long("id").autoIncrement("seq_prenotazioni_pasti").entityId()
val idTessera = long("id_tessera")
val idSlotPuntoCassa = long("id_slot_punto_cassa")
val idResidenza = long("id_residenza").nullable()
val idVassoio = long("id_vassoio")
val importoPagato = double("importo_pagato")
val codiceRistocloud = varchar("codice_ristocloud", 255).nullable()
}
object PrenotazioniPastiDettaglioTable : IdTable<Long>("prenotazioni_pasti_dettaglio"){
override val id = long("id").autoIncrement("seq_pren_past_dettaglio").entityId()
val idPrenotazione = long("id_prenotazione")
val idProdotto = long("id_prodotto")
val idStato = long("id_stato")
}
object ViewPrenotazioniPastiTable : IdTable<Long>("view_prenotazioni_pasti"){
override val id = long("id").entityId()
val idPrenotazione = long("id_prenotazione")
val idStato = long("id_stato")
val stato = varchar("stato", 255)
val dataLimiteCancellazione = datetime("data_limite_cancellazione")
}
class AccountsDAO(id: EntityID<Int>) :IntEntity(id) {
companion object : IntEntityClass<AccountsDAO>(AccountsTable)
@ -137,6 +206,77 @@ class RicaricheDao(id: EntityID<Long>) :LongEntity(id){
var importo by RicaricheTable.importo
}
class SlotPrenotabiliDao(id: EntityID<Long>) :LongEntity(id) {
companion object : LongEntityClass<SlotPrenotabiliDao>(SlotPrenotabiliTable)
var giorno by SlotPrenotabiliTable.giorno
var dataInizio by SlotPrenotabiliTable.dataInizio
var dataFine by SlotPrenotabiliTable.dataFine
var dataLimiteCancellazione by SlotPrenotabiliTable.dataLimiteCancellazione
var idModalita by SlotPrenotabiliTable.idModalita
var modalitaPrenotazione by SlotPrenotabiliTable.modalitaPrenotazione
var idPuntoDistribuzione by SlotPrenotabiliTable.idPuntoDistribuzione
var puntoDistribuzione by SlotPrenotabiliTable.puntoDistribuzione
var idPuntoCassa by SlotPrenotabiliTable.idPuntoCassa
var puntoCassa by SlotPrenotabiliTable.puntoCassa
var idTurno by SlotPrenotabiliTable.idTurno
var turno by SlotPrenotabiliTable.turno
var idResidenza by SlotPrenotabiliTable.idResidenza
var residenza by SlotPrenotabiliTable.residenza
}
class ProdottiPrenotabiliDao(id: EntityID<Long>) :LongEntity(id) {
companion object : LongEntityClass<ProdottiPrenotabiliDao>(ProdottiPrenotabiliTable)
var giorno by ProdottiPrenotabiliTable.giorno
var idPuntoDistribuzione by ProdottiPrenotabiliTable.idPuntoDistribuzione
var puntoDistribuzione by ProdottiPrenotabiliTable.puntoDistribuzione
var idTurno by ProdottiPrenotabiliTable.idTurno
var turno by ProdottiPrenotabiliTable.turno
var idProdotto by ProdottiPrenotabiliTable.idProdotto
var prodotto by ProdottiPrenotabiliTable.prodotto
var codiceProdotto by ProdottiPrenotabiliTable.codiceProdotto
var descrizioneProdotto by ProdottiPrenotabiliTable.descrizioneProdotto
var idCategoria by ProdottiPrenotabiliTable.idCategoria
var categoria by ProdottiPrenotabiliTable.categoria
var idModalita by ProdottiPrenotabiliTable.idModalita
var modalitaPrenotazione by ProdottiPrenotabiliTable.modalitaPrenotazione
}
class ResidenzeDao(id: EntityID<Long>) :LongEntity(id){
companion object : LongEntityClass<ResidenzeDao>(ResidenzeTable)
val idPuntoDistribuzione by ResidenzeTable.idPuntoDistribuzione
val nome by ResidenzeTable.nome
}
class PrenotazioniPastiDao(id: EntityID<Long>) :LongEntity(id){
companion object : LongEntityClass<PrenotazioniPastiDao>(PrenotazioniPastiTable)
val idTessera by PrenotazioniPastiTable.idTessera
val idSlotPuntoCassa by PrenotazioniPastiTable.idSlotPuntoCassa
val idResidenza by PrenotazioniPastiTable.idResidenza
val idVassoio by PrenotazioniPastiTable.idVassoio
val importoPagato by PrenotazioniPastiTable.importoPagato
val codiceRistocloud by PrenotazioniPastiTable.codiceRistocloud
}
class PrenotazioniPastiDettaglioDao(id: EntityID<Long>) :LongEntity(id){
companion object : LongEntityClass<PrenotazioniPastiDettaglioDao>(PrenotazioniPastiDettaglioTable)
val idPrenotazione by PrenotazioniPastiDettaglioTable.idPrenotazione
val idProdotto by PrenotazioniPastiDettaglioTable.idProdotto
val idStato by PrenotazioniPastiDettaglioTable.idStato
}
class ViewPrenotazioniPastiDao(id: EntityID<Long>) :LongEntity(id){
companion object : LongEntityClass<ViewPrenotazioniPastiDao>(ViewPrenotazioniPastiTable)
val idPrenotazione by ViewPrenotazioniPastiTable.idPrenotazione
val idStato by ViewPrenotazioniPastiTable.idStato
val stato by ViewPrenotazioniPastiTable.stato
val dataLimiteCancellazione by ViewPrenotazioniPastiTable.dataLimiteCancellazione
}
fun accountsDaoToModel(dao: AccountsDAO) = Accounts(
dao.id.value,
@ -190,6 +330,106 @@ fun composizioniDaoToModel(dao: ComposizioniDao) = Composizioni(
dao.quantita
)
fun puntiDistribuzioneDaoToModel(dao: SlotPrenotabiliDao) :PuntiDistribuzione{
return PuntiDistribuzione(
dao.id.value,
dao.idPuntoDistribuzione,
dao.puntoDistribuzione,
dao.idPuntoCassa,
dao.puntoCassa,
dao.idModalita,
dao.modalitaPrenotazione
)
}
fun slotOrariDaoToModel(dao: SlotPrenotabiliDao) :SlotOrari{
val formatterGiorno = DateTimeFormatter.ofPattern("ddMMyyyy")
val formatterConOra = DateTimeFormatter.ofPattern("ddMMyyyy HH:mm")
val formattedGiorno = dao.giorno.format(formatterGiorno)
val formattedDataInizio = dao.dataInizio.format(formatterConOra)
val formattedDataFine = dao.dataFine.format(formatterConOra)
val formattedDataLimiteCancellazione = dao.dataLimiteCancellazione.format(formatterConOra)
return SlotOrari(
dao.id.value,
formattedGiorno,
formattedDataInizio,
formattedDataFine,
formattedDataLimiteCancellazione,
dao.idPuntoDistribuzione,
dao.puntoDistribuzione,
dao.idPuntoCassa,
dao.puntoCassa,
dao.idModalita,
dao.modalitaPrenotazione,
dao.idTurno,
dao.turno,
dao.idResidenza,
dao.residenza
)
}
fun prodottiPrenotabiliDaoToModel(dao: ProdottiPrenotabiliDao) :ProdottiPrenotabili{
val formatterGiorno = DateTimeFormatter.ofPattern("ddMMyyyy")
val formattedGiorno = dao.giorno.format(formatterGiorno)
return ProdottiPrenotabili(
dao.id.value,
formattedGiorno,
dao.idPuntoDistribuzione,
dao.puntoDistribuzione,
dao.idTurno,
dao.turno,
dao.idProdotto,
dao.prodotto,
dao.codiceProdotto,
dao.descrizioneProdotto,
dao.idCategoria,
dao.categoria,
dao.idModalita,
dao.modalitaPrenotazione
)
}
fun residenzeDaoToModel(dao: ResidenzeDao) :Residenze{
return Residenze(
dao.id.value,
dao.idPuntoDistribuzione,
dao.nome
)
}
fun prenotazioniPastiDaoToModel(dao: PrenotazioniPastiDao) : PrenotazioniPasti{
return PrenotazioniPasti(
dao.id.value,
dao.idTessera,
dao.idSlotPuntoCassa,
dao.idResidenza,
dao.idVassoio,
dao.importoPagato,
dao.codiceRistocloud
)
}
fun prenotazioniPastiDettaglioDaoToModel(dao: PrenotazioniPastiDettaglioDao) : PrenotazioniPastiDettaglio{
return PrenotazioniPastiDettaglio(
dao.id.value,
dao.idPrenotazione,
dao.idProdotto,
dao.idStato
)
}
fun viewPrenotazioniPastiDaoToModel(dao: ViewPrenotazioniPastiDao) : ViewPrenotazioniPasti{
return ViewPrenotazioniPasti(
dao.id.value,
dao.idPrenotazione,
dao.idStato,
dao.stato,
dao.dataLimiteCancellazione.toKotlinLocalDateTime()
)
}
suspend fun <T> suspendTransaction(block: Transaction.() -> T): T =
newSuspendedTransaction(Dispatchers.IO, statement = block)

View File

@ -0,0 +1,21 @@
package eu.maiora.model
import kotlinx.serialization.Serializable
@Serializable
data class Prenotazioni(
val id: Long? = null,
val codiceRistocloud: String? = null,
val idTessera : Long,
val idSlotPuntoCassa : Long,
val giorno : String? = null,
val turno : String? = null,
val dataInizio : String? = null,
val dataFine : String? = null,
val dataLimiteCancellazione : String? = null,
val idVassoio : Long,
val idStato : Long? = null,
val stato : String? = null,
val listaProdotti : List<ProdottiPrenotabili>? = null,
val importoPagato : Double
)

View File

@ -0,0 +1,14 @@
package eu.maiora.model
import kotlinx.serialization.Serializable
@Serializable
data class PrenotazioniPasti(
val id: Long,
val idTessera : Long,
val idSlotPuntoCassa : Long,
val idResidenza : Long? = null,
val idVassoio : Long,
val importoPagato : Double,
val codiceRistocloud : String? = null
)

View File

@ -0,0 +1,11 @@
package eu.maiora.model
import kotlinx.serialization.Serializable
@Serializable
data class PrenotazioniPastiDettaglio(
val id: Long? = null,
val idPrenotazione : Long,
val idProdotto : Long,
val idStato : Long
)

View File

@ -0,0 +1,7 @@
package eu.maiora.model
interface PrenotazioniPastiDettaglioRepository {
suspend fun insert(prenotazionePastoDettaglio : PrenotazioniPastiDettaglio): PrenotazioniPastiDettaglio
suspend fun update(prenotazionePastoDettaglio: PrenotazioniPastiDettaglio): PrenotazioniPastiDettaglio
suspend fun listaDettagliByIdPrenotazione(idPrenotazione : Long): List<PrenotazioniPastiDettaglio>
}

View File

@ -0,0 +1,42 @@
package eu.maiora.model
import eu.maiora.db.*
import org.jetbrains.exposed.sql.insertAndGetId
import org.jetbrains.exposed.sql.update
class PrenotazioniPastiDettaglioRepositoryImpl : PrenotazioniPastiDettaglioRepository {
override suspend fun insert(prenotazionePastoDettaglio : PrenotazioniPastiDettaglio): PrenotazioniPastiDettaglio = suspendTransaction {
// Inserisci un nuovo dettaglio di una prenotazione pasto
// ID non definito: viene gestito dalla sequence
val idPrenPastiDettInserted = PrenotazioniPastiDettaglioTable.insertAndGetId {
it[idPrenotazione] = prenotazionePastoDettaglio.idPrenotazione
it[idProdotto] = prenotazionePastoDettaglio.idProdotto
it[idStato] = prenotazionePastoDettaglio.idStato
}.value
PrenotazioniPastiDettaglio(
idPrenPastiDettInserted,
prenotazionePastoDettaglio.idPrenotazione,
prenotazionePastoDettaglio.idProdotto,
prenotazionePastoDettaglio.idStato
)
}
override suspend fun update (prenotazionePastoDettaglio : PrenotazioniPastiDettaglio): PrenotazioniPastiDettaglio = suspendTransaction {
PrenotazioniPastiDettaglioTable.update({PrenotazioniPastiDettaglioTable.id eq prenotazionePastoDettaglio.id}){
it[idPrenotazione] = prenotazionePastoDettaglio.idPrenotazione
it[idProdotto] = prenotazionePastoDettaglio.idProdotto
it[idStato] = prenotazionePastoDettaglio.idStato
}
prenotazionePastoDettaglio
}
override suspend fun listaDettagliByIdPrenotazione(idPrenotazione : Long): List<PrenotazioniPastiDettaglio> = suspendTransaction {
// Cerca la lista di dettagli della prenotazione (ovvero i prodotti)
PrenotazioniPastiDettaglioDao.find { PrenotazioniPastiDettaglioTable.idPrenotazione eq idPrenotazione }
.toList() // Restituisce la lista dei prodotti
.map { prenotazioniPastiDettaglioDaoToModel(it) } // Converte il DAO in un oggetto PrenotazioniPastiDettaglio
}
}

View File

@ -0,0 +1,5 @@
package eu.maiora.model
interface PrenotazioniPastiRepository {
suspend fun insert(prenotazionePasto : PrenotazioniPasti): PrenotazioniPasti
}

View File

@ -0,0 +1,29 @@
package eu.maiora.model
import eu.maiora.db.*
import org.jetbrains.exposed.sql.insertAndGetId
class PrenotazioniPastiRepositoryImpl : PrenotazioniPastiRepository {
override suspend fun insert(prenotazionePasto : PrenotazioniPasti): PrenotazioniPasti = suspendTransaction {
// Inserisci una nuova prenotazione pasto
// ID non definito: viene gestito dalla sequence
val idPrenPastiInserted = PrenotazioniPastiTable.insertAndGetId {
it[idTessera] = prenotazionePasto.idTessera
it[idSlotPuntoCassa] = prenotazionePasto.idSlotPuntoCassa
it[idResidenza] = prenotazionePasto.idResidenza
it[idVassoio] = prenotazionePasto.idVassoio
it[importoPagato] = prenotazionePasto.importoPagato
it[codiceRistocloud] = prenotazionePasto.codiceRistocloud
}.value
PrenotazioniPasti(
idPrenPastiInserted,
prenotazionePasto.idTessera,
prenotazionePasto.idSlotPuntoCassa,
prenotazionePasto.idResidenza,
prenotazionePasto.idVassoio,
prenotazionePasto.importoPagato,
prenotazionePasto.codiceRistocloud
)
}
}

View File

@ -0,0 +1,21 @@
package eu.maiora.model
import kotlinx.serialization.Serializable
@Serializable
data class ProdottiPrenotabili(
val id: Long,
val giorno : String? = null,
val idPuntoDistribuzione : Long? = null,
val puntoDistribuzione : String? = null,
val idTurno : Long? = null,
val turno : String? = null,
val idProdotto : Long? = null,
val prodotto : String? = null,
val codiceProdotto : String? = null,
val descrizioneProdotto : String? = null,
val idCategoria : Long? = null,
val categoria : String? = null,
val idModalita : Long? = null,
val modalitaPrenotazione : String? = null
)

View File

@ -0,0 +1,8 @@
package eu.maiora.model
interface ProdottiPrenotabiliRepository {
suspend fun prodottiPrenotabiliByGiornoIdTurnoIdPuntoDistIdMod(giorno : String,
idTurno : Long,
idPuntoDistribuzione : Long,
idModalita : Long): List<ProdottiPrenotabili>?
}

View File

@ -0,0 +1,25 @@
package eu.maiora.model
import eu.maiora.db.*
import org.jetbrains.exposed.sql.and
import java.time.LocalDate
import java.time.format.DateTimeFormatter
class ProdottiPrenotabiliRepositoryImpl : ProdottiPrenotabiliRepository {
override suspend fun prodottiPrenotabiliByGiornoIdTurnoIdPuntoDistIdMod(giorno : String,
idTurno : Long,
idPuntoDistribuzione : Long,
idModalita : Long): List<ProdottiPrenotabili> = suspendTransaction {
// Cerca la lista di prodotti prenotabili
val formatter = DateTimeFormatter.ofPattern("ddMMyyyy")
val formattedDate = LocalDate.parse(giorno, formatter)
ProdottiPrenotabiliDao.find { (ProdottiPrenotabiliTable.giorno eq formattedDate) and
(ProdottiPrenotabiliTable.idTurno eq idTurno) and
(ProdottiPrenotabiliTable.idPuntoDistribuzione eq idPuntoDistribuzione) and
(ProdottiPrenotabiliTable.idModalita eq idModalita)}
.toList() // Restituisce la lista dei prodotti prenotabili
.map { prodottiPrenotabiliDaoToModel(it) } // Converte il DAO in un oggetto ProdottiPrenotabili
}
}

View File

@ -0,0 +1,14 @@
package eu.maiora.model
import kotlinx.serialization.Serializable
@Serializable
data class PuntiDistribuzione(
val id: Long,
val idPuntoDistribuzione : Long,
val puntoDistribuzione : String,
val idPuntoCassa : Long,
val puntoCassa : String,
val idModalita : Long,
val modalitaPrenotazione : String
)

View File

@ -0,0 +1,5 @@
package eu.maiora.model
interface PuntiDistribuzioneRepository {
suspend fun puntiDistByGiornoIdTurno(giorno : String, idTurno : Long): List<PuntiDistribuzione>?
}

View File

@ -0,0 +1,21 @@
package eu.maiora.model
import eu.maiora.db.*
import org.jetbrains.exposed.sql.SortOrder
import org.jetbrains.exposed.sql.and
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
class PuntiDistribuzioneRepositoryImpl : PuntiDistribuzioneRepository {
override suspend fun puntiDistByGiornoIdTurno(giorno : String, idTurno : Long): List<PuntiDistribuzione> = suspendTransaction {
// Cerca la lista di punti distribuzione dalla tabella degli slot prenotabili
val formatter = DateTimeFormatter.ofPattern("ddMMyyyy")
val formattedDate = LocalDate.parse(giorno, formatter)
SlotPrenotabiliDao.find { (SlotPrenotabiliTable.giorno eq formattedDate) and (SlotPrenotabiliTable.idTurno eq idTurno)}
.toList() // Restituisce la lista degli slot prenotabili da cui ricavare i punti distribuzione
.map { puntiDistribuzioneDaoToModel(it) } // Converte il DAO in un oggetto PuntiDistribuzione
}
}

View File

@ -0,0 +1,10 @@
package eu.maiora.model
import kotlinx.serialization.Serializable
@Serializable
data class Residenze(
val id: Long,
val idPuntoDistribuzione : Long,
val nome : String
)

View File

@ -0,0 +1,5 @@
package eu.maiora.model
interface ResidenzeRepository {
suspend fun listaResidenze(): List<Residenze>
}

View File

@ -0,0 +1,13 @@
package eu.maiora.model
import eu.maiora.db.*
class ResidenzeRepositoryImpl : ResidenzeRepository {
override suspend fun listaResidenze(): List<Residenze> = suspendTransaction {
// Cerca la lista di composizioni
ResidenzeDao.all()
.toList()
.map { residenzeDaoToModel(it) } // Converte il DAO in un oggetto Residenze
}
}

View File

@ -0,0 +1,22 @@
package eu.maiora.model
import kotlinx.serialization.Serializable
@Serializable
data class SlotOrari(
val id: Long,
val giorno : String,
val dataInizio : String,
val dataFine : String,
val dataLimiteCancellazione : String,
val idPuntoDistribuzione : Long,
val puntoDistribuzione : String,
val idPuntoCassa : Long,
val puntoCassa : String,
val idModalita : Long,
val modalitaPrenotazione : String,
val idTurno : Long,
val turno : String,
val idResidenza : Long? = null,
val residenza : String? = null
)

View File

@ -0,0 +1,12 @@
package eu.maiora.model
interface SlotOrariRepository {
suspend fun slotOrariByGiornoIdTurnoIdPuntoDistIdMod(giorno : String,
idTurno : Long,
idPuntoDistribuzione : Long,
idModalita : Long): List<SlotOrari>?
suspend fun idResidenzaByIdSlotOrario(idSlot : Long) : Long?
suspend fun slotOrarioById(idSlot : Long) : SlotOrari?
}

View File

@ -0,0 +1,38 @@
package eu.maiora.model
import eu.maiora.db.*
import org.jetbrains.exposed.sql.and
import java.time.LocalDate
import java.time.format.DateTimeFormatter
class SlotOrariRepositoryImpl : SlotOrariRepository {
override suspend fun slotOrariByGiornoIdTurnoIdPuntoDistIdMod(giorno : String,
idTurno : Long,
idPuntoDistribuzione : Long,
idModalita : Long): List<SlotOrari> = suspendTransaction {
// Cerca la lista di slot orari
val formatter = DateTimeFormatter.ofPattern("ddMMyyyy")
val formattedDate = LocalDate.parse(giorno, formatter)
SlotPrenotabiliDao.find { (SlotPrenotabiliTable.giorno eq formattedDate) and
(SlotPrenotabiliTable.idTurno eq idTurno) and
(SlotPrenotabiliTable.idPuntoDistribuzione eq idPuntoDistribuzione) and
(SlotPrenotabiliTable.idModalita eq idModalita)}
.toList() // Restituisce la lista degli slot prenotabili da cui ricavare i punti distribuzione
.map { slotOrariDaoToModel(it) } // Converte il DAO in un oggetto SlotOrari
}
override suspend fun idResidenzaByIdSlotOrario(idSlot : Long) : Long? = suspendTransaction {
SlotPrenotabiliDao.find{ SlotPrenotabiliTable.id eq idSlot }
.single() // Restituisce un singolo risultato o null se non trovato
.let { slotOrariDaoToModel(it) } // Converte il DAO in un oggetto SlotOrari
.idResidenza
}
override suspend fun slotOrarioById(idSlot : Long) : SlotOrari? = suspendTransaction {
SlotPrenotabiliDao.find{ SlotPrenotabiliTable.id eq idSlot }
.singleOrNull() // Restituisce un singolo risultato o null se non trovato
?.let { slotOrariDaoToModel(it) } // Converte il DAO in un oggetto SlotOrari
}
}

View File

@ -0,0 +1,13 @@
package eu.maiora.model
import kotlinx.datetime.LocalDateTime
import kotlinx.serialization.Serializable
@Serializable
data class ViewPrenotazioniPasti(
val id: Long,
val idPrenotazione: Long,
val idStato: Long,
val stato: String,
val dataLimiteCancellazione: LocalDateTime
)

View File

@ -0,0 +1,5 @@
package eu.maiora.model
interface ViewPrenotazioniPastiRepository {
suspend fun prenotazioniPastiById(id : Long): ViewPrenotazioniPasti
}

View File

@ -0,0 +1,15 @@
package eu.maiora.model
import eu.maiora.db.*
import org.jetbrains.exposed.sql.SortOrder
import org.jetbrains.exposed.sql.insertAndGetId
class ViewPrenotazioniPastiRepositoryImpl : ViewPrenotazioniPastiRepository {
override suspend fun prenotazioniPastiById(id : Long): ViewPrenotazioniPasti = suspendTransaction {
// Cerca la prenotazione
ViewPrenotazioniPastiDao.find { ViewPrenotazioniPastiTable.idPrenotazione eq id }
.first() //prendo solo il primo record, dato che ci sono tanti record quanti prodotti prenotati
.let { viewPrenotazioniPastiDaoToModel(it) } // Converte il DAO in un oggetto ViewPrenotazioniPasti
}
}

View File

@ -18,5 +18,11 @@ fun Application.configureRouting() {
composizioni(ComposizioniRepositoryImpl())
valorePasti(ValorePastiRepositoryImpl())
ricariche(RicaricheRepositoryImpl())
puntiDistribuzione(PuntiDistribuzioneRepositoryImpl())
slotOrari(SlotOrariRepositoryImpl())
prodottiPrenotabili(ProdottiPrenotabiliRepositoryImpl())
residenze(ResidenzeRepositoryImpl())
prenotazioni(PrenotazioniPastiRepositoryImpl(), SlotOrariRepositoryImpl(), PrenotazioniPastiDettaglioRepositoryImpl())
annullaPrenotazioni(ViewPrenotazioniPastiRepositoryImpl(), PrenotazioniPastiDettaglioRepositoryImpl())
}
}

View File

@ -0,0 +1,71 @@
package eu.maiora.routes
import eu.maiora.model.*
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import kotlinx.datetime.toJavaLocalDateTime
import java.time.LocalDateTime
fun Route.annullaPrenotazioni(
viewPrenotazioniPastiRepository: ViewPrenotazioniPastiRepositoryImpl,
prenotazioniPastiDettaglioRepository: PrenotazioniPastiDettaglioRepositoryImpl
) {
route("/api/annullaPrenotazioni") {
authenticate("auth-jwt") {
patch("{idPrenotazione}") {
//ottieni l'id della prenotazione dal percorso
val idPrenotazione = call.parameters["idPrenotazione"]
if (idPrenotazione == null) {
call.respondText("ID prenotazione non valido", status = HttpStatusCode.BadRequest)
return@patch
}
val prenotazione = viewPrenotazioniPastiRepository.prenotazioniPastiById(idPrenotazione.toLong())
val statoPrenotazione = prenotazione.stato
//prenotazione annullabile se lo stato non è SERVITA 2L
if (prenotazione.idStato == 2L) {
call.respond(
HttpStatusCode.BadRequest,
"Prenotazione non annullata. Stato corrente della prenotazione: $statoPrenotazione"
)
return@patch
}
//prenotazione annullabile se la data limite per la cancellazione non è stato superato
if (LocalDateTime.now().isAfter(prenotazione.dataLimiteCancellazione.toJavaLocalDateTime())) {
call.respond(
HttpStatusCode.BadRequest,
"Prenotazione non annullata: data limite cancellazione superata"
)
return@patch
}
val listaProdottiPrenotati =
prenotazioniPastiDettaglioRepository.listaDettagliByIdPrenotazione(idPrenotazione.toLong())
//aggiorna lo stato di ogni prodotto per annullare la prenotazione
listaProdottiPrenotati.forEach { el ->
val prodottoDaAggiornare = PrenotazioniPastiDettaglio(
el.id,
el.idPrenotazione,
el.idProdotto,
3L //ANNULLATA
)
prenotazioniPastiDettaglioRepository.update(prodottoDaAggiornare)
}
call.respond(HttpStatusCode.OK, "Prenotazione $idPrenotazione annullata")
}
}
}
}

View File

@ -0,0 +1,84 @@
package eu.maiora.routes
import eu.maiora.model.*
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.*
fun Route.prenotazioni(prenotazioniPastiRepository: PrenotazioniPastiRepository,
slotOrariRepository: SlotOrariRepository,
prenotazioniPastiDettaglioRepository : PrenotazioniPastiDettaglioRepository){
route("/api/prenotazioni"){
authenticate("auth-jwt") {
post(){
try{
val listaDettagliInseriti = mutableListOf<PrenotazioniPastiDettaglio>()
val prenotazioneRequest = call.receive<Prenotazioni>()
//recupera lo slot orario selezionato
val idSlotOrario = slotOrariRepository.slotOrarioById(prenotazioneRequest.idSlotPuntoCassa)
if(idSlotOrario == null){
call.respond(HttpStatusCode.BadRequest,"Slot orario non esistente")
return@post
}
val prenotazionePasto = PrenotazioniPasti(
-1,
prenotazioneRequest.idTessera,
prenotazioneRequest.idSlotPuntoCassa,
idSlotOrario.idResidenza,
prenotazioneRequest.idVassoio,
prenotazioneRequest.importoPagato,
prenotazioneRequest.codiceRistocloud
)
//Inserisci la prenotazione nel database
val prenotazioneInserita = prenotazioniPastiRepository.insert(prenotazionePasto)
//per ogni prodotto, inserisci il dettaglio della prenotazione
prenotazioneRequest.listaProdotti?.forEach { el ->
val dettaglioPrenotazione = PrenotazioniPastiDettaglio(
-1,
prenotazioneInserita.id,
el.id,
0L
)
listaDettagliInseriti.add(prenotazioniPastiDettaglioRepository.insert(dettaglioPrenotazione))
}
//restituisci la prenotazione
val prenotazione = Prenotazioni(
prenotazioneInserita.id,
prenotazioneRequest.codiceRistocloud,
prenotazioneInserita.idTessera,
prenotazioneInserita.idSlotPuntoCassa,
idSlotOrario.giorno,
idSlotOrario.turno,
idSlotOrario.dataInizio,
idSlotOrario.dataFine,
idSlotOrario.dataLimiteCancellazione,
prenotazioneRequest.idVassoio,
prenotazioneRequest.idStato,
prenotazioneRequest.stato,
prenotazioneRequest.listaProdotti,
prenotazioneRequest.importoPagato
)
call.respond(HttpStatusCode.Created, prenotazione)
}
catch (e: Exception){
call.respond(
HttpStatusCode.BadRequest,
"Errore nel processare la richiesta: ${e.cause}"
)
}
}
}
}
}

View File

@ -0,0 +1,55 @@
package eu.maiora.routes
import eu.maiora.model.ProdottiPrenotabiliRepositoryImpl
import eu.maiora.model.SlotOrariRepositoryImpl
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.prodottiPrenotabili(prodottiPrenotabiliRepository: ProdottiPrenotabiliRepositoryImpl){
route("/api/prodottiPrenotabili"){
authenticate("auth-jwt") {
get(){
// Ottieni l'id del turno, il giorno, l'id della modalita e l'id del punto di distribuzione dal percorso
val idTurno = call.parameters["idTurno"]
val giorno = call.parameters["giorno"]
val idPuntoDistribuzione = call.parameters["idPuntoDistribuzione"]
val idModalita = call.parameters["idModalita"]
if (idTurno.isNullOrEmpty()) {
call.respondText("ID turno non valido o non presente nei parametri", status = HttpStatusCode.BadRequest)
return@get
}
if (idPuntoDistribuzione.isNullOrEmpty()) {
call.respondText("ID punto distribuzione non valido o non presente nei parametri", status = HttpStatusCode.BadRequest)
return@get
}
if (idModalita.isNullOrEmpty()) {
call.respondText("ID modalita non valido o non presente nei parametri", status = HttpStatusCode.BadRequest)
return@get
}
if (giorno.isNullOrEmpty()) {
call.respondText("Giorno non valido o non presente nei parametri", status = HttpStatusCode.BadRequest)
return@get
}
// Cerca i prodotti prenotabili per giorno, turno, punto distribuzione e modalita
val listaProdottiPrenotabili = prodottiPrenotabiliRepository.prodottiPrenotabiliByGiornoIdTurnoIdPuntoDistIdMod(giorno,
idTurno.toLong(),
idPuntoDistribuzione.toLong(),
idModalita.toLong())
if (listaProdottiPrenotabili != null) {
call.respond(listaProdottiPrenotabili)
} else {
call.respondText("Prodotti prenotabili non trovati", status = HttpStatusCode.NotFound)
}
}
}
}
}

View File

@ -0,0 +1,41 @@
package eu.maiora.routes
import eu.maiora.model.PuntiDistribuzioneRepositoryImpl
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.puntiDistribuzione(puntiDistribuzioneRepository: PuntiDistribuzioneRepositoryImpl){
route("/api/puntiDistribuzione"){
authenticate("auth-jwt") {
get(){
// Ottieni l'id del turno e il giorno dal percorso
val idTurno = call.parameters["idTurno"]
val giorno = call.parameters["giorno"]
if (idTurno.isNullOrEmpty()) {
call.respondText("ID turno non valido o non presente nei parametri", status = HttpStatusCode.BadRequest)
return@get
}
if (giorno.isNullOrEmpty()) {
call.respondText("Giorno non valido o non presente nei parametri", status = HttpStatusCode.BadRequest)
return@get
}
// Cerca i punti distribuzione per giorno e turno
val listaPuntiDistribuzione = puntiDistribuzioneRepository.puntiDistByGiornoIdTurno(giorno, idTurno.toLong())
if (listaPuntiDistribuzione != null) {
call.respond(listaPuntiDistribuzione)
} else {
call.respondText("Punti distribuzione non trovati", status = HttpStatusCode.NotFound)
}
}
}
}
}

View File

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

View File

@ -0,0 +1,54 @@
package eu.maiora.routes
import eu.maiora.model.SlotOrariRepositoryImpl
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.slotOrari(slotOrariRepository: SlotOrariRepositoryImpl){
route("/api/slotOrari"){
authenticate("auth-jwt") {
get(){
// Ottieni l'id del turno, il giorno, l'id della modalita e l'id del punto di distribuzione dal percorso
val idTurno = call.parameters["idTurno"]
val giorno = call.parameters["giorno"]
val idPuntoDistribuzione = call.parameters["idPuntoDistribuzione"]
val idModalita = call.parameters["idModalita"]
if (idTurno.isNullOrEmpty()) {
call.respondText("ID turno non valido o non presente nei parametri", status = HttpStatusCode.BadRequest)
return@get
}
if (idPuntoDistribuzione.isNullOrEmpty()) {
call.respondText("ID punto distribuzione non valido o non presente nei parametri", status = HttpStatusCode.BadRequest)
return@get
}
if (idModalita.isNullOrEmpty()) {
call.respondText("ID modalita non valido o non presente nei parametri", status = HttpStatusCode.BadRequest)
return@get
}
if (giorno.isNullOrEmpty()) {
call.respondText("Giorno non valido o non presente nei parametri", status = HttpStatusCode.BadRequest)
return@get
}
// Cerca gli slot orari per giorno, turno, punto distribuzione e modalita
val listaSlotOrari = slotOrariRepository.slotOrariByGiornoIdTurnoIdPuntoDistIdMod(giorno,
idTurno.toLong(),
idPuntoDistribuzione.toLong(),
idModalita.toLong())
if (listaSlotOrari != null) {
call.respond(listaSlotOrari)
} else {
call.respondText("Slot orari non trovati", status = HttpStatusCode.NotFound)
}
}
}
}
}