aggiornamento saldo tessera e inserimento movimento di storno

separazione del mapping tra TESSERE e VIEW_TESSERE_API per il recupero dei dati della tessera da inserire nel movimento di storno
gestione delle eccezioni per ogni query di select, insert e update legate all'annullamento (eccezione generica per il blocco)
aggiunta campo VASSOIO nella VIEW_PRENOTAZIONI_PASTI
This commit is contained in:
Francesco Di Sciascio 2025-10-03 12:19:04 +02:00
parent 21983b35d8
commit ef2fcff779
14 changed files with 485 additions and 104 deletions

View File

@ -3,6 +3,8 @@ package eu.maiora.db
import eu.maiora.model.*
import kotlinx.coroutines.Dispatchers
import kotlinx.datetime.toKotlinLocalDate
import kotlinx.datetime.toKotlinLocalDateTime
import org.jetbrains.exposed.dao.*
import org.jetbrains.exposed.dao.id.EntityID
import org.jetbrains.exposed.dao.id.IdTable
@ -13,8 +15,7 @@ import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransacti
import java.time.format.DateTimeFormatter
object AccountsTable : IdTable<Int>("accounts"){
object AccountsTable : IdTable<Int>("accounts") {
override val id = integer("id").entityId()
val username = varchar("username", 255)
val password = varchar("password", 255)
@ -22,7 +23,7 @@ object AccountsTable : IdTable<Int>("accounts"){
override val primaryKey = PrimaryKey(id)
}
object ParametriTable : IdTable<Int>("parametri"){
object ParametriTable : IdTable<Int>("parametri") {
override val id = integer("id").entityId()
val chiave = varchar("chiave", 255)
val valore = varchar("valore", 255)
@ -30,7 +31,15 @@ object ParametriTable : IdTable<Int>("parametri"){
override val primaryKey = PrimaryKey(id)
}
object TessereTable : IdTable<Long>("view_tessere_api"){
object TessereTable : IdTable<Long>("tessere") {
override val id = long("id").entityId()
val saldo = double("saldo")
val tsUltimoUtilizzo = datetime("ts_ultimo_utilizzo")
override val primaryKey = PrimaryKey(id)
}
object ViewTessereAPITable : IdTable<Long>("view_tessere_api") {
override val id = long("id").entityId()
val idUtente = long("id_utente")
val codiceFiscale = varchar("codice_fiscale", 255)
@ -41,7 +50,7 @@ object TessereTable : IdTable<Long>("view_tessere_api"){
override val primaryKey = PrimaryKey(id)
}
object MovimentiTable : IdTable<Long>("view_movimenti_api"){
object MovimentiTable : IdTable<Long>("view_movimenti_api") {
override val id = long("id").entityId()
val idTessera = long("id_tessera")
val numero = varchar("numero_tessera", 255)
@ -49,7 +58,7 @@ object MovimentiTable : IdTable<Long>("view_movimenti_api"){
val dataMovimento = datetime("data_movimento")
val transazione = varchar("transazione", 255)
val dispositivo = varchar("dispositivo", 255)
val riferimento= varchar("riferimento", 255)
val riferimento = varchar("riferimento", 255)
val saldoPre = double("saldo_pre")
val importo = double("importo")
val saldoPost = double("saldo_post")
@ -59,7 +68,36 @@ object MovimentiTable : IdTable<Long>("view_movimenti_api"){
val dettagli = varchar("dettagli", 255)
}
object ComposizioniTable : IdTable<Long>("view_composizioni"){
object DwhMovimentiTable : IdTable<Long>("dwh.movimenti") {
override val id = long("id").autoIncrement("dwh.seq_movimenti").entityId()
val idTessera = long("id_tessera")
val numero = varchar("numero", 255)
val operazione = varchar("operazione", 255)
val data = datetime("DATA")
val transazione = long("transazione")
val dispositivo = varchar("dispositivo", 255)
val riferimento = varchar("riferimento", 255)
val saldoPre = double("saldo_pre")
val importo = double("importo")
val saldoPost = double("saldo_post")
val puntiPre = long("punti_pre")
val punti = long("punti")
val puntiPost = long("punti_post")
val flagPassaggioTessera = integer("flag_passaggio_tessera")
val oggetto = varchar("oggetto", 255)
val cognome = varchar("cognome", 255)
val nome = varchar("nome", 255)
val codiceFiscale = varchar("codice_fiscale", 255)
val azienda = varchar("azienda", 255)
val categoriaUtenti = varchar("categoria_utenti", 255)
val fascia = varchar("fascia", 255)
val idTipoMovimentoConto = integer("id_tipo_movimento_conto")
val giorno = date("giorno")
val modalita = varchar("modalita", 255)
val idModalita = long("id_modalita")
}
object ComposizioniTable : IdTable<Long>("view_composizioni") {
override val id = long("id").entityId()
val idVassoio = long("id_vassoio")
val vassoio = varchar("vassoio", 255)
@ -68,7 +106,7 @@ object ComposizioniTable : IdTable<Long>("view_composizioni"){
val quantita = integer("quantita")
}
object RicaricheTable : IdTable<Long>("ricariche_app"){
object RicaricheTable : IdTable<Long>("ricariche_app") {
override val id = long("id").autoIncrement("seq_ricariche_app").entityId()
val codiceTransazione = varchar("codice_transazione", 255)
val messaggio = varchar("messaggio", 255).nullable()
@ -76,7 +114,7 @@ object RicaricheTable : IdTable<Long>("ricariche_app"){
val importo = double("importo")
}
object SlotPrenotabiliTable : IdTable<Long>("view_slot_prenotabili"){
object SlotPrenotabiliTable : IdTable<Long>("view_slot_prenotabili") {
override val id = long("id").entityId()
val giorno = date("giorno")
val dataInizio = datetime("data_inizio")
@ -94,7 +132,7 @@ object SlotPrenotabiliTable : IdTable<Long>("view_slot_prenotabili"){
val residenza = varchar("residenza", 255).nullable()
}
object ProdottiPrenotabiliTable : IdTable<Long>("view_prodotti_prenotabili"){
object ProdottiPrenotabiliTable : IdTable<Long>("view_prodotti_prenotabili") {
override val id = long("id").entityId()
val giorno = date("giorno")
val idPuntoDistribuzione = long("id_punto_distribuzione")
@ -111,13 +149,13 @@ object ProdottiPrenotabiliTable : IdTable<Long>("view_prodotti_prenotabili"){
val modalitaPrenotazione = varchar("modalita_prenotazione", 255)
}
object ResidenzeTable : IdTable<Long>("residenze"){
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"){
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")
@ -127,7 +165,7 @@ object PrenotazioniPastiTable : IdTable<Long>("prenotazioni_pasti"){
val codiceRistocloud = varchar("codice_ristocloud", 255).nullable()
}
object PrenotazioniPastiDettaglioTable : IdTable<Long>("prenotazioni_pasti_dettaglio"){
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")
@ -135,7 +173,7 @@ object PrenotazioniPastiDettaglioTable : IdTable<Long>("prenotazioni_pasti_detta
}
object ViewPrenotazioniPastiTable : IdTable<Long>("view_prenotazioni_pasti"){
object ViewPrenotazioniPastiTable : IdTable<Long>("view_prenotazioni_pasti") {
override val id = long("id").entityId()
val idPrenotazione = long("id_prenotazione")
val idStato = long("id_stato")
@ -148,6 +186,7 @@ object ViewPrenotazioniPastiTable : IdTable<Long>("view_prenotazioni_pasti"){
val dataFine = datetime("data_fine")
val dataLimiteCancellazione = datetime("data_limite_cancellazione")
val idVassoio = long("id_vassoio").nullable()
val vassoio = varchar("vassoio", 255)
val codiceRistocloud = varchar("codice_ristocloud", 255).nullable()
val importoPagato = double("importo_pagato")
val puntoDistribuzione = varchar("punto_distribuzione", 255)
@ -158,31 +197,38 @@ object ViewPrenotazioniPastiTable : IdTable<Long>("view_prenotazioni_pasti"){
}
class AccountsDAO(id: EntityID<Int>) :IntEntity(id) {
class AccountsDAO(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<AccountsDAO>(AccountsTable)
var username by AccountsTable.username
var password by AccountsTable.password
}
class ParametriDAO(id: EntityID<Int>) :IntEntity(id) {
class ParametriDAO(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<ParametriDAO>(ParametriTable)
var chiave by ParametriTable.chiave
var valore by ParametriTable.valore
}
class TessereDao(id: EntityID<Long>) :LongEntity(id) {
class TessereDao(id: EntityID<Long>) : LongEntity(id) {
companion object : LongEntityClass<TessereDao>(TessereTable)
var idUtente by TessereTable.idUtente
var codiceFiscale by TessereTable.codiceFiscale
var numero by TessereTable.numero
var saldo by TessereTable.saldo
var punti by TessereTable.punti
var tsUltimoUtilizzo by TessereTable.tsUltimoUtilizzo
}
class MovimentiDao(id: EntityID<Long>) :LongEntity(id) {
class ViewTessereAPIDao(id: EntityID<Long>) : LongEntity(id) {
companion object : LongEntityClass<ViewTessereAPIDao>(ViewTessereAPITable)
var idUtente by ViewTessereAPITable.idUtente
var codiceFiscale by ViewTessereAPITable.codiceFiscale
var numero by ViewTessereAPITable.numero
var saldo by ViewTessereAPITable.saldo
var punti by ViewTessereAPITable.punti
}
class MovimentiDao(id: EntityID<Long>) : LongEntity(id) {
companion object : LongEntityClass<MovimentiDao>(MovimentiTable)
var idTessera by MovimentiTable.idTessera
@ -201,7 +247,37 @@ class MovimentiDao(id: EntityID<Long>) :LongEntity(id) {
var dettagli by MovimentiTable.dettagli
}
class ComposizioniDao(id: EntityID<Long>) :LongEntity(id){
class DwhMovimentiDao(id: EntityID<Long>) : LongEntity(id) {
companion object : LongEntityClass<DwhMovimentiDao>(DwhMovimentiTable)
var idTessera by DwhMovimentiTable.idTessera
var numero by DwhMovimentiTable.numero
var operazione by DwhMovimentiTable.operazione
var data by DwhMovimentiTable.data
var transazione by DwhMovimentiTable.transazione
var dispositivo by DwhMovimentiTable.dispositivo
var riferimento by DwhMovimentiTable.riferimento
var saldoPre by DwhMovimentiTable.saldoPre
var importo by DwhMovimentiTable.importo
var saldoPost by DwhMovimentiTable.saldoPost
var puntiPre by DwhMovimentiTable.puntiPre
var punti by DwhMovimentiTable.punti
var puntiPost by DwhMovimentiTable.puntiPost
var flagPassaggioTessera by DwhMovimentiTable.flagPassaggioTessera
var oggetto by DwhMovimentiTable.oggetto
var cognome by DwhMovimentiTable.cognome
var nome by DwhMovimentiTable.nome
var codiceFiscale by DwhMovimentiTable.codiceFiscale
var azienda by DwhMovimentiTable.azienda
var categoriaUtenti by DwhMovimentiTable.categoriaUtenti
var fascia by DwhMovimentiTable.fascia
var idTipoMovimentoConto by DwhMovimentiTable.idTipoMovimentoConto
var giorno by DwhMovimentiTable.giorno
var modalita by DwhMovimentiTable.modalita
var idModalita by DwhMovimentiTable.idModalita
}
class ComposizioniDao(id: EntityID<Long>) : LongEntity(id) {
companion object : LongEntityClass<ComposizioniDao>(ComposizioniTable)
var idVassoio by ComposizioniTable.idVassoio
@ -211,7 +287,7 @@ class ComposizioniDao(id: EntityID<Long>) :LongEntity(id){
var quantita by ComposizioniTable.quantita
}
class RicaricheDao(id: EntityID<Long>) :LongEntity(id){
class RicaricheDao(id: EntityID<Long>) : LongEntity(id) {
companion object : LongEntityClass<RicaricheDao>(RicaricheTable)
var codiceTransazione by RicaricheTable.codiceTransazione
@ -220,7 +296,7 @@ class RicaricheDao(id: EntityID<Long>) :LongEntity(id){
var importo by RicaricheTable.importo
}
class SlotPrenotabiliDao(id: EntityID<Long>) :LongEntity(id) {
class SlotPrenotabiliDao(id: EntityID<Long>) : LongEntity(id) {
companion object : LongEntityClass<SlotPrenotabiliDao>(SlotPrenotabiliTable)
var giorno by SlotPrenotabiliTable.giorno
@ -239,7 +315,7 @@ class SlotPrenotabiliDao(id: EntityID<Long>) :LongEntity(id) {
var residenza by SlotPrenotabiliTable.residenza
}
class ProdottiPrenotabiliDao(id: EntityID<Long>) :LongEntity(id) {
class ProdottiPrenotabiliDao(id: EntityID<Long>) : LongEntity(id) {
companion object : LongEntityClass<ProdottiPrenotabiliDao>(ProdottiPrenotabiliTable)
var giorno by ProdottiPrenotabiliTable.giorno
@ -257,14 +333,14 @@ class ProdottiPrenotabiliDao(id: EntityID<Long>) :LongEntity(id) {
var modalitaPrenotazione by ProdottiPrenotabiliTable.modalitaPrenotazione
}
class ResidenzeDao(id: EntityID<Long>) :LongEntity(id){
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){
class PrenotazioniPastiDao(id: EntityID<Long>) : LongEntity(id) {
companion object : LongEntityClass<PrenotazioniPastiDao>(PrenotazioniPastiTable)
val idTessera by PrenotazioniPastiTable.idTessera
@ -275,7 +351,7 @@ class PrenotazioniPastiDao(id: EntityID<Long>) :LongEntity(id){
val codiceRistocloud by PrenotazioniPastiTable.codiceRistocloud
}
class PrenotazioniPastiDettaglioDao(id: EntityID<Long>) :LongEntity(id){
class PrenotazioniPastiDettaglioDao(id: EntityID<Long>) : LongEntity(id) {
companion object : LongEntityClass<PrenotazioniPastiDettaglioDao>(PrenotazioniPastiDettaglioTable)
val idPrenotazione by PrenotazioniPastiDettaglioTable.idPrenotazione
@ -283,7 +359,7 @@ class PrenotazioniPastiDettaglioDao(id: EntityID<Long>) :LongEntity(id){
val idStato by PrenotazioniPastiDettaglioTable.idStato
}
class ViewPrenotazioniPastiDao(id: EntityID<Long>) :LongEntity(id){
class ViewPrenotazioniPastiDao(id: EntityID<Long>) : LongEntity(id) {
companion object : LongEntityClass<ViewPrenotazioniPastiDao>(ViewPrenotazioniPastiTable)
val idPrenotazione by ViewPrenotazioniPastiTable.idPrenotazione
@ -297,6 +373,7 @@ class ViewPrenotazioniPastiDao(id: EntityID<Long>) :LongEntity(id){
val dataFine by ViewPrenotazioniPastiTable.dataFine
val dataLimiteCancellazione by ViewPrenotazioniPastiTable.dataLimiteCancellazione
val idVassoio by ViewPrenotazioniPastiTable.idVassoio
val vassoio by ViewPrenotazioniPastiTable.vassoio
val codiceRistocloud by ViewPrenotazioniPastiTable.codiceRistocloud
val importoPagato by ViewPrenotazioniPastiTable.importoPagato
val puntoDistribuzione by ViewPrenotazioniPastiTable.puntoDistribuzione
@ -321,14 +398,25 @@ fun parametriDaoToModel(dao: ParametriDAO) = Parametri(
fun tessereDaoToModel(dao: TessereDao) = Tessere(
dao.id.value,
dao.idUtente,
dao.codiceFiscale,
dao.numero,
dao.saldo,
dao.punti
dao.tsUltimoUtilizzo.toKotlinLocalDateTime()
)
fun movimentiDaoToModel(dao: MovimentiDao) :Movimenti{
fun viewTessereAPIDaoToModel(dao: ViewTessereAPIDao): ViewTessereAPI {
return ViewTessereAPI(
dao.id.value,
dao.idUtente,
dao.codiceFiscale,
dao.numero,
dao.saldo,
dao.punti
)
}
fun movimentiDaoToModel(dao: MovimentiDao): Movimenti {
val formatter = DateTimeFormatter.ofPattern("ddMMyyyy HH:mm")
val formattedDate = dao.dataMovimento.format(formatter)
@ -351,6 +439,36 @@ fun movimentiDaoToModel(dao: MovimentiDao) :Movimenti{
)
}
fun dwhMovimentiDaoToModel(dao: DwhMovimentiDao) = DwhMovimenti(
dao.id.value,
dao.idTessera,
dao.numero,
dao.operazione,
dao.data.toKotlinLocalDateTime(),
dao.transazione,
dao.dispositivo,
dao.riferimento,
dao.saldoPre,
dao.importo,
dao.saldoPost,
dao.puntiPre,
dao.punti,
dao.puntiPost,
dao.flagPassaggioTessera,
dao.oggetto,
dao.cognome,
dao.nome,
dao.codiceFiscale,
dao.azienda,
dao.categoriaUtenti,
dao.fascia,
dao.idTipoMovimentoConto,
dao.giorno.toKotlinLocalDate(),
dao.modalita,
dao.idModalita
)
fun composizioniDaoToModel(dao: ComposizioniDao) = Composizioni(
dao.id.value,
dao.idVassoio,
@ -360,7 +478,7 @@ fun composizioniDaoToModel(dao: ComposizioniDao) = Composizioni(
dao.quantita
)
fun puntiDistribuzioneDaoToModel(dao: SlotPrenotabiliDao) :PuntiDistribuzione{
fun puntiDistribuzioneDaoToModel(dao: SlotPrenotabiliDao): PuntiDistribuzione {
return PuntiDistribuzione(
dao.id.value,
dao.idPuntoDistribuzione,
@ -372,7 +490,7 @@ fun puntiDistribuzioneDaoToModel(dao: SlotPrenotabiliDao) :PuntiDistribuzione{
)
}
fun slotOrariDaoToModel(dao: SlotPrenotabiliDao) :SlotOrari{
fun slotOrariDaoToModel(dao: SlotPrenotabiliDao): SlotOrari {
val formatterGiorno = DateTimeFormatter.ofPattern("ddMMyyyy")
val formatterConOra = DateTimeFormatter.ofPattern("ddMMyyyy HH:mm")
val formattedGiorno = dao.giorno.format(formatterGiorno)
@ -399,7 +517,7 @@ fun slotOrariDaoToModel(dao: SlotPrenotabiliDao) :SlotOrari{
)
}
fun prodottiPrenotabiliDaoToModel(dao: ProdottiPrenotabiliDao) :ProdottiPrenotabili{
fun prodottiPrenotabiliDaoToModel(dao: ProdottiPrenotabiliDao): ProdottiPrenotabili {
val formatterGiorno = DateTimeFormatter.ofPattern("ddMMyyyy")
val formattedGiorno = dao.giorno.format(formatterGiorno)
@ -421,7 +539,7 @@ fun prodottiPrenotabiliDaoToModel(dao: ProdottiPrenotabiliDao) :ProdottiPrenotab
)
}
fun residenzeDaoToModel(dao: ResidenzeDao) :Residenze{
fun residenzeDaoToModel(dao: ResidenzeDao): Residenze {
return Residenze(
dao.id.value,
dao.idPuntoDistribuzione,
@ -429,7 +547,7 @@ fun residenzeDaoToModel(dao: ResidenzeDao) :Residenze{
)
}
fun prenotazioniPastiDaoToModel(dao: PrenotazioniPastiDao) : PrenotazioniPasti{
fun prenotazioniPastiDaoToModel(dao: PrenotazioniPastiDao): PrenotazioniPasti {
return PrenotazioniPasti(
dao.id.value,
dao.idTessera,
@ -441,7 +559,7 @@ fun prenotazioniPastiDaoToModel(dao: PrenotazioniPastiDao) : PrenotazioniPasti{
)
}
fun prenotazioniPastiDettaglioDaoToModel(dao: PrenotazioniPastiDettaglioDao) : PrenotazioniPastiDettaglio{
fun prenotazioniPastiDettaglioDaoToModel(dao: PrenotazioniPastiDettaglioDao): PrenotazioniPastiDettaglio {
return PrenotazioniPastiDettaglio(
dao.id.value,
dao.idPrenotazione,
@ -450,39 +568,11 @@ fun prenotazioniPastiDettaglioDaoToModel(dao: PrenotazioniPastiDettaglioDao) : P
)
}
/*fun viewPrenotazioniPastiDaoToModel(dao: ViewPrenotazioniPastiDao) : ViewPrenotazioniPasti{
val formatterGiorno = DateTimeFormatter.ofPattern("ddMMyyyy")
val formatterDataInizio = DateTimeFormatter.ofPattern("ddMMyyyy HH:mm")
val formatterDataFine = DateTimeFormatter.ofPattern("ddMMyyyy HH:mm")
val formatterDataLimiteCancellazione = DateTimeFormatter.ofPattern("ddMMyyyy HH:mm")
val formattedGiorno = dao.giorno.format(formatterGiorno)
val formattedDataInizio = dao.dataInizio.format(formatterDataInizio)
val formattedDataFine = dao.dataFine.format(formatterDataFine)
val formattedDataLimiteCanc = dao.dataLimiteCancellazione.format(formatterDataLimiteCancellazione)
return ViewPrenotazioniPasti(
dao.idPrenotazione,
dao.idStato,
dao.stato,
dao.idTessera,
dao.idSlotPuntoCassa,
formattedGiorno,
dao.turno,
formattedDataInizio,
formattedDataFine,
formattedDataLimiteCanc,
dao.idVassoio,
dao.codiceRistocloud,
dao.importoPagato,
dao.puntoDistribuzione,
dao.puntoCassa,
dao.modalita,
null
)
}*/
fun viewPrenotazioniPastiDaoToModel(dao: ViewPrenotazioniPastiDao, listaProdotti: List<ListaProdottiElement>? = null) : ViewPrenotazioniPasti{
fun viewPrenotazioniPastiDaoToModel(
dao: ViewPrenotazioniPastiDao,
listaProdotti: List<ListaProdottiElement>? = null
): ViewPrenotazioniPasti {
val formatterGiorno = DateTimeFormatter.ofPattern("ddMMyyyy")
val formatterDataInizio = DateTimeFormatter.ofPattern("ddMMyyyy HH:mm")
val formatterDataFine = DateTimeFormatter.ofPattern("ddMMyyyy HH:mm")
@ -505,6 +595,7 @@ fun viewPrenotazioniPastiDaoToModel(dao: ViewPrenotazioniPastiDao, listaProdotti
formattedDataFine,
formattedDataLimiteCanc,
dao.idVassoio,
dao.vassoio,
dao.codiceRistocloud,
dao.importoPagato,
dao.puntoDistribuzione,

View File

@ -0,0 +1,38 @@
package eu.maiora.model
import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime
import kotlinx.serialization.Serializable
@Serializable
data class DwhMovimenti(
val id: Long,
val idTessera: Long,
val numero: String,
val operazione: String,
val data: LocalDateTime,
val transazione: Long,
val dispositivo: String,
val riferimento: String,
val saldoPre: Double,
val importo: Double,
val saldoPost: Double,
val puntiPre: Long,
val punti: Long,
val puntiPost: Long,
val flagPassaggioTessera: Int,
val oggetto: String,
val cognome: String,
val nome: String,
val codiceFiscale: String,
val azienda: String,
val categoriaUtenti: String,
val fascia: String,
val idTipoMovimentoConto: Int,
val giorno: LocalDate,
val modalita: String,
val idModalita: Long
)

View File

@ -0,0 +1,5 @@
package eu.maiora.model
interface DwhMovimentiRepository {
suspend fun insert(movimento : DwhMovimenti): DwhMovimenti
}

View File

@ -0,0 +1,71 @@
package eu.maiora.model
import eu.maiora.db.*
import kotlinx.datetime.toJavaLocalDate
import kotlinx.datetime.toJavaLocalDateTime
import org.jetbrains.exposed.sql.insertAndGetId
class DwhMovimentiRepositoryImpl : DwhMovimentiRepository {
override suspend fun insert(movimento : DwhMovimenti): DwhMovimenti = suspendTransaction {
// Inserisci un nuovo movimento
// ID non definito: viene gestito dalla sequence
val idMovimentoInserted = DwhMovimentiTable.insertAndGetId {
it[idTessera] = movimento.idTessera
it[numero] = movimento.numero
it[operazione] = movimento.operazione
it[data] = movimento.data.toJavaLocalDateTime()
it[transazione] = movimento.transazione
it[dispositivo] = movimento.dispositivo
it[riferimento] = movimento.riferimento
it[saldoPre] = movimento.saldoPre
it[importo] = movimento.importo
it[saldoPost] = movimento.saldoPost
it[puntiPre] = movimento.puntiPre
it[punti] = movimento.punti
it[puntiPost] = movimento.puntiPost
it[flagPassaggioTessera] = movimento.flagPassaggioTessera
it[oggetto] = movimento.oggetto
it[cognome] = movimento.cognome
it[nome] = movimento.nome
it[codiceFiscale] = movimento.codiceFiscale
it[azienda] = movimento.azienda
it[categoriaUtenti] = movimento.categoriaUtenti
it[fascia] = movimento.fascia
it[idTipoMovimentoConto] = movimento.idTipoMovimentoConto
it[giorno] = movimento.giorno.toJavaLocalDate()
it[modalita] = movimento.modalita
it[idModalita] = movimento.idModalita
}.value
DwhMovimenti(
idMovimentoInserted,
movimento.idTessera,
movimento.numero,
movimento.operazione,
movimento.data,
movimento.transazione,
movimento.dispositivo,
movimento.riferimento,
movimento.saldoPre,
movimento.importo,
movimento.saldoPost,
movimento.puntiPre,
movimento.punti,
movimento.puntiPost,
movimento.flagPassaggioTessera,
movimento.oggetto,
movimento.cognome,
movimento.nome,
movimento.codiceFiscale,
movimento.azienda,
movimento.categoriaUtenti,
movimento.fascia,
movimento.idTipoMovimentoConto,
movimento.giorno,
movimento.modalita,
movimento.idModalita
)
}
}

View File

@ -1,13 +1,11 @@
package eu.maiora.model
import kotlinx.datetime.LocalDateTime
import kotlinx.serialization.Serializable
@Serializable
data class Tessere(
val id: Long,
val idUtente : Long,
val codiceFiscale : String,
val numero : String,
val saldo : Double,
val punti : Int
val tsUltimoUtilizzo : LocalDateTime
)

View File

@ -1,5 +1,5 @@
package eu.maiora.model
interface TessereRepository {
suspend fun tesseraByCodiceFiscale(cf : String): Tessere?
suspend fun update(tessera: Tessere): Tessere
}

View File

@ -1,13 +1,17 @@
package eu.maiora.model
import eu.maiora.db.*
import kotlinx.datetime.toJavaLocalDateTime
import org.jetbrains.exposed.sql.update
class TessereRepositoryImpl : TessereRepository {
override suspend fun tesseraByCodiceFiscale(cf: String): Tessere? = suspendTransaction {
// Cerca tessere in base al codice fiscale
TessereDao.find { TessereTable.codiceFiscale eq cf }
.singleOrNull() // Restituisce un singolo risultato o null se non trovato
?.let { tessereDaoToModel(it) } // Converte il DAO in un oggetto Tessere
override suspend fun update (tessera : Tessere): Tessere = suspendTransaction {
TessereTable.update({TessereTable.id eq tessera.id}){
it[saldo] = tessera.saldo
it[tsUltimoUtilizzo] = tessera.tsUltimoUtilizzo.toJavaLocalDateTime()
}
tessera
}
}

View File

@ -1,6 +1,7 @@
package eu.maiora.model
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
@Serializable
data class ViewPrenotazioniPasti(
@ -15,6 +16,8 @@ data class ViewPrenotazioniPasti(
val dataFine: String,
val dataLimiteCancellazione: String,
val idVassoio: Long? = null,
@Transient
val vassoio: String = "",
val codiceRistocloud: String? = null,
val importoPagato: Double,
val puntoDistribuzione: String,

View File

@ -0,0 +1,14 @@
package eu.maiora.model
import kotlinx.serialization.Serializable
import javax.management.monitor.StringMonitor
@Serializable
data class ViewTessereAPI(
val id: Long,
val idUtente : Long,
val codiceFiscale : String,
val numero : String,
val saldo : Double,
val punti : Int
)

View File

@ -0,0 +1,6 @@
package eu.maiora.model
interface ViewTessereAPIRepository {
suspend fun tesseraByCodiceFiscale(cf : String): ViewTessereAPI?
suspend fun tesseraById(id : Long): ViewTessereAPI?
}

View File

@ -0,0 +1,23 @@
package eu.maiora.model
import eu.maiora.db.*
import org.jetbrains.exposed.sql.update
import java.time.LocalDateTime
class ViewTessereAPIRepositoryImpl : ViewTessereAPIRepository {
override suspend fun tesseraByCodiceFiscale(cf: String): ViewTessereAPI? = suspendTransaction {
// Cerca tessere in base al codice fiscale
ViewTessereAPIDao.find { ViewTessereAPITable.codiceFiscale eq cf }
.singleOrNull() // Restituisce un singolo risultato o null se non trovato
?.let { viewTessereAPIDaoToModel(it) } // Converte il DAO in un oggetto ViewTessereAPI
}
override suspend fun tesseraById(id: Long): ViewTessereAPI? = suspendTransaction{
//Cerca tessera in base all'id
ViewTessereAPIDao.find{ViewTessereAPITable.id eq id}
.singleOrNull()
?.let{viewTessereAPIDaoToModel(it)}
}
}

View File

@ -13,7 +13,7 @@ fun Application.configureRouting() {
}
auth(AccountsRepositoryImpl())
tessere(TessereRepositoryImpl())
tessere(ViewTessereAPIRepositoryImpl())
movimenti(MovimentiRepositoryImpl())
composizioni(ComposizioniRepositoryImpl())
valorePasti(ValorePastiRepositoryImpl())
@ -26,7 +26,11 @@ fun Application.configureRouting() {
SlotOrariRepositoryImpl(),
PrenotazioniPastiDettaglioRepositoryImpl(),
ViewPrenotazioniPastiRepositoryImpl())
annullaPrenotazioni(ViewPrenotazioniPastiRepositoryImpl(), PrenotazioniPastiDettaglioRepositoryImpl())
annullaPrenotazioni(ViewPrenotazioniPastiRepositoryImpl(),
PrenotazioniPastiDettaglioRepositoryImpl(),
TessereRepositoryImpl(),
ViewTessereAPIRepositoryImpl(),
DwhMovimentiRepositoryImpl())
verificaVassoio(SelezionaComposizioneRepositoryImpl())
}
}

View File

@ -6,14 +6,22 @@ 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 kotlinx.datetime.toKotlinLocalDate
import kotlinx.datetime.toKotlinLocalDateTime
import kotlinx.serialization.Serializable
import org.jetbrains.exposed.sql.transactions.TransactionManager
import org.jetbrains.exposed.sql.transactions.transaction
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
fun Route.annullaPrenotazioni(
viewPrenotazioniPastiRepository: ViewPrenotazioniPastiRepositoryImpl,
prenotazioniPastiDettaglioRepository: PrenotazioniPastiDettaglioRepositoryImpl
prenotazioniPastiDettaglioRepository: PrenotazioniPastiDettaglioRepositoryImpl,
tessereRepository: TessereRepositoryImpl,
viewTessereAPIRepository: ViewTessereAPIRepositoryImpl,
dwhMovimentiRepository: DwhMovimentiRepositoryImpl
) {
route("/api/annullaPrenotazioni") {
authenticate("auth-jwt") {
@ -26,7 +34,7 @@ fun Route.annullaPrenotazioni(
return@patch
}
try{
try {
val prenotazione = viewPrenotazioniPastiRepository.prenotazioniPastiById(idPrenotazione.toLong())
val statoPrenotazione = prenotazione.stato
@ -54,27 +62,143 @@ fun Route.annullaPrenotazioni(
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
val tessera = viewTessereAPIRepository.tesseraById(prenotazione.idTessera)
if (tessera == null) {
call.respond(
HttpStatusCode.BadRequest,
"Prenotazione non annullata: tessera collegata alla prenotazione non trovata"
)
prenotazioniPastiDettaglioRepository.update(prodottoDaAggiornare)
return@patch
}
//recupero i dati di tessera e utente
val datiUtenteTessera = transaction {
val query = """
SELECT u.cognome, u.nome, a.nome as azienda, cu.nome as categoria_utenti, f.nome as fascia
FROM tessere t
LEFT JOIN utenti u ON t.id_utente = u.id
LEFT JOIN categorie_utenti cu ON u.id_categoria = cu.id
LEFT JOIN aziende a ON cu.id_azienda = a.id
LEFT JOIN categorie_utenti_fasce cuf ON cuf.id_categoria_utenti = cu.id
LEFT JOIN fasce f ON cuf.id_fascia = f.id
WHERE t.id = ?
""".trimIndent()
val connection = TransactionManager.current().connection
val preparedStatement = connection.prepareStatement(query, true)
preparedStatement[1] = tessera.id
val rs = preparedStatement.executeQuery()
if (rs.next()) {
DatiUtenteTessera(
cognome = rs.getString("cognome"),
nome = rs.getString("nome"),
azienda = rs.getString("azienda"),
categoriaUtenti = rs.getString("categoria_utenti"),
fascia = rs.getString("fascia")
)
} else null
}
if (datiUtenteTessera == null) {
call.respond(
HttpStatusCode.BadRequest,
"Prenotazione non annullata: dati utente tessera non trovati"
)
return@patch
}
//aggiorna lo stato di ogni prodotto per annullare la prenotazione
try {
listaProdottiPrenotati.forEach { el ->
val prodottoDaAggiornare = PrenotazioniPastiDettaglio(
el.id,
el.idPrenotazione,
el.idProdotto,
3L //ANNULLATA
)
prenotazioniPastiDettaglioRepository.update(prodottoDaAggiornare)
}
} catch (e: Exception) {
println("Annulamento prenotazione non completato. Errore durante l'update dei dettagli: ${e.message}")
call.respond(HttpStatusCode.InternalServerError, "Errore durante l'update dei dettagli: ${e.message}")
}
//effettuare l'aggiornamento del saldo della tessera
val nuovoSaldo = tessera.saldo.plus(prenotazione.importoPagato)
try {
tessereRepository.update(
Tessere(
tessera.id,
nuovoSaldo,
LocalDateTime.now().toKotlinLocalDateTime()
)
)
} catch (e: Exception) {
println("Annulamento prenotazione non completato. Errore durante l'update della tessera: ${e.message}")
call.respond(HttpStatusCode.InternalServerError, "Errore durante l'update della tessera: ${e.message}")
}
//effettuare l'inserimento del movimento di storno
try {
dwhMovimentiRepository.insert(
DwhMovimenti(
-1L,
tessera.id,
tessera.numero,
"Storno prenotazione pre pagata",
LocalDateTime.now().toKotlinLocalDateTime(),
prenotazione.id,
"App",
"0",
tessera.saldo,
prenotazione.importoPagato,
tessera.saldo + prenotazione.importoPagato,
tessera.punti.toLong(),
0,
tessera.punti.toLong() + 0,
0,
prenotazione.vassoio,
datiUtenteTessera.cognome,
datiUtenteTessera.nome,
tessera.codiceFiscale,
datiUtenteTessera.azienda,
datiUtenteTessera.categoriaUtenti,
datiUtenteTessera.fascia,
3, //Storno
LocalDate.now().toKotlinLocalDate(),
"Standard",
1
)
)
} catch (e: Exception) {
println("Annulamento prenotazione non completato. Errore durante l'insert del movimento: ${e.message}")
call.respond(HttpStatusCode.InternalServerError, "Errore durante l'insert del movimento: ${e.message}")
}
call.respond(HttpStatusCode.OK, "Prenotazione $idPrenotazione annullata")
}
catch (e: IllegalArgumentException) {
} catch (e: IllegalArgumentException) {
call.respond(HttpStatusCode.NotFound, "Prenotazione non trovata: ${e.message}")
} catch(e: Exception){
println("Annulamento prenotazione non completato. Errore generico: ${e.message}")
call.respond(HttpStatusCode.InternalServerError, "Errore generico: ${e.message}")
}
}
}
}
}
}
@Serializable
data class DatiUtenteTessera(
val cognome: String,
val nome: String,
val azienda: String,
val categoriaUtenti: String,
val fascia: String
)

View File

@ -1,6 +1,6 @@
package eu.maiora.routes
import eu.maiora.model.TessereRepositoryImpl
import eu.maiora.model.ViewTessereAPIRepositoryImpl
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.auth.*
@ -8,7 +8,7 @@ import io.ktor.server.response.*
import io.ktor.server.routing.*
fun Route.tessere(tessereRepository: TessereRepositoryImpl){
fun Route.tessere(tessereRepository: ViewTessereAPIRepositoryImpl){
route("/api/tessere"){
authenticate("auth-jwt") {
get("{cf}"){