diff --git a/src/main/java/group/goforward/battlbuilder/controllers/ProductController.java b/src/main/java/group/goforward/battlbuilder/controllers/ProductController.java index d41d0ef..666af49 100644 --- a/src/main/java/group/goforward/battlbuilder/controllers/ProductController.java +++ b/src/main/java/group/goforward/battlbuilder/controllers/ProductController.java @@ -3,12 +3,14 @@ package group.goforward.battlbuilder.controllers; import group.goforward.battlbuilder.model.Product; import group.goforward.battlbuilder.model.ProductOffer; import group.goforward.battlbuilder.repos.ProductOfferRepository; +import group.goforward.battlbuilder.web.dto.ProductDto; import group.goforward.battlbuilder.web.dto.ProductOfferDto; import group.goforward.battlbuilder.repos.ProductRepository; import group.goforward.battlbuilder.web.dto.ProductSummaryDto; import group.goforward.battlbuilder.web.mapper.ProductMapper; import org.springframework.cache.annotation.Cacheable; import org.springframework.web.bind.annotation.*; +import org.springframework.http.ResponseEntity; import java.math.BigDecimal; import java.util.*; @@ -134,4 +136,20 @@ public class ProductController { .min(Comparator.comparing(ProductOffer::getEffectivePrice)) .orElse(null); } + + @GetMapping("/gunbuilder/products/{id}") + public ResponseEntity getGunbuilderProductById(@PathVariable("id") Integer productId) { + return productRepository.findById(productId) + .map(product -> { + List offers = productOfferRepository.findByProductId(productId); + ProductOffer bestOffer = pickBestOffer(offers); + + BigDecimal price = bestOffer != null ? bestOffer.getEffectivePrice() : null; + String buyUrl = bestOffer != null ? bestOffer.getBuyUrl() : null; + + return ProductMapper.toSummary(product, price, buyUrl); + }) + .map(ResponseEntity::ok) + .orElseGet(() -> ResponseEntity.notFound().build()); + } } \ No newline at end of file diff --git a/src/main/java/group/goforward/battlbuilder/services/GunbuilderProductService.java b/src/main/java/group/goforward/battlbuilder/services/GunbuilderProductService.java index 2838667..acceb91 100644 --- a/src/main/java/group/goforward/battlbuilder/services/GunbuilderProductService.java +++ b/src/main/java/group/goforward/battlbuilder/services/GunbuilderProductService.java @@ -12,6 +12,7 @@ import group.goforward.battlbuilder.model.ImportStatus; import java.util.HashMap; import java.util.Map; import java.util.List; +import java.util.Optional; @Service @@ -132,6 +133,44 @@ public class GunbuilderProductService { return listGunbuilderProducts(platform, partRoles); } + public Optional getGunbuilderProductById(String id) { + if (id == null || id.isBlank()) { + return Optional.empty(); + } + + Integer numericId; + try { + numericId = Integer.parseInt(id); + } catch (NumberFormatException ex) { + return Optional.empty(); + } + + return productRepository.findById(numericId) + .map(p -> { + String platform = p.getPlatform(); + + PartCategory cat = partCategoryResolverService + .resolveForPlatformAndPartRole(platform, p.getPartRole()) + .orElse(null); + + String categorySlug = (cat != null) ? cat.getSlug() : "unmapped"; + String categoryGroup = (cat != null) ? cat.getGroupName() : "Unmapped"; + + return new GunbuilderProductDto( + p.getId(), + p.getName(), + p.getBrand().getName(), + platform, + p.getPartRole(), + p.getBestOfferPrice(), + p.getMainImageUrl(), + p.getBestOfferBuyUrl(), + categorySlug, + categoryGroup + ); + }); + } + /** * Tiny helper used ONLY by /test-products-db to prove DB wiring. */ diff --git a/src/main/java/group/goforward/battlbuilder/web/dto/ProductDto.java b/src/main/java/group/goforward/battlbuilder/web/dto/ProductDto.java new file mode 100644 index 0000000..1539b81 --- /dev/null +++ b/src/main/java/group/goforward/battlbuilder/web/dto/ProductDto.java @@ -0,0 +1,23 @@ +// src/main/java/com/ballistic/gunbuilder/api/dto/GunbuilderProductDto.java +package group.goforward.battlbuilder.web.dto; + +import java.math.BigDecimal; + +public class ProductDto { + private String id; + private String name; + private String brand; + private String platform; + private String partRole; + private BigDecimal price; + private String imageUrl; + private String buyUrl; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } +} \ No newline at end of file diff --git a/src/main/java/group/goforward/battlbuilder/web/dto/ProductSummaryDto.java b/src/main/java/group/goforward/battlbuilder/web/dto/ProductSummaryDto.java index 9b10d82..5cbf0ba 100644 --- a/src/main/java/group/goforward/battlbuilder/web/dto/ProductSummaryDto.java +++ b/src/main/java/group/goforward/battlbuilder/web/dto/ProductSummaryDto.java @@ -12,6 +12,8 @@ public class ProductSummaryDto { private String categoryKey; private BigDecimal price; private String buyUrl; + private String imageUrl; + public String getId() { return id; @@ -76,4 +78,8 @@ public class ProductSummaryDto { public void setBuyUrl(String buyUrl) { this.buyUrl = buyUrl; } + + public String getImageUrl() { return imageUrl; } + + public void setImageUrl(String imageUrl) { this.imageUrl = imageUrl; } } \ No newline at end of file diff --git a/src/main/java/group/goforward/battlbuilder/web/mapper/ProductMapper.java b/src/main/java/group/goforward/battlbuilder/web/mapper/ProductMapper.java index d614bc6..308b40a 100644 --- a/src/main/java/group/goforward/battlbuilder/web/mapper/ProductMapper.java +++ b/src/main/java/group/goforward/battlbuilder/web/mapper/ProductMapper.java @@ -25,6 +25,10 @@ public class ProductMapper { dto.setPrice(price); dto.setBuyUrl(buyUrl); + // product image + dto.setImageUrl(product.getMainImageUrl()); + + return dto; } } \ No newline at end of file