diff --git a/build.gradle b/build.gradle index 47962f8..7a7cf39 100644 --- a/build.gradle +++ b/build.gradle @@ -42,6 +42,7 @@ dependencies { compileOnly 'org.projectlombok:lombok' // https://mvnrepository.com/artifact/com.google.code.findbugs/jsr305 implementation 'com.google.code.findbugs:jsr305:3.0.2' + implementation 'com.opencsv:opencsv:5.12.0' annotationProcessor 'org.projectlombok:lombok' // Email & SMS diff --git a/src/main/java/com/nakamas/hatfieldbackend/HatfieldBackendApplication.java b/src/main/java/com/nakamas/hatfieldbackend/HatfieldBackendApplication.java index 835b231..08ccfae 100644 --- a/src/main/java/com/nakamas/hatfieldbackend/HatfieldBackendApplication.java +++ b/src/main/java/com/nakamas/hatfieldbackend/HatfieldBackendApplication.java @@ -2,12 +2,14 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cache.annotation.EnableCaching; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableAsync @EnableScheduling +@EnableCaching public class HatfieldBackendApplication { public static void main(String[] args) { diff --git a/src/main/java/com/nakamas/hatfieldbackend/controllers/PricingController.java b/src/main/java/com/nakamas/hatfieldbackend/controllers/PricingController.java new file mode 100644 index 0000000..82102f4 --- /dev/null +++ b/src/main/java/com/nakamas/hatfieldbackend/controllers/PricingController.java @@ -0,0 +1,73 @@ +package com.nakamas.hatfieldbackend.controllers; + +import com.nakamas.hatfieldbackend.models.entities.prices.Pricing; +import com.nakamas.hatfieldbackend.models.views.incoming.PricingView; +import com.nakamas.hatfieldbackend.models.views.outgoing.PricingEvaluation; +import com.nakamas.hatfieldbackend.services.PricingService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/price") +public class PricingController { + private final PricingService pricingService; + + @GetMapping("/evaluate") + public PricingEvaluation evaluate( + @RequestParam String deviceType, + @RequestParam String brand, + @RequestParam String model, + @RequestParam String issue) { + return pricingService.evaluate(deviceType, brand, model, issue); + } + + @GetMapping("/worker/pricings") + public List getAllPricings() { + return pricingService.getAllPricings(); + } + @GetMapping("/worker/pricings/filter") + public List getPricingsWithFilters( + @RequestParam(required = false) String deviceType, + @RequestParam(required = false) String brand, + @RequestParam(required = false) String model) { + return pricingService.getPricingsWithFilters(deviceType, brand, model); + } + @PostMapping("/worker/pricings") + public Pricing createPricing(@RequestBody PricingView pricing) { + + return pricingService.save(pricing); + } + + @PutMapping("/worker/pricings/{id}") + public Pricing updatePricing(@PathVariable Long id, @RequestBody PricingView pricing) { + return pricingService.save(pricing, id); + } + + @DeleteMapping("/worker/pricings/{id}") + public void deletePricing(@PathVariable Long id) { + pricingService.delete(id); + } + @GetMapping("/worker/pricings/csv") + public ResponseEntity downloadCsv() { + List pricings = pricingService.getAllPricings(); + byte[] csvBytes = pricingService.exportToCsv(pricings); + + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=pricings.csv") + .contentType(MediaType.parseMediaType("text/csv")) + .body(csvBytes); + } + + @PostMapping("/worker/pricings/csv") + public ResponseEntity uploadCsv(@RequestParam("file") MultipartFile file) { + pricingService.importFromCsv(file); + return ResponseEntity.ok().build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/nakamas/hatfieldbackend/controllers/PublicController.java b/src/main/java/com/nakamas/hatfieldbackend/controllers/PublicController.java index 3ffd5cb..5f08bc2 100644 --- a/src/main/java/com/nakamas/hatfieldbackend/controllers/PublicController.java +++ b/src/main/java/com/nakamas/hatfieldbackend/controllers/PublicController.java @@ -2,16 +2,18 @@ import com.nakamas.hatfieldbackend.config.exception.CustomException; import com.nakamas.hatfieldbackend.models.views.outgoing.ResponseMessage; +import com.nakamas.hatfieldbackend.models.views.outgoing.inventory.BrandView; +import com.nakamas.hatfieldbackend.models.views.outgoing.shop.ShopView; +import com.nakamas.hatfieldbackend.services.InventoryItemService; +import com.nakamas.hatfieldbackend.services.ShopService; import com.nakamas.hatfieldbackend.services.UserService; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.util.HashMap; +import java.util.List; import java.util.Map; @RestController @@ -19,6 +21,8 @@ @RequestMapping("api/public") public class PublicController { private final UserService userService; + private final ShopService shopService; + private final InventoryItemService inventoryItemService; private final Map requestMap = new HashMap<>(); @PostMapping("forgot-password") @@ -28,6 +32,15 @@ public ResponseMessage editPassword(@RequestParam String username, HttpServletRe requestMap.put(request.getRemoteAddr(), requestCount + 1); return responseMessage; } +//todo: caches for /shop and /brands as they could be called without a profile. + @GetMapping("/shop") + public ShopView getShopPublicData(@RequestParam(name = "shopName") String name){ + return shopService.getShopByName(name); + } + @GetMapping("/brands") + public List getBrandsForShop(){ + return inventoryItemService.getAllBrands(); + } private int limitUserRequestsByIp(HttpServletRequest request) { int MAX_REQUESTS_PER_HOUR = 2; diff --git a/src/main/java/com/nakamas/hatfieldbackend/models/entities/prices/Pricing.java b/src/main/java/com/nakamas/hatfieldbackend/models/entities/prices/Pricing.java new file mode 100644 index 0000000..1cbf27c --- /dev/null +++ b/src/main/java/com/nakamas/hatfieldbackend/models/entities/prices/Pricing.java @@ -0,0 +1,38 @@ +package com.nakamas.hatfieldbackend.models.entities.prices; + +import com.nakamas.hatfieldbackend.models.entities.ticket.Brand; +import com.nakamas.hatfieldbackend.models.entities.ticket.Model; +import com.nakamas.hatfieldbackend.models.views.incoming.PricingView; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.math.BigDecimal; + +@Getter +@Setter +@Entity +@Table(name = "pricings") +@NoArgsConstructor +public class Pricing { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String deviceType; + private Long brandId; + private Long modelId; + private String issue; + private BigDecimal price; + private BigDecimal originalPrice; + + public Pricing(PricingView view, Brand brand, Model modelId) { + this.deviceType = view.deviceType(); + this.brandId = brand.getId(); + this.modelId = modelId.getId(); + this.issue = view.issue(); + this.price = view.price(); + this.originalPrice = view.originalPrice(); + } +} diff --git a/src/main/java/com/nakamas/hatfieldbackend/models/entities/shop/ShopPageTemplates.java b/src/main/java/com/nakamas/hatfieldbackend/models/entities/shop/ShopPageTemplates.java index e936abe..3b81355 100644 --- a/src/main/java/com/nakamas/hatfieldbackend/models/entities/shop/ShopPageTemplates.java +++ b/src/main/java/com/nakamas/hatfieldbackend/models/entities/shop/ShopPageTemplates.java @@ -13,21 +13,29 @@ @AllArgsConstructor @Embeddable public class ShopPageTemplates { + public static final String WELWYNHATFIELD = "WELWYNHATFIELD"; + @Column() + private String name; + @Column(columnDefinition = "text") private String aboutPage; public ShopPageTemplates() { + this.name = WELWYNHATFIELD; this.aboutPage = "# About us"; } public ShopPageTemplates(ShopPageTemplatesView view) { + this(); if (view != null && view.getAboutPage() != null && view.getAboutPage().isBlank()) { + this.name = view.getTemplateName(); this.aboutPage = view.getAboutPage(); - } else this.aboutPage = "# About us"; + } } public void update(ShopPageTemplatesView view) { + if (view.getTemplateName()!=null) this.name = view.getTemplateName(); if (view.getAboutPage() != null) this.aboutPage = view.getAboutPage(); } } diff --git a/src/main/java/com/nakamas/hatfieldbackend/models/views/incoming/PricingView.java b/src/main/java/com/nakamas/hatfieldbackend/models/views/incoming/PricingView.java new file mode 100644 index 0000000..474d602 --- /dev/null +++ b/src/main/java/com/nakamas/hatfieldbackend/models/views/incoming/PricingView.java @@ -0,0 +1,19 @@ +package com.nakamas.hatfieldbackend.models.views.incoming; + +import com.nakamas.hatfieldbackend.models.entities.prices.Pricing; + +import java.math.BigDecimal; + +public record PricingView( + Long id, + String deviceType, + String brand, + String model, + String issue, + BigDecimal price, + BigDecimal originalPrice) { + + public PricingView(Pricing p, String brand, String model){ + this(p.getId(), p.getDeviceType(), brand, model, p.getIssue(), p.getPrice(), p.getOriginalPrice()); + } +} diff --git a/src/main/java/com/nakamas/hatfieldbackend/models/views/incoming/ShopPageTemplatesView.java b/src/main/java/com/nakamas/hatfieldbackend/models/views/incoming/ShopPageTemplatesView.java index f8d5386..b384a26 100644 --- a/src/main/java/com/nakamas/hatfieldbackend/models/views/incoming/ShopPageTemplatesView.java +++ b/src/main/java/com/nakamas/hatfieldbackend/models/views/incoming/ShopPageTemplatesView.java @@ -15,9 +15,10 @@ public class ShopPageTemplatesView { @Column(columnDefinition = "text") private String aboutPage; + private String templateName; public ShopPageTemplatesView(ShopPageTemplates templates) { - this(templates != null ? templates.getAboutPage() : ""); + this(templates != null ? templates.getAboutPage() : "", ShopPageTemplates.WELWYNHATFIELD); } public void fillTemplates(Shop shop) { @@ -31,4 +32,11 @@ public String getAboutPage() { return aboutPage; } + public String getTemplateName() { + return templateName; + } + + public void setTemplateName(String templateName) { + this.templateName = templateName; + } } diff --git a/src/main/java/com/nakamas/hatfieldbackend/models/views/outgoing/PricingEvaluation.java b/src/main/java/com/nakamas/hatfieldbackend/models/views/outgoing/PricingEvaluation.java new file mode 100644 index 0000000..96fd97e --- /dev/null +++ b/src/main/java/com/nakamas/hatfieldbackend/models/views/outgoing/PricingEvaluation.java @@ -0,0 +1,12 @@ +package com.nakamas.hatfieldbackend.models.views.outgoing; + +import java.math.BigDecimal; + +public record PricingEvaluation( + BigDecimal price, + BigDecimal originalPrice, + boolean priceExists, + String action +) { + +} \ No newline at end of file diff --git a/src/main/java/com/nakamas/hatfieldbackend/repositories/BrandRepository.java b/src/main/java/com/nakamas/hatfieldbackend/repositories/BrandRepository.java index 7a6e78a..aa06d3e 100644 --- a/src/main/java/com/nakamas/hatfieldbackend/repositories/BrandRepository.java +++ b/src/main/java/com/nakamas/hatfieldbackend/repositories/BrandRepository.java @@ -14,5 +14,5 @@ public interface BrandRepository extends JpaRepository { List findAllBrands(); @Query("from Brand b where LOWER(b.brand) = LOWER(?1)") - Brand findByName(String brandValue); + List findByName(String brandValue); } diff --git a/src/main/java/com/nakamas/hatfieldbackend/repositories/ModelRepository.java b/src/main/java/com/nakamas/hatfieldbackend/repositories/ModelRepository.java index d0c2bf7..6ff0e54 100644 --- a/src/main/java/com/nakamas/hatfieldbackend/repositories/ModelRepository.java +++ b/src/main/java/com/nakamas/hatfieldbackend/repositories/ModelRepository.java @@ -17,5 +17,5 @@ public interface ModelRepository extends JpaRepository { @Query("select m " + "from Model m " + "where LOWER(m.model) like LOWER(?1) and m.brandId = ?2") - Model findByName(String name, Long brandId); + List findByName(String name, Long brandId); } diff --git a/src/main/java/com/nakamas/hatfieldbackend/repositories/PricingRepository.java b/src/main/java/com/nakamas/hatfieldbackend/repositories/PricingRepository.java new file mode 100644 index 0000000..bd721ea --- /dev/null +++ b/src/main/java/com/nakamas/hatfieldbackend/repositories/PricingRepository.java @@ -0,0 +1,43 @@ +package com.nakamas.hatfieldbackend.repositories; + +import com.nakamas.hatfieldbackend.models.entities.prices.Pricing; +import com.nakamas.hatfieldbackend.models.views.incoming.PricingView; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.List; +import java.util.Optional; + +public interface PricingRepository extends JpaRepository { + @Query(""" + from Pricing p + where p.deviceType=?1 and + p.brandId=?2 and + p.modelId=?3 and + p.issue=?4 + """) + Optional findByDeviceTypeAndBrandIdAndModelAndIssue(String deviceType, Long brandId, Long modelId, String issue); + + @Query(""" + select new com.nakamas.hatfieldbackend.models.views.incoming.PricingView(p, b.brand, m.model) + from Pricing p + join Brand b on b.id = p.brandId + join Model m on m.id = p.modelId + """) + List findAllPricingViews(); + + @Query(""" + select new com.nakamas.hatfieldbackend.models.views.incoming.PricingView(p, b.brand, m.model) + from Pricing p + join Brand b on b.id = p.brandId + join Model m on m.id = p.modelId + where (:deviceType is null or p.deviceType = :deviceType) + and (:brand is null or b.brand = :brand) + and (:model is null or m.model = :model) + """) + List findAllWithFilters( + @Param("deviceType") String deviceType, + @Param("brand") String brand, + @Param("model") String model); +} \ No newline at end of file diff --git a/src/main/java/com/nakamas/hatfieldbackend/services/InventoryItemService.java b/src/main/java/com/nakamas/hatfieldbackend/services/InventoryItemService.java index dd608fb..6dc50d6 100644 --- a/src/main/java/com/nakamas/hatfieldbackend/services/InventoryItemService.java +++ b/src/main/java/com/nakamas/hatfieldbackend/services/InventoryItemService.java @@ -19,6 +19,7 @@ import com.nakamas.hatfieldbackend.repositories.*; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; @@ -30,6 +31,7 @@ import java.util.Optional; import java.util.stream.Collectors; +@Slf4j @Service @RequiredArgsConstructor public class InventoryItemService { @@ -46,7 +48,7 @@ public class InventoryItemService { public InventoryItem createInventoryItem(CreateInventoryItem inventoryItem) { Brand brand = getOrCreateBrand(inventoryItem.brandId(), inventoryItem.brand()); Model model = getOrCreateModel(inventoryItem.modelId(), inventoryItem.model(), brand); - if (brand !=null && !brand.getModels().contains(model)) brand.getModels().add(model); + if (brand != null && !brand.getModels().contains(model)) brand.getModels().add(model); Optional category = Optional.empty(); if (inventoryItem.categoryId() != null) { category = categoryRepository.findById(inventoryItem.categoryId()); @@ -163,11 +165,14 @@ public Model getOrCreateModel(Long modelId, String modelValue, Brand brand) { public Model getOrCreateModel(String modelValue, Brand brand) { if (modelValue == null || modelValue.isBlank() || brand == null) return null; Long brandId = brand.getId(); - Model existingByName = modelRepository.findByName(modelValue, brandId); - if (existingByName != null) { - if (brand.getModels().stream().noneMatch((model)-> Objects.equals(model.getId(), existingByName.getId()))) - brand.getModels().add(new Model(existingByName.getModel(), brandId)); - return existingByName; + List existingByName = modelRepository.findByName(modelValue, brandId); + if (!existingByName.isEmpty()) { + if (existingByName.size() > 1) + log.warn("Duplicate models " + existingByName.stream().map(e -> "{%s,%s}".formatted(e.getId(), e.getModel())).collect(Collectors.joining(", "))); + Model existing = existingByName.get(0); + if (brand.getModels().stream().noneMatch((model) -> Objects.equals(model.getId(), existing.getId()))) + brand.getModels().add(new Model(existing.getModel(), brandId)); + return existing; } Model save = modelRepository.save(new Model(modelValue, brandId)); brand.getModels().add(save); @@ -182,8 +187,10 @@ public Brand getOrCreateBrand(Long brandId, String brandValue) { public Brand getOrCreateBrand(String brandValue) { if (brandValue == null || brandValue.isBlank()) return null; - Brand existingByName = brandRepository.findByName(brandValue); - if (existingByName != null) return existingByName; + List existingByName = brandRepository.findByName(brandValue); + if (existingByName.size() > 1) + log.warn("Duplicate models " + existingByName.stream().map(e -> "{%s,%s}".formatted(e.getId(), e.getBrand())).collect(Collectors.joining(", "))); + if (!existingByName.isEmpty()) return existingByName.get(0); return brandRepository.save(new Brand(brandValue)); } diff --git a/src/main/java/com/nakamas/hatfieldbackend/services/PricingService.java b/src/main/java/com/nakamas/hatfieldbackend/services/PricingService.java new file mode 100644 index 0000000..b321cea --- /dev/null +++ b/src/main/java/com/nakamas/hatfieldbackend/services/PricingService.java @@ -0,0 +1,147 @@ +package com.nakamas.hatfieldbackend.services; + +import com.nakamas.hatfieldbackend.models.entities.prices.Pricing; +import com.nakamas.hatfieldbackend.models.entities.ticket.Brand; +import com.nakamas.hatfieldbackend.models.entities.ticket.Model; +import com.nakamas.hatfieldbackend.models.views.incoming.PricingView; +import com.nakamas.hatfieldbackend.models.views.outgoing.PricingEvaluation; +import com.nakamas.hatfieldbackend.models.views.outgoing.inventory.BrandView; +import com.nakamas.hatfieldbackend.models.views.outgoing.inventory.ItemPropertyView; +import com.nakamas.hatfieldbackend.repositories.PricingRepository; +import com.opencsv.CSVWriter; +import com.opencsv.bean.CsvToBean; +import com.opencsv.bean.CsvToBeanBuilder; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.math.BigDecimal; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +@Service +public class PricingService { + private final PricingRepository pricingRepository; + private final InventoryItemService inventoryItemService; + + public PricingService(PricingRepository pricingRepository, InventoryItemService inventoryItemService) { + this.pricingRepository = pricingRepository; + this.inventoryItemService = inventoryItemService; + } + + @Cacheable(value = "pricingEvaluation", key = "#deviceType + '_' + #brandId + '_' + #model + '_' + #issue") + public PricingEvaluation evaluate(String deviceType, String brand, String model, String issue) { + List brands = inventoryItemService.getAllBrands(); + Optional fromDb = brands.stream().filter(b -> b.value().equals(brand)).findAny(); + if (fromDb.isEmpty()) { + return new PricingEvaluation(BigDecimal.ZERO, BigDecimal.ZERO, false, "CALL"); + } + Optional modelFromDb = fromDb.get().models().stream().filter((m) -> m.value().equals(model)).findAny(); + if (modelFromDb.isEmpty()) { + return new PricingEvaluation(BigDecimal.ZERO, BigDecimal.ZERO, false, "CALL"); + } + Optional opt = pricingRepository.findByDeviceTypeAndBrandIdAndModelAndIssue( + deviceType, fromDb.get().id(), modelFromDb.get().id(), issue); + if (opt.isPresent()) { + Pricing p = opt.get(); + return new PricingEvaluation(p.getPrice(), p.getOriginalPrice(), true, "VISIT_SHOP"); + } + return new PricingEvaluation(BigDecimal.ZERO, BigDecimal.ZERO, false, "CALL"); + } + + public List getAllPricings() { + return pricingRepository.findAllPricingViews(); + } + public List getPricingsWithFilters(String deviceType, String brand, String model) { + return pricingRepository.findAllWithFilters(deviceType, brand, model); + } + + public Pricing save(PricingView view) { + Pricing pricing = toEntity(view); + return save(pricing); + } + + public Pricing save(PricingView view, Long id) { + Pricing pricing = toEntity(view); + pricing.setId(id); + return save(pricing); + } + + private Pricing toEntity(PricingView view) { + Brand brand = inventoryItemService.getOrCreateBrand(view.brand()); + Model model = inventoryItemService.getOrCreateModel(view.model(), brand); + return new Pricing(view, brand, model); + } + + @CacheEvict(value = "pricingEvaluation", allEntries = true) + public Pricing save(Pricing pricing) { + if (pricing.getId() == null) { + Optional fromDb = pricingRepository.findByDeviceTypeAndBrandIdAndModelAndIssue( + pricing.getDeviceType(), pricing.getBrandId(), pricing.getModelId(), pricing.getIssue()); + fromDb.ifPresent((p) -> pricing.setId(p.getId())); + } + return pricingRepository.save(pricing); + } + + @CacheEvict(value = "pricingEvaluation", allEntries = true) + public void delete(Long id) { + pricingRepository.deleteById(id); + } + + // CSV Export + public byte[] exportToCsv(List pricings) { + try (StringWriter writer = new StringWriter(); + CSVWriter csvWriter = new CSVWriter(writer, + CSVWriter.DEFAULT_SEPARATOR, + CSVWriter.NO_QUOTE_CHARACTER, + CSVWriter.DEFAULT_ESCAPE_CHARACTER, + CSVWriter.DEFAULT_LINE_END)) { + + // Header + csvWriter.writeNext(new String[]{"deviceType", "brand", "model", "issue", "price", "originalPrice"}); + + // Data + for (PricingView p : pricings) { + csvWriter.writeNext(new String[]{ + p.deviceType(), + p.brand(), + p.model(), + p.issue(), + p.price().toString(), + p.originalPrice() != null ? p.originalPrice().toString() : "" + }); + } + return writer.toString().getBytes(StandardCharsets.UTF_8); + } catch (IOException e) { + throw new RuntimeException("Failed to export CSV", e); + } + } + + // CSV Import + @CacheEvict(value = "pricingEvaluation", allEntries = true) + public void importFromCsv(MultipartFile file) { + if (file.isEmpty()) { + throw new IllegalArgumentException("Uploaded file is empty"); + } + + try (Reader reader = new BufferedReader(new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8))) { + CsvToBean csvToBean = new CsvToBeanBuilder(reader) + .withType(PricingView.class) + .withIgnoreLeadingWhiteSpace(true) + .withSeparator(',') + .build(); + + List imported = csvToBean.parse(); + + List collect = imported.stream().map(this::toEntity).collect(Collectors.toList()); + + pricingRepository.saveAll(collect); + } catch (Exception e) { + throw new RuntimeException("Failed to import CSV: " + e.getMessage(), e); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/nakamas/hatfieldbackend/services/ShopService.java b/src/main/java/com/nakamas/hatfieldbackend/services/ShopService.java index c5d3e51..9b7c75a 100644 --- a/src/main/java/com/nakamas/hatfieldbackend/services/ShopService.java +++ b/src/main/java/com/nakamas/hatfieldbackend/services/ShopService.java @@ -9,6 +9,7 @@ import com.nakamas.hatfieldbackend.models.views.outgoing.shop.ShopSettingsView; import com.nakamas.hatfieldbackend.models.views.outgoing.shop.ShopView; import com.nakamas.hatfieldbackend.models.views.outgoing.shop.WorkerShopView; +import com.nakamas.hatfieldbackend.repositories.BrandRepository; import com.nakamas.hatfieldbackend.repositories.ShopRepository; import jakarta.servlet.http.HttpServletResponse; import jakarta.transaction.Transactional; @@ -23,6 +24,7 @@ @RequiredArgsConstructor public class ShopService { private final ShopRepository shopRepository; + private final BrandRepository brandRepository; private final LoggerService loggerService; private final PhotoService photoService; @@ -81,4 +83,8 @@ public void updateShopImage(Long shopId, MultipartFile image) { loggerService.createLog(new Log(LogType.UPDATED_SHOP), shop.getShopName(), "The shop photo was changed."); shopRepository.save(shop); } + + public ShopView getShopByName(String name) { + return new ShopView(shopRepository.findByName(name)); + } }