2
0
forked from maiora/backend-api

Compare commits

..

No commits in common. "main" and "main" have entirely different histories.
main ... main

21 changed files with 6 additions and 524 deletions

View File

@ -1,5 +1,5 @@
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0"
}
rootProject.name = "Backend_API_FAER"
rootProject.name = "Backend_API"

View File

@ -1,17 +1,13 @@
package eu.maiora.db
import com.fasterxml.jackson.databind.deser.impl.CreatorCandidate.Param
import eu.maiora.db.AccountsTable.entityId
import eu.maiora.db.ViewEcommercePrezSconDispTable.double
import eu.maiora.db.ViewEcommercePrezSconDispTable.integer
import eu.maiora.db.ViewEcommercePrezSconDispTable.long
import eu.maiora.db.ViewEcommercePrezSconDispTable.varchar
import eu.maiora.model.*
import eu.maiora.model.Accounts
import eu.maiora.model.Parametri
import kotlinx.coroutines.Dispatchers
import org.jetbrains.exposed.dao.*
import org.jetbrains.exposed.dao.IntEntity
import org.jetbrains.exposed.dao.IntEntityClass
import org.jetbrains.exposed.dao.id.EntityID
import org.jetbrains.exposed.dao.id.IdTable
import org.jetbrains.exposed.sql.Table
import org.jetbrains.exposed.sql.Transaction
import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
@ -23,43 +19,6 @@ object AccountsTable : IdTable<Int>("accounts"){
override val primaryKey = PrimaryKey(id)
}
object ArticoliCrossQRicambiTable : IdTable<Int>("articoli_cross_qricambi"){
override val id = ArticoliCrossQRicambiTable.integer("id").entityId()
val codiceArticolo = varchar("codice_articolo", 50)
val codiceCross = varchar("codice_cross", 50)
val tipo = varchar("tipo", 2)
val costruttore = varchar("costruttore", 50)
}
object ViewEcommerceArticoliTable : IdTable<Long>("view_ecommerce_articoli"){
override val id = ViewEcommerceArticoliTable.long("id").entityId()
val codice = varchar("codice", 20)
val descrizione = varchar("descrizione", 255)
}
object ViewClientiAgentiTable : IdTable<Long>("view_clienti_agenti"){
override val id = ViewClientiAgentiTable.long("id_cliente").entityId()
val cliente = varchar("cliente", 255)
val idAgente = long("id_agente")
val username = varchar("username", 255)
}
object ViewEcommercePrezSconDispTable : IdTable<Long>("view_ecommerce_prez_scon_disp"){
override val id = ViewEcommercePrezSconDispTable.long("id").entityId()
val idCliente = long("id_cliente")
val idArticolo = long("id_articolo")
val idMagazzino = long("id_magazzino")
val magazzino = varchar("magazzino", 255)
val valoreCarcassa = double("valore_carcassa")
val prezzo = double("prezzo")
val sconto = double("sconto")
val sconto1 = double("sconto_1")
val sconto2 = double("sconto_2")
val sconto3 = double("sconto_3")
val netto = double("netto")
val numeroPezzi = integer("numero_pezzi")
}
object ParametriTable : IdTable<Int>("parametri"){
override val id = integer("id").entityId()
val chiave = varchar("chiave", 255)
@ -75,47 +34,6 @@ class AccountsDAO(id: EntityID<Int>) :IntEntity(id) {
var password by AccountsTable.password
}
class ArticoliCrossQRicambiDAO(id: EntityID<Int>) :IntEntity(id) {
companion object : IntEntityClass<ArticoliCrossQRicambiDAO>(ArticoliCrossQRicambiTable)
var codiceArticolo by ArticoliCrossQRicambiTable.codiceArticolo
var codiceCross by ArticoliCrossQRicambiTable.codiceCross
var tipo by ArticoliCrossQRicambiTable.tipo
var costruttore by ArticoliCrossQRicambiTable.costruttore
}
class ViewEcommerceArticoliDAO(id: EntityID<Long>) :LongEntity(id) {
companion object : LongEntityClass<ViewEcommerceArticoliDAO>(ViewEcommerceArticoliTable)
var codice by ViewEcommerceArticoliTable.codice
var descrizione by ViewEcommerceArticoliTable.descrizione
}
class ViewClientiAgentiDAO(id: EntityID<Long>) :LongEntity(id) {
companion object : LongEntityClass<ViewClientiAgentiDAO>(ViewClientiAgentiTable)
var cliente by ViewClientiAgentiTable.cliente
var idAgente by ViewClientiAgentiTable.idAgente
var username by ViewClientiAgentiTable.username
}
class ViewEcommercePrezSconDispDAO(id: EntityID<Long>) :LongEntity(id) {
companion object : LongEntityClass<ViewEcommercePrezSconDispDAO>(ViewEcommercePrezSconDispTable)
val idCliente by ViewEcommercePrezSconDispTable.idCliente
val idArticolo by ViewEcommercePrezSconDispTable.idArticolo
val idMagazzino by ViewEcommercePrezSconDispTable.idMagazzino
val magazzino by ViewEcommercePrezSconDispTable.magazzino
val valoreCarcassa by ViewEcommercePrezSconDispTable.valoreCarcassa
val prezzo by ViewEcommercePrezSconDispTable.prezzo
val sconto by ViewEcommercePrezSconDispTable.sconto
val sconto1 by ViewEcommercePrezSconDispTable.sconto1
val sconto2 by ViewEcommercePrezSconDispTable.sconto2
val sconto3 by ViewEcommercePrezSconDispTable.sconto3
val netto by ViewEcommercePrezSconDispTable.netto
val numeroPezzi by ViewEcommercePrezSconDispTable.numeroPezzi
}
class ParametriDAO(id: EntityID<Int>) :IntEntity(id) {
companion object : IntEntityClass<ParametriDAO>(ParametriTable)
@ -130,43 +48,6 @@ fun accountsDaoToModel(dao: AccountsDAO) = Accounts(
dao.password
)
fun articoliCrossQRicambiDaoToModel(dao: ArticoliCrossQRicambiDAO) = ArticoliCrossQRicambi(
dao.id.value,
dao.codiceArticolo,
dao.codiceCross,
dao.tipo,
dao.costruttore
)
fun viewEcommerceArticoliDaoToModel(dao: ViewEcommerceArticoliDAO) = ViewEcommerceArticoli(
dao.id.value,
dao.codice,
dao.descrizione
)
fun viewClientiAgentiDaoToModel(dao: ViewClientiAgentiDAO) = ViewClientiAgenti(
dao.id.value,
dao.cliente,
dao.idAgente,
dao.username
)
fun viewEcommercePrezSconDispDaoToModel(dao: ViewEcommercePrezSconDispDAO) = ViewEcommercePrezSconDisp(
dao.id.value,
dao.idCliente,
dao.idArticolo,
dao.idMagazzino,
dao.magazzino,
dao.valoreCarcassa,
dao.prezzo,
dao.sconto,
dao.sconto1,
dao.sconto2,
dao.sconto3,
dao.netto,
dao.numeroPezzi
)
fun parametriDaoToModel(dao: ParametriDAO) = Parametri(
dao.id.value,
dao.chiave,

View File

@ -1,13 +0,0 @@
package eu.maiora.model
import kotlinx.serialization.Serializable
@Serializable
data class ArticoliCrossQRicambi(
val id : Int,
val codiceArticolo : String,
val codiceCross : String,
val costruttore : String,
val tipo : String
)

View File

@ -1,6 +0,0 @@
package eu.maiora.model
interface ArticoliCrossQRicambiRepository {
suspend fun articoloByCodArt(codice : String): List<ArticoliCrossQRicambi>
//suspend fun articoloByCodCross(codice : String): ArticoliCrossQRicambi?
}

View File

@ -1,21 +0,0 @@
package eu.maiora.model
import eu.maiora.db.*
import org.jetbrains.exposed.sql.or
class ArticoliCrossQRicambiRepositoryImpl : ArticoliCrossQRicambiRepository {
override suspend fun articoloByCodArt(codice: String): List<ArticoliCrossQRicambi> = suspendTransaction {
// Cerca un articolo dalla tabella ArticoliCrossQRicambiTable
ArticoliCrossQRicambiDAO.find { (ArticoliCrossQRicambiTable.codiceArticolo eq codice) or (ArticoliCrossQRicambiTable.codiceCross eq codice) }
.toList() // Restituisce un singolo risultato o null se non trovato
.map { articoliCrossQRicambiDaoToModel(it) } // Converte il DAO in un oggetto ArticoliCrossQRicambi
}
/*override suspend fun articoloByCodCross(codice: String): ArticoliCrossQRicambi? = suspendTransaction {
// Cerca un articolo dalla tabella ArticoliCrossQRicambiTable
ArticoliCrossQRicambiDAO.find { ArticoliCrossQRicambiTable.codiceCross eq codice }
.singleOrNull() // Restituisce un singolo risultato o null se non trovato
?.let { articoliCrossQRicambiDaoToModel(it) } // Converte il DAO in un oggetto ArticoliCrossQRicambi
}*/
}

View File

@ -1,15 +0,0 @@
package eu.maiora.model
import kotlinx.serialization.Serializable
@Serializable
data class DisponibilitaArticoli(
val codiceArticolo : String,
val descrizione : String,
val costruttore : String,
val prezzoNetto : String,
val isDisponibile: Boolean,
val disponibilita : List<NumPezziPerMagazzino>,
val costoCarcassa: String
)

View File

@ -1,10 +0,0 @@
package eu.maiora.model
import kotlinx.serialization.Serializable
@Serializable
data class NumPezziPerMagazzino(
val nomeMagazzino : String,
val numeroPezziDisponibili : String
)

View File

@ -1,12 +0,0 @@
package eu.maiora.model
import kotlinx.serialization.Serializable
@Serializable
data class ViewClientiAgenti(
val idCliente : Long,
val cliente : String,
val idAgente: Long,
val username: String
)

View File

@ -1,5 +0,0 @@
package eu.maiora.model
interface ViewClientiAgentiRepository {
suspend fun clienteByAgente(username : String): ViewClientiAgenti?
}

View File

@ -1,14 +0,0 @@
package eu.maiora.model
import eu.maiora.db.*
import org.jetbrains.exposed.sql.or
class ViewClientiAgentiRepositoryImpl : ViewClientiAgentiRepository {
override suspend fun clienteByAgente(username: String): ViewClientiAgenti? = suspendTransaction {
// Cerca un cliente dalla tabella ViewClientiAgenti
ViewClientiAgentiDAO.find { ViewClientiAgentiTable.username eq username }
.singleOrNull() // Restituisce un singolo risultato o null se non trovato
?.let { viewClientiAgentiDaoToModel(it) } // Converte il DAO in un oggetto ViewClientiAgenti
}
}

View File

@ -1,11 +0,0 @@
package eu.maiora.model
import kotlinx.serialization.Serializable
@Serializable
data class ViewEcommerceArticoli(
val id : Long,
val codice : String,
val descrizione: String
)

View File

@ -1,5 +0,0 @@
package eu.maiora.model
interface ViewEcommerceArticoliRepository {
suspend fun articoloByCodice(codice : String): ViewEcommerceArticoli?
}

View File

@ -1,14 +0,0 @@
package eu.maiora.model
import eu.maiora.db.*
import org.jetbrains.exposed.sql.or
class ViewEcommerceArticoliRepositoryImpl : ViewEcommerceArticoliRepository {
override suspend fun articoloByCodice(codice: String): ViewEcommerceArticoli? = suspendTransaction {
// Cerca un articolo dalla tabella ViewEcommerceArticoliTable
ViewEcommerceArticoliDAO.find { ViewEcommerceArticoliTable.codice eq codice }
.singleOrNull() // Restituisce un singolo risultato o null se non trovato
?.let { viewEcommerceArticoliDaoToModel(it) } // Converte il DAO in un oggetto ViewEcommerceArticoli
}
}

View File

@ -1,21 +0,0 @@
package eu.maiora.model
import kotlinx.serialization.Serializable
@Serializable
data class ViewEcommercePrezSconDisp(
val id : Long,
val idCliente : Long,
val idArticolo : Long,
val idMagazzino : Long,
val magazzino : String,
val valoreCarcassa : Double,
val prezzo : Double,
val sconto : Double,
val sconto1 : Double,
val sconto2 : Double,
val sconto3 : Double,
val netto : Double,
val numeroPezzi : Int
)

View File

@ -1,5 +0,0 @@
package eu.maiora.model
interface ViewEcommercePrezSconDispRepository {
suspend fun disponibilitaByIdArtIdClie(idCliente: Long, idArticolo : Long ): List<ViewEcommercePrezSconDisp>?
}

View File

@ -1,64 +0,0 @@
package eu.maiora.model
import eu.maiora.db.*
import eu.maiora.loadConfig
import org.jetbrains.exposed.sql.LongColumnType
class ViewEcommercePrezSconDispRepositoryImpl : ViewEcommercePrezSconDispRepository {
override suspend fun disponibilitaByIdArtIdClie(idCliente: Long, idArticolo : Long): List<ViewEcommercePrezSconDisp>? = suspendTransaction {
// Cerca le disponibilità e i prezzi dato articolo e cliente dalla table function ViewEcommercePrezSconDispTable
val properties = loadConfig()
val result = exec("SELECT * FROM dbo.Get_Prez_Scon_Disp(?, ?)", listOf(
LongColumnType() to idCliente,
LongColumnType() to idArticolo
)) { rs ->
val list = mutableListOf<ViewEcommercePrezSconDisp>()
while (rs.next()) {
val element : ViewEcommercePrezSconDisp
if(idCliente == properties.getProperty("qricambi.id").toLong()){
element = ViewEcommercePrezSconDisp(
id = rs.getLong("id"),
idCliente = rs.getLong("id_cliente"),
idArticolo = rs.getLong("id_articolo"),
idMagazzino = -1,
magazzino = "",
valoreCarcassa = rs.getDouble("valore_carcassa"),
prezzo = 0.0,
sconto = 0.0,
sconto1 = 0.0,
sconto2 = 0.0,
sconto3 = 0.0,
netto = 0.0,
numeroPezzi = rs.getInt("numero_pezzi")
)
}
else {
element = ViewEcommercePrezSconDisp(
id = rs.getLong("id"),
idCliente = rs.getLong("id_cliente"),
idArticolo = rs.getLong("id_articolo"),
idMagazzino = rs.getLong("id_magazzino"),
magazzino = rs.getString("magazzino"),
valoreCarcassa = rs.getDouble("valore_carcassa"),
prezzo = rs.getDouble("prezzo"),
sconto = rs.getDouble("sconto"),
sconto1 = rs.getDouble("sconto_1"),
sconto2 = rs.getDouble("sconto_2"),
sconto3 = rs.getDouble("sconto_3"),
netto = rs.getDouble("netto"),
numeroPezzi = rs.getInt("numero_pezzi")
)
}
list.add(element)
}
list
}
result?.ifEmpty { emptyList() }
}
}

View File

@ -1,12 +0,0 @@
package eu.maiora.model
import kotlinx.serialization.Serializable
@Serializable
data class ViewEcommerceValoreUsato(
val id : Long,
val idCliente : Long,
val idArticolo : Long,
val valoreUsato : Double
)

View File

@ -1,5 +0,0 @@
package eu.maiora.model
interface ViewEcommerceValoreUsatoRepository {
suspend fun getValoreByIdArtIdClie(idCliente: Long, idArticolo : Long ): List<ViewEcommerceValoreUsato>?
}

View File

@ -1,32 +0,0 @@
package eu.maiora.model
import eu.maiora.db.*
import org.jetbrains.exposed.sql.LongColumnType
class ViewEcommerceValoreUsatoRepositoryImpl : ViewEcommerceValoreUsatoRepository {
override suspend fun getValoreByIdArtIdClie(idCliente: Long, idArticolo : Long): List<ViewEcommerceValoreUsato>? = suspendTransaction {
// Cerca il valore della carcassa dalla table function ViewEcommerceValoreUsatoTable
val result = exec("SELECT * FROM dbo.Get_Valore_usato(?, ?)", listOf(
LongColumnType() to idCliente,
LongColumnType() to idArticolo
)) { rs ->
val list = mutableListOf<ViewEcommerceValoreUsato>()
while (rs.next()) {
val element : ViewEcommerceValoreUsato
element = ViewEcommerceValoreUsato(
id = rs.getLong("id"),
idCliente = rs.getLong("id_cliente"),
idArticolo = rs.getLong("id_articolo"),
valoreUsato = rs.getDouble("valore_usato")
)
list.add(element)
}
list
}
result?.ifEmpty { emptyList() }
}
}

View File

@ -1,8 +1,7 @@
package eu.maiora.plugins
import eu.maiora.model.*
import eu.maiora.model.AccountsRepositoryImpl
import eu.maiora.routes.auth
import eu.maiora.routes.disponibilitaArticoli
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
@ -14,10 +13,5 @@ fun Application.configureRouting() {
}
auth(AccountsRepositoryImpl())
disponibilitaArticoli(ArticoliCrossQRicambiRepositoryImpl(),
ViewEcommerceArticoliRepositoryImpl(),
ViewEcommercePrezSconDispRepositoryImpl(),
ViewClientiAgentiRepositoryImpl(),
ViewEcommerceValoreUsatoRepositoryImpl())
}
}

View File

@ -1,128 +0,0 @@
package eu.maiora.routes
import eu.maiora.loadConfig
import eu.maiora.model.*
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.server.auth.jwt.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import kotlin.collections.ArrayList
fun Route.disponibilitaArticoli(articoliCrossQRicambiRepository: ArticoliCrossQRicambiRepository,
viewEcommerceArticoliRepository: ViewEcommerceArticoliRepository,
viewEcommercePrezSconDispRepository: ViewEcommercePrezSconDispRepository,
viewClientiAgentiRepository : ViewClientiAgentiRepository,
viewEcommerceValoreUsatoRepository: ViewEcommerceValoreUsatoRepository){
route("/api/disponibilitaArticoli"){
authenticate("auth-jwt") {
get("{codiceArticolo}"){
val username = call.authentication.principal<JWTPrincipal>()?.payload?.subject ?: ""
// Ottieni il codice articolo dal percorso
val codiceArticolo = call.parameters["codiceArticolo"]
if (codiceArticolo == null) {
call.respondText("Codice articolo non valido", status = HttpStatusCode.BadRequest)
return@get
}
//ricerca del codice articolo
//- verifico che il codice esista nel sistema interno, ovvero nella tabella ARTICOLI_CROSS_QRICAMBI
// la ricerca va effettuata prima per CODICE_ARTICOLO e poi per CODICE_CROSS
//- se non esiste, restituisco not found
//- altrimenti, recupero l'id dell'articolo dalla vista VIEW_ECOMMERCE_ARTICOLI
// e tutti i dati da mostrare (vedi GET_PREZ_SCON_DISP, named query in ViewEcommercePrezSconDisp)
val properties = loadConfig()
if(username.equals(properties.getProperty("qricambi.username").toString())){
val idClienteQRicambi = properties.getProperty("qricambi.id").toLong()
val listArticoliCrossQRicambi = articoliCrossQRicambiRepository.articoloByCodArt(codiceArticolo)
if(listArticoliCrossQRicambi.isNotEmpty()){
val articoloEcommerce = viewEcommerceArticoliRepository.articoloByCodice(listArticoliCrossQRicambi[0].codiceArticolo)
if(articoloEcommerce != null){
val dataValoreUsato = viewEcommerceValoreUsatoRepository.getValoreByIdArtIdClie(idClienteQRicambi, articoloEcommerce.id)
val data = viewEcommercePrezSconDispRepository.disponibilitaByIdArtIdClie(idClienteQRicambi, articoloEcommerce.id)
if(data != null){
var listNumPezziPerMagazzino = ArrayList<NumPezziPerMagazzino>()
var numPezziDisponibili = 0;
data.forEach { e ->
numPezziDisponibili += e.numeroPezzi
}
listNumPezziPerMagazzino.add(NumPezziPerMagazzino("", numPezziDisponibili.toString()))
val result = DisponibilitaArticoli(articoloEcommerce.codice,
articoloEcommerce.descrizione,
listArticoliCrossQRicambi[0].costruttore,
data[0].netto.toString(),
data[0].numeroPezzi > 0,
listNumPezziPerMagazzino,
(dataValoreUsato?.firstOrNull()?.valoreUsato ?: "0.0").toString()
)
call.respond(result)
}
else {
call.respondText("Articolo ecommerce non trovato (prezzi sconti e disponibilita)", status = HttpStatusCode.NotFound)
}
}
else {
call.respondText("Articolo ecommerce non trovato", status = HttpStatusCode.NotFound)
}
}
else {
call.respondText("Articolo non trovato", status = HttpStatusCode.NotFound)
}
}
else {
//verificare il cliente collegato all'agente/username
val cliente = viewClientiAgentiRepository.clienteByAgente(username)
if(cliente != null){
val listArticoliCrossQRicambi = articoliCrossQRicambiRepository.articoloByCodArt(codiceArticolo)
if(!listArticoliCrossQRicambi.isEmpty()){
val articoloEcommerce = viewEcommerceArticoliRepository.articoloByCodice(listArticoliCrossQRicambi[0].codiceArticolo)
if(articoloEcommerce != null){
val dataValoreUsato = viewEcommerceValoreUsatoRepository.getValoreByIdArtIdClie(cliente.idCliente, articoloEcommerce.id)
val data = viewEcommercePrezSconDispRepository.disponibilitaByIdArtIdClie(cliente.idCliente, articoloEcommerce.id)
if(!data.isNullOrEmpty()){
var listNumPezziPerMagazzino = ArrayList<NumPezziPerMagazzino>()
data.forEach { e ->
listNumPezziPerMagazzino.add(NumPezziPerMagazzino(e.magazzino, e.numeroPezzi.toString()))
}
val result = DisponibilitaArticoli(articoloEcommerce.codice,
articoloEcommerce.descrizione,
listArticoliCrossQRicambi[0].costruttore,
data[0].netto.toString(),
data[0].numeroPezzi > 0,
listNumPezziPerMagazzino,
dataValoreUsato?.get(0)?.valoreUsato.toString()
)
call.respond(result)
}
else {
call.respondText("Articolo ecommerce non trovato (prezzi sconti e disponibilita)", status = HttpStatusCode.NotFound)
}
}
else {
call.respondText("Articolo ecommerce non trovato", status = HttpStatusCode.NotFound)
}
}
else {
call.respondText("Articolo non trovato", status = HttpStatusCode.NotFound)
}
}
else {
call.respondText("Cliente collegato all'agente non trovato", status = HttpStatusCode.NotFound)
}
}
}
}
}
}