package golf.handicap.hibernate.db import com.fasterxml.jackson.databind.ObjectMapper import dmo.fs.entities.PersistedScores import dmo.fs.utils.Err import golf.handicap.Score import golf.handicap.hibernate.db.PopulateGolferScores.Companion.Parms import io.smallrye.mutiny.Uni import io.vertx.mutiny.core.Promise import jakarta.persistence.criteria.CriteriaQuery import org.hibernate.reactive.mutiny.Mutiny import org.slf4j.LoggerFactory import java.time.LocalDateTime class PopulateScore : SqlConstants(), IPopulateScore { companion object { private val LOGGER = LoggerFactory.getLogger(PopulateScore::class.java.name) } override fun setScore( score: Score, session: Mutiny.Session ): Uni { val jsonPromise: Promise = Promise.promise() val uniScores = getScoreByTeetime(score, session) uniScores.onItemOrFailure().invoke { scores, err -> if (err != null) { LOGGER.error(Err.displayErr(85), err.message) } val jsonMapper = ObjectMapper() if (scores.isEmpty()) { val persistedScores = buildScore(score) session.persist(persistedScores).onItemOrFailure().invoke { _, err -> if (err != null) { LOGGER.error(Err.displayErr(86), err.message) score.status = -1 score.message = Err.displayErr(87) val jsonData = jsonMapper.writeValueAsString(score) jsonPromise.complete(jsonData) } else { session.flush().onItemOrFailure().invoke { _, err -> if (err != null) { LOGGER.error(Err.displayErr(77), err.message) } session.clear() val jsonData = jsonMapper.writeValueAsString(score) jsonPromise.complete(jsonData) }.subscribeAsCompletionStage() } }.subscribeAsCompletionStage() } else { updateScore(score, session).onItemOrFailure().invoke { updatedScore, err -> if (err != null) { LOGGER.error(Err.displayErr(81), err.message) } val jsonData = jsonMapper.writeValueAsString(updatedScore) jsonPromise.complete(jsonData) }.subscribeAsCompletionStage() } }.subscribeAsCompletionStage() return jsonPromise.future() } private fun getScoreByTeetime(score: Score, session: Mutiny.Session): Uni> { val scoresPromise: Promise> = Promise.promise() val scores = mutableSetOf() val builder = session.criteriaBuilder val scoreCriteria: CriteriaQuery = builder.createQuery(PersistedScores::class.java) val root = scoreCriteria.from(PersistedScores::class.java) val pinPredicate = builder.equal(root.get(Parms.PIN.entry), score.golfer!!.pin) val teeTimePredicate = builder.equal( root.get("teeTime"), score.teeTime?.let { LocalDateTime.parse(it) }) val coursePredicate = builder.equal(root.get("courseSeq"), score.course!!.course_key) scoreCriteria.where( pinPredicate, builder.and(teeTimePredicate), builder.and(coursePredicate), builder.and(teeTimePredicate) ) session.createQuery(scoreCriteria).resultList.onItemOrFailure().invoke { queryScores, err -> if (err != null) { LOGGER.error(Err.displayErr(78), err.message) } for (queryScore in queryScores) { val newScore = Score() newScore.golfer = golf.handicap.Golfer() newScore.course = score.course newScore.golfer!!.pin = queryScore.scoresId!!.pin newScore.grossScore = queryScore.grossScore!! newScore.netScore = queryScore.netScore!!.toFloat() newScore.adjustedScore = queryScore.adjustedScore!! newScore.teeTime = queryScore.teeTime.toString() newScore.handicap = queryScore.handicap!!.toFloat() newScore.golfer!!.handicap = queryScore.handicap!!.toDouble() newScore.course!!.course_key = queryScore.course!!.courseSeq newScore.course!!.teeId = queryScore.courseTees!! newScore.tees = queryScore.courseTees!!.toString() scores.add(newScore) } scoresPromise.complete(scores) }.subscribeAsCompletionStage() return scoresPromise.future() //scores } private fun buildScore(score: Score): PersistedScores { val persistedScores = PersistedScores() try { persistedScores.grossScore = score.grossScore persistedScores.netScore = score.netScore.toBigDecimal(); persistedScores.adjustedScore = score.adjustedScore persistedScores.pin = score.golfer!!.pin persistedScores.courseSeq = score.course!!.course_key persistedScores.courseTees = score.course!!.teeId persistedScores.handicap = score.handicap.toBigDecimal() persistedScores.teeTime = score.teeTime?.let { LocalDateTime.parse(it) } val scoreId = PersistedScores.ScoresId(score.golfer!!.pin!!, score.course!!.course_key, persistedScores.teeTime!!) persistedScores.scoresId = scoreId persistedScores.used = persistedScores.used ?: ' ' } catch (e: Exception) { e.printStackTrace() } return persistedScores } private fun updateScore(score: Score, session: Mutiny.Session): Uni { val updatePromise: Promise = Promise.promise() val query = scoreUpdateQuery(score, session) query.executeUpdate().onItemOrFailure().invoke { _, err -> if (err != null) { err.printStackTrace() LOGGER.error(err.message, err) score.status = -1 score.message = Err.displayErr(88) } session.flush().onItemOrFailure().invoke { _, err -> if (err != null) { LOGGER.error(err.message, err) } updateGolfer(score, session).onItemOrFailure().invoke { golferScore, err -> if (err != null) { LOGGER.error("${Err.displayErr(88)}: ${err.message}") } updatePromise.complete(golferScore) }.subscribeAsCompletionStage() }.subscribeAsCompletionStage() }.subscribeAsCompletionStage() return updatePromise.future() } private fun scoreUpdateQuery(score: Score, session: Mutiny.Session): Mutiny.MutationQuery { val teeTime = score.teeTime?.let { LocalDateTime.parse(it) } return session.createMutationQuery(UPDATE_SCORE) .setParameter(Parms.NET.entry, score.netScore) .setParameter(Parms.GROSS.entry, score.grossScore) .setParameter(Parms.ADJUSTED.entry, score.adjustedScore) .setParameter(Parms.HANDICAP.entry, score.handicap) .setParameter(Parms.COURSE.entry, score.course?.course_key) .setParameter(Parms.PIN.entry, score.golfer?.pin) .setParameter(Parms.TEE.entry, score.course?.teeId) .setParameter(Parms.TIME.entry, teeTime) } private fun updateGolfer(score: Score, session: Mutiny.Session): Uni { val updatePromise: Promise = Promise.promise() var pin = "" score.golfer?.pin.let { pin = it!! } val query = session.createMutationQuery(UPDATE_GOLFER) .setParameter(1, score.golfer!!.overlap) .setParameter(2, score.golfer!!.public) .setParameter(3, score.golfer!!.pin) query.executeUpdate().onItemOrFailure().invoke { _, err -> if (err != null) { LOGGER.error(Err.displayErr(71), err.message) score.status = -1 score.message = Err.displayErr(88) } session.flush().onItemOrFailure().invoke { _, err -> if (err != null) { LOGGER.error(Err.displayErr(89), err.message) } session.close().onItemOrFailure().invoke { _, err -> if (err != null) { LOGGER.error(Err.displayErr(77), err.message) } updatePromise.complete(score) }.subscribeAsCompletionStage() }.subscribeAsCompletionStage() }.subscribeAsCompletionStage() return updatePromise.future() } }