mirror of
https://github.com/Sheldan/gw2-tools.git
synced 2026-04-04 23:15:13 +00:00
initial commit of functioning opening tracking
This commit is contained in:
79
gw2-tools-backend/rest-api/pom.xml
Normal file
79
gw2-tools-backend/rest-api/pom.xml
Normal file
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>dev.sheldan.gw2.tools</groupId>
|
||||
<artifactId>gw2-tools</artifactId>
|
||||
<version>0.0.9-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>rest-api</artifactId>
|
||||
|
||||
|
||||
<build>
|
||||
<sourceDirectory>src/main/kotlin</sourceDirectory>
|
||||
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire-plugin.version}</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>${maven-failsafe-plugin.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-test-junit5</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.gw2.tools</groupId>
|
||||
<artifactId>gw2-api-client</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.gw2.tools</groupId>
|
||||
<artifactId>database</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.microutils</groupId>
|
||||
<artifactId>kotlin-logging-jvm</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,4 @@
|
||||
package dev.sheldan.gw2.tools
|
||||
|
||||
class ItemNotFoundException(message: String): Throwable(message) {
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package dev.sheldan.gw2.tools.api
|
||||
|
||||
import dev.sheldan.gw2.tools.loader.AccountLoader
|
||||
import dev.sheldan.gw2.tools.models.AccountMaterialView
|
||||
import dev.sheldan.gw2.tools.models.AccountVaultView
|
||||
import dev.sheldan.gw2.tools.models.AccountWalletView
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
import org.springframework.web.context.annotation.RequestScope
|
||||
|
||||
@RestController
|
||||
@RequestScope
|
||||
class AccountController(var accountLoader: AccountLoader) {
|
||||
@GetMapping("/characters")
|
||||
fun inventory(): List<String>? {
|
||||
return accountLoader.getCharacters()
|
||||
}
|
||||
|
||||
@GetMapping("/wallet")
|
||||
fun wallet(): AccountWalletView {
|
||||
return accountLoader.getWallet()
|
||||
}
|
||||
|
||||
@GetMapping("/bank")
|
||||
fun bank(): AccountVaultView {
|
||||
return accountLoader.getBank()
|
||||
}
|
||||
|
||||
@GetMapping("/materials")
|
||||
fun materials(): AccountMaterialView {
|
||||
return accountLoader.getMaterials()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.gw2.tools.api
|
||||
|
||||
import dev.sheldan.gw2.tools.service.CacheService
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@RestController
|
||||
class CurrencyController(val cacheService: CacheService) {
|
||||
|
||||
@PostMapping("/currency-cache")
|
||||
fun updateCurrencyCache() {
|
||||
cacheService.reloadCurrencyCache()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package dev.sheldan.gw2.tools.api
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@RestController
|
||||
class Health {
|
||||
@GetMapping("/health-check")
|
||||
fun healCheck(): String {
|
||||
return "yes"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package dev.sheldan.gw2.tools.api
|
||||
|
||||
import dev.sheldan.gw2.tools.loader.InventoryLoader
|
||||
import dev.sheldan.gw2.tools.models.AccountInventory
|
||||
import dev.sheldan.gw2.tools.models.AccountInventoryView
|
||||
import dev.sheldan.gw2.tools.models.CharacterInventory
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
import org.springframework.web.context.annotation.RequestScope
|
||||
|
||||
@RestController
|
||||
@RequestScope
|
||||
class InventoryController(var inventoryLoader: InventoryLoader) {
|
||||
|
||||
@GetMapping("/inventory/{name}")
|
||||
fun characterInventory(@PathVariable("name") characterName: String): CharacterInventory {
|
||||
return inventoryLoader.getFullCharacterInventory(characterName)
|
||||
}
|
||||
|
||||
@GetMapping("/inventory")
|
||||
fun completeCharacterInventory(): AccountInventoryView {
|
||||
return inventoryLoader.getAccountInventory()
|
||||
}
|
||||
|
||||
@GetMapping("/sharedInventory")
|
||||
fun accountInventory(): AccountInventory {
|
||||
return inventoryLoader.getSharedInventory()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.gw2.tools.api
|
||||
|
||||
import dev.sheldan.gw2.tools.service.CacheService
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@RestController
|
||||
class ItemController(val cacheService: CacheService) {
|
||||
|
||||
@PostMapping("/item-cache")
|
||||
fun updateItemCache() {
|
||||
cacheService.reloadItemCache()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package dev.sheldan.gw2.tools.api
|
||||
|
||||
import dev.sheldan.gw2.tools.config.ApiKeyInterceptor
|
||||
import dev.sheldan.gw2.tools.model.ItemRates
|
||||
import dev.sheldan.gw2.tools.model.OpeningRequest
|
||||
import dev.sheldan.gw2.tools.model.OpeningsView
|
||||
import dev.sheldan.gw2.tools.service.OpeningService
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import mu.KotlinLogging
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import org.springframework.web.context.annotation.RequestScope
|
||||
|
||||
@RestController
|
||||
@RequestScope
|
||||
class OpeningController(val openingService: OpeningService) {
|
||||
private val logger = KotlinLogging.logger {}
|
||||
|
||||
@PostMapping("/openings")
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
fun createOpenings(request: HttpServletRequest, @RequestBody openingRequest: OpeningRequest) {
|
||||
val apiKey: String = request.getHeader(ApiKeyInterceptor.API_KEY_HEADER_NAME) ?: throw IllegalArgumentException("API key not provided.")
|
||||
openingService.createOpening(openingRequest, apiKey)
|
||||
}
|
||||
|
||||
@GetMapping("/openings")
|
||||
fun getOpenings(request: HttpServletRequest, @RequestParam("showOwnOnly") ownOnly: String?): OpeningsView {
|
||||
val apiKey: String? = request.getHeader(ApiKeyInterceptor.API_KEY_HEADER_NAME)
|
||||
val showOnOnly = ownOnly.toBoolean()
|
||||
logger.info { "Retrieving openings" }
|
||||
val loadedOpenings = openingService.loadOpenings(apiKey, showOnOnly)
|
||||
logger.info { "Loaded ${loadedOpenings.openings.size} openings" }
|
||||
return loadedOpenings
|
||||
}
|
||||
|
||||
@DeleteMapping("/openings/{id}")
|
||||
fun deleteOpening(request: HttpServletRequest, @PathVariable("id") openingId: Int) {
|
||||
val apiKey: String = request.getHeader(ApiKeyInterceptor.API_KEY_HEADER_NAME) ?: throw IllegalArgumentException("API key not provided.")
|
||||
openingService.deleteOpening(apiKey, openingId)
|
||||
}
|
||||
|
||||
@GetMapping("/itemRates")
|
||||
fun getItemRates(): ItemRates {
|
||||
return openingService.loadItemRates()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package dev.sheldan.gw2.tools.api
|
||||
|
||||
import dev.sheldan.gw2.tools.ItemNotFoundException
|
||||
import dev.sheldan.gw2.tools.service.SubmissionTemplateService
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.web.bind.annotation.*
|
||||
|
||||
@RestController
|
||||
class SubmissionTemplateController(
|
||||
val submissionTemplateService: SubmissionTemplateService
|
||||
) {
|
||||
@GetMapping("/submissionTemplates")
|
||||
@ResponseBody
|
||||
fun getSubmissionTemplatesForItem(@RequestParam("itemId") itemId: Int?): ResponseEntity<Any> {
|
||||
try {
|
||||
val responseObj = itemId?.let { submissionTemplateService.getSubmissionTemplateForItem(itemId) } ?: submissionTemplateService.getSubmissionTemplates()
|
||||
return ResponseEntity(responseObj, HttpStatus.OK)
|
||||
} catch (e: ItemNotFoundException) {
|
||||
return ResponseEntity(e.message, HttpStatus.BAD_REQUEST)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package dev.sheldan.gw2.tools.config
|
||||
|
||||
open class ApiKeyContainer : ApiKey {
|
||||
var apiKeyValue: String = "";
|
||||
override fun getApiKey(): String {
|
||||
return apiKeyValue
|
||||
}
|
||||
|
||||
override fun setApiKey(key: String) {
|
||||
this.apiKeyValue = key
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.sheldan.gw2.tools.config
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import jakarta.servlet.http.HttpServletResponse
|
||||
import org.springframework.web.servlet.HandlerInterceptor
|
||||
|
||||
class ApiKeyInterceptor(private val apiKeyContainer: ApiKey) : HandlerInterceptor {
|
||||
|
||||
companion object {
|
||||
const val API_KEY_HEADER_NAME = "api-key"
|
||||
}
|
||||
|
||||
override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
|
||||
val apiKey: String? = request.getHeader(API_KEY_HEADER_NAME)
|
||||
apiKey?.let { apiKeyContainer.setApiKey(it) }
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package dev.sheldan.gw2.tools.config
|
||||
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.web.context.annotation.RequestScope
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
|
||||
|
||||
|
||||
@Configuration
|
||||
class HeaderInterceptorConfig : WebMvcConfigurer {
|
||||
override fun addInterceptors(registry: InterceptorRegistry) {
|
||||
registry.addInterceptor(apiKeyInterceptor())
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun apiKeyInterceptor(): ApiKeyInterceptor {
|
||||
return ApiKeyInterceptor(apiContainer())
|
||||
}
|
||||
|
||||
@Bean
|
||||
@RequestScope
|
||||
fun apiContainer(): ApiKeyContainer {
|
||||
return ApiKeyContainer()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package dev.sheldan.gw2.tools.model
|
||||
|
||||
|
||||
data class DisplayOpeningItem(val itemId: Int, val change: Int, val itemType: OpeningItemType) {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.sheldan.gw2.tools.model
|
||||
|
||||
class ItemDisplay(
|
||||
val id: Int,
|
||||
val name: String,
|
||||
val iconUrl: String,
|
||||
val description: String,
|
||||
val rarity: String
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package dev.sheldan.gw2.tools.model
|
||||
|
||||
import dev.sheldan.gw2.tools.models.EnrichedCurrency
|
||||
import dev.sheldan.gw2.tools.models.EnrichedItem
|
||||
|
||||
class ItemRate(val item: EnrichedItem, val receivedItems: List<EnrichedItem>, val receivedCurrencies: List<EnrichedCurrency>) {
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package dev.sheldan.gw2.tools.model
|
||||
|
||||
class ItemRates(val itemRates: List<ItemRate>) {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package dev.sheldan.gw2.tools.model
|
||||
|
||||
class ItemSubmissionTemplate(
|
||||
val submissionTemplates: List<SubmissionTemplateDisplay>,
|
||||
val item: ItemDisplay
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.sheldan.gw2.tools.model
|
||||
|
||||
class ItemSubmissionTemplateList(
|
||||
val itemSubmissionTemplates: List<ItemSubmissionTemplate>
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package dev.sheldan.gw2.tools.model
|
||||
|
||||
enum class OpeningItemType {
|
||||
CURRENCY, ITEM
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package dev.sheldan.gw2.tools.model
|
||||
|
||||
data class OpeningRequest(
|
||||
val items: List<DisplayOpeningItem>,
|
||||
val description: String?=null,
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package dev.sheldan.gw2.tools.model
|
||||
|
||||
import dev.sheldan.gw2.tools.models.EnrichedCurrency
|
||||
import dev.sheldan.gw2.tools.models.EnrichedItem
|
||||
import java.time.Instant
|
||||
|
||||
class OpeningView(
|
||||
val itemChanges: List<EnrichedItem>,
|
||||
val currencyChanges: List<EnrichedCurrency>,
|
||||
val openingId: Int,
|
||||
val description: String?,
|
||||
val openingDate: Instant) {
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package dev.sheldan.gw2.tools.model
|
||||
|
||||
class OpeningsView(val openings: List<OpeningView>) {
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package dev.sheldan.gw2.tools.model
|
||||
|
||||
class SubmissionTemplateDisplay(
|
||||
val name: String,
|
||||
val description: String,
|
||||
val templateText: String
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package dev.sheldan.gw2.tools.service
|
||||
|
||||
import dev.sheldan.gw2.tools.loader.CurrencyLoader
|
||||
import dev.sheldan.gw2.tools.loader.ItemLoader
|
||||
import mu.KotlinLogging
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
class CacheService(
|
||||
val itemLoader: ItemLoader,
|
||||
val itemManagement: ItemManagement,
|
||||
val currencyLoader: CurrencyLoader,
|
||||
val currencyManagement: CurrencyManagement
|
||||
) {
|
||||
|
||||
private val logger = KotlinLogging.logger {}
|
||||
fun reloadItemCache() {
|
||||
val allItemsApi = itemLoader.getAllItems().associateBy { it.id }
|
||||
logger.info { "Loaded ${allItemsApi.size} items from API" }
|
||||
val allItemsDb = itemManagement.getItems().associateBy { it.id }
|
||||
logger.info { "Loaded ${allItemsDb.size} items from DB" }
|
||||
val missingItems = allItemsApi.keys.minus(allItemsDb.keys)
|
||||
val newDbItems = missingItems.mapNotNull { itemId ->
|
||||
val item = allItemsApi[itemId]
|
||||
item?.let {
|
||||
itemManagement.createItem(
|
||||
it.id,
|
||||
item.name!!,
|
||||
item.description!!,
|
||||
item.iconUrl!!,
|
||||
it.type!!.name,
|
||||
item.rarity!!.name
|
||||
)
|
||||
}
|
||||
}.toList()
|
||||
logger.info { "Creating ${newDbItems.size} new items" }
|
||||
itemManagement.saveItems(newDbItems)
|
||||
|
||||
}
|
||||
|
||||
fun reloadCurrencyCache() {
|
||||
val allCurrenciesApi = currencyLoader.getAllCurrencies().associateBy { it.id }
|
||||
logger.info { "Loaded ${allCurrenciesApi.size} currencies from API" }
|
||||
val allCurrenciesDb = currencyManagement.getCurrencies().associateBy { it.id }
|
||||
logger.info { "Loaded ${allCurrenciesDb.size} currencies from DB" }
|
||||
val missingCurrencies = allCurrenciesApi.keys.minus(allCurrenciesDb.keys)
|
||||
val newDbCurrencies = missingCurrencies.mapNotNull {
|
||||
itemId ->
|
||||
val item = allCurrenciesApi[itemId]
|
||||
item?.let {
|
||||
currencyManagement.createCurrency(
|
||||
it.id,
|
||||
item.name,
|
||||
item.description,
|
||||
item.iconUrl
|
||||
)
|
||||
}
|
||||
}
|
||||
logger.info { "Creating ${newDbCurrencies.size} new items" }
|
||||
currencyManagement.saveCurrencies(newDbCurrencies)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
package dev.sheldan.gw2.tools.service
|
||||
|
||||
import dev.sheldan.gw2.tools.entity.Currency
|
||||
import dev.sheldan.gw2.tools.entity.Item
|
||||
import dev.sheldan.gw2.tools.entity.Opening
|
||||
import dev.sheldan.gw2.tools.entity.OpeningItem
|
||||
import dev.sheldan.gw2.tools.model.*
|
||||
import dev.sheldan.gw2.tools.models.EnrichedCurrency
|
||||
import dev.sheldan.gw2.tools.models.EnrichedItem
|
||||
import dev.sheldan.gw2.tools.models.Gw2TItemType
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
class OpeningService(
|
||||
val userManagement: UserManagement,
|
||||
val openingManagement: OpeningManagement,
|
||||
val itemManagement: ItemManagement,
|
||||
val currencyManagement: CurrencyManagement
|
||||
) {
|
||||
fun createOpening(openingRequest: OpeningRequest, token: String) {
|
||||
val user = userManagement.getOrCreateUser(token)
|
||||
val itemsWithIds = openingRequest.items.filter { it.itemType == OpeningItemType.ITEM }.associateBy { it.itemId }
|
||||
val fullItems =
|
||||
itemManagement.getItems(itemsWithIds.keys.toList()).associateWith { itemsWithIds[it.id]!!.change }
|
||||
val currenciesWithIds =
|
||||
openingRequest.items.filter { it.itemType == OpeningItemType.CURRENCY }.associateBy { it.itemId }
|
||||
val fullCurrencies = currencyManagement.getCurrencies(currenciesWithIds.keys.toList())
|
||||
.associateWith { currenciesWithIds[it.id]!!.change }
|
||||
openingManagement.createOpening(user, fullItems, fullCurrencies, openingRequest.description)
|
||||
}
|
||||
|
||||
fun loadOpenings(token: String?, ownOnly: Boolean): OpeningsView {
|
||||
val openings: List<Opening>;
|
||||
if (ownOnly && token != null) {
|
||||
val user = userManagement.getOrCreateUser(token)
|
||||
openings = openingManagement.getOpeningsByUser(user)
|
||||
} else {
|
||||
openings = openingManagement.getAllOpenings()
|
||||
}
|
||||
val items = openings.filter { it.items != null }.flatMap { it.items!! }
|
||||
val itemIds = items.map { it.item.id }
|
||||
val loadedItemsMap = itemManagement.getItemsAsMap(itemIds)
|
||||
val currencies = openings.filter { it.currencies != null }.flatMap { it.currencies!! }
|
||||
val currencyIds = currencies.map { it.currency.id }
|
||||
val loadedCurrenciesMapMap = currencyManagement.getCurrenciesAsMap(currencyIds)
|
||||
val openingViews = openings.map { convertOpening(it, loadedItemsMap, loadedCurrenciesMapMap) }
|
||||
return OpeningsView(openingViews)
|
||||
}
|
||||
|
||||
fun deleteOpening(token: String, openingId: Int) {
|
||||
val user = userManagement.getOrCreateUser(token)
|
||||
val opening = openingManagement.getOpening(openingId)
|
||||
opening.map {
|
||||
if (user.id == it.user.id) {
|
||||
openingManagement.deleteOpening(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun convertOpening(opening: Opening, itemMap: Map<Int, Item>, currencyMap: Map<Int, Currency>): OpeningView {
|
||||
val items = mutableListOf<EnrichedItem>()
|
||||
opening.items?.mapNotNull {
|
||||
val enrichedItem = EnrichedItem(it.item.id, it.count)
|
||||
itemMap[it.item.id]?.let { item ->
|
||||
enrichedItem.setValuesFromDbItem(item)
|
||||
return@mapNotNull enrichedItem
|
||||
}
|
||||
}?.let { items.addAll(it) }
|
||||
val currencies = mutableListOf<EnrichedCurrency>()
|
||||
opening.currencies?.mapNotNull {
|
||||
currencyMap[it.currency.id]?.let { currency ->
|
||||
EnrichedCurrency(currency.id, it.amount, currency.name, currency.description, currency.iconUrl)
|
||||
}
|
||||
}?.let { currencies.addAll(it) }
|
||||
return OpeningView(items, currencies, opening.id!!, opening.description, opening.creationDate!!)
|
||||
}
|
||||
|
||||
fun loadItemRates(): ItemRates {
|
||||
val openings = openingManagement.getAllOpenings()
|
||||
val presentItems = openings.filter { it.items != null }.flatMap { it.items!! }.map { it.item }
|
||||
val presentCurrencies = openings.filter { it.currencies != null }.flatMap { it.currencies!! }.map { it.currency }
|
||||
val itemIds = presentItems.map { it.id }
|
||||
val currencyIds = presentCurrencies.map { it.id }
|
||||
val loadedItemsMap = itemManagement.getItemsAsMap(itemIds)
|
||||
val loadedCurrenciesMap = currencyManagement.getCurrenciesAsMap(currencyIds)
|
||||
val allItems = openings.mapNotNull { opening ->
|
||||
val containers = getListOfContainersFromOpening(opening)
|
||||
if(containers.size == 1) {
|
||||
val containerOpeningItem = containers[0]
|
||||
val enrichedContainerItem = EnrichedItem(containerOpeningItem.item.id, containerOpeningItem.count)
|
||||
loadedItemsMap[containerOpeningItem.item.id]?.let { item ->
|
||||
enrichedContainerItem.setValuesFromDbItem(item)
|
||||
}
|
||||
val resultingItems = opening.items?.filter { it.count > 0 }?.mapNotNull itemMap@ {
|
||||
val enrichedItem = EnrichedItem(it.item.id, it.count)
|
||||
loadedItemsMap[it.item.id]?.let { item ->
|
||||
enrichedItem.setValuesFromDbItem(item)
|
||||
return@itemMap enrichedItem
|
||||
}
|
||||
}?: listOf()
|
||||
val resultingCurrencies = opening.currencies?.filter { it.amount > 0 }?.mapNotNull currencyMap@ {
|
||||
loadedCurrenciesMap[it.currency.id]?.let { currency ->
|
||||
val enrichedCurrency = EnrichedCurrency(it.currency.id, it.amount, currency.name, currency.description, currency.iconUrl)
|
||||
return@currencyMap enrichedCurrency
|
||||
}
|
||||
}?: listOf()
|
||||
return@mapNotNull ItemRate(enrichedContainerItem, resultingItems, resultingCurrencies)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
val itemRateMap = mutableMapOf<Int, ItemRate>()
|
||||
allItems.forEach{ item ->
|
||||
itemRateMap[item.item.id]?.let { itemRate ->
|
||||
val existingEnrichedItems = itemRate.receivedItems.associateBy { receivedItem -> receivedItem.id }
|
||||
item.receivedItems.forEach{receivedItem ->
|
||||
existingEnrichedItems[receivedItem.id]?.let{
|
||||
it.count += receivedItem.count
|
||||
}?: itemRate.receivedItems.addLast(receivedItem)
|
||||
}
|
||||
val existingEnrichedCurrencies = itemRate.receivedCurrencies.associateBy { receivedCurrency -> receivedCurrency.id }
|
||||
item.receivedCurrencies.forEach{receivedCurrency ->
|
||||
existingEnrichedCurrencies[receivedCurrency.id]?.let{
|
||||
it.amount += receivedCurrency.amount
|
||||
}?: itemRate.receivedCurrencies.addLast(receivedCurrency)
|
||||
}
|
||||
itemRate.item.count += item.item.count
|
||||
}?: itemRateMap.put(item.item.id, item)
|
||||
}
|
||||
return ItemRates(itemRateMap.values.toList())
|
||||
}
|
||||
|
||||
private fun getListOfContainersFromOpening(opening: Opening): List<OpeningItem> {
|
||||
return opening.items?.filter { item -> item.count < 0 && item.item.type == Gw2TItemType.CONTAINER.name } ?: listOf()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package dev.sheldan.gw2.tools.service
|
||||
|
||||
import dev.sheldan.gw2.tools.ItemNotFoundException
|
||||
import dev.sheldan.gw2.tools.model.ItemDisplay
|
||||
import dev.sheldan.gw2.tools.model.SubmissionTemplateDisplay
|
||||
import dev.sheldan.gw2.tools.model.ItemSubmissionTemplate
|
||||
import dev.sheldan.gw2.tools.model.ItemSubmissionTemplateList
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
class SubmissionTemplateService(
|
||||
val submissionTemplateManagement: SubmissionTemplateManagement,
|
||||
val itemManagement: ItemManagement
|
||||
) {
|
||||
fun getSubmissionTemplateForItem(itemId: Int): ItemSubmissionTemplate {
|
||||
val item = itemManagement.getItem(itemId)?: throw ItemNotFoundException("Item not found.")
|
||||
val submissionTemplates = submissionTemplateManagement.getSubmissionTemplatesForItem(item)
|
||||
val itemDisplay = ItemDisplay(item.id, item.name, item.iconUrl, item.description, item.rarity)
|
||||
val templateDisplays = submissionTemplates.map {
|
||||
SubmissionTemplateDisplay(it.name, it.description, it.templateText)
|
||||
}
|
||||
return ItemSubmissionTemplate(templateDisplays, itemDisplay)
|
||||
}
|
||||
|
||||
fun getSubmissionTemplates(): ItemSubmissionTemplateList {
|
||||
val submissionTemplates = submissionTemplateManagement.getAllSubmissionTemplates()
|
||||
val items = submissionTemplates.associateBy { it.item }.keys
|
||||
val itemSubmissionTemplates = items.map { item ->
|
||||
val itemDisplay = ItemDisplay(item.id, item.name, item.iconUrl, item.description, item.rarity)
|
||||
val submissionTemplatesOfItem = submissionTemplates.filter { it.item.id == item.id }
|
||||
val templateDisplays = submissionTemplatesOfItem.map {
|
||||
SubmissionTemplateDisplay(it.name, it.description, it.templateText)
|
||||
}
|
||||
ItemSubmissionTemplate(templateDisplays, itemDisplay)
|
||||
}
|
||||
return ItemSubmissionTemplateList(itemSubmissionTemplates)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user