diff --git a/backend/src/main/java/com/petshop/backend/controller/DropdownController.java b/backend/src/main/java/com/petshop/backend/controller/DropdownController.java new file mode 100644 index 00000000..73ba3cba --- /dev/null +++ b/backend/src/main/java/com/petshop/backend/controller/DropdownController.java @@ -0,0 +1,91 @@ +package com.petshop.backend.controller; + +import com.petshop.backend.dto.common.DropdownOption; +import com.petshop.backend.repository.*; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.stream.Collectors; + +@RestController +@RequestMapping("/api/v1/dropdowns") +@RequiredArgsConstructor +public class DropdownController { + + private final PetRepository petRepository; + private final CustomerRepository customerRepository; + private final ServiceRepository serviceRepository; + private final ProductRepository productRepository; + private final CategoryRepository categoryRepository; + private final StoreRepository storeRepository; + private final SupplierRepository supplierRepository; + + @GetMapping("/pets") + public ResponseEntity> getPets() { + return ResponseEntity.ok( + petRepository.findAll().stream() + .map(p -> new DropdownOption(p.getId(), p.getPetName())) + .collect(Collectors.toList()) + ); + } + + @GetMapping("/customers") + public ResponseEntity> getCustomers() { + return ResponseEntity.ok( + customerRepository.findAll().stream() + .map(c -> new DropdownOption(c.getId(), c.getCustomerName())) + .collect(Collectors.toList()) + ); + } + + @GetMapping("/services") + public ResponseEntity> getServices() { + return ResponseEntity.ok( + serviceRepository.findAll().stream() + .map(s -> new DropdownOption(s.getId(), s.getServiceName())) + .collect(Collectors.toList()) + ); + } + + @GetMapping("/products") + public ResponseEntity> getProducts() { + return ResponseEntity.ok( + productRepository.findAll().stream() + .map(p -> new DropdownOption(p.getId(), p.getProductName())) + .collect(Collectors.toList()) + ); + } + + @GetMapping("/categories") + public ResponseEntity> getCategories() { + return ResponseEntity.ok( + categoryRepository.findAll().stream() + .map(c -> new DropdownOption(c.getId(), c.getCategoryName())) + .collect(Collectors.toList()) + ); + } + + @GetMapping("/stores") + public ResponseEntity> getStores() { + return ResponseEntity.ok( + storeRepository.findAll().stream() + .map(s -> new DropdownOption(s.getId(), s.getStoreName())) + .collect(Collectors.toList()) + ); + } + + @GetMapping("/suppliers") + @PreAuthorize("hasRole('ADMIN')") + public ResponseEntity> getSuppliers() { + return ResponseEntity.ok( + supplierRepository.findAll().stream() + .map(s -> new DropdownOption(s.getId(), s.getSupplierName())) + .collect(Collectors.toList()) + ); + } +} diff --git a/backend/src/main/java/com/petshop/backend/controller/InventoryController.java b/backend/src/main/java/com/petshop/backend/controller/InventoryController.java new file mode 100644 index 00000000..61ac8df2 --- /dev/null +++ b/backend/src/main/java/com/petshop/backend/controller/InventoryController.java @@ -0,0 +1,57 @@ +package com.petshop.backend.controller; + +import com.petshop.backend.dto.common.BulkDeleteRequest; +import com.petshop.backend.dto.inventory.InventoryRequest; +import com.petshop.backend.dto.inventory.InventoryResponse; +import com.petshop.backend.service.InventoryService; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/api/v1/inventory") +@RequiredArgsConstructor +@PreAuthorize("hasRole('ADMIN')") +public class InventoryController { + + private final InventoryService inventoryService; + + @GetMapping + public ResponseEntity> getAllInventory(Pageable pageable) { + return ResponseEntity.ok(inventoryService.getAllInventory(pageable)); + } + + @GetMapping("/{id}") + public ResponseEntity getInventoryById(@PathVariable Long id) { + return ResponseEntity.ok(inventoryService.getInventoryById(id)); + } + + @PostMapping + public ResponseEntity createInventory(@Valid @RequestBody InventoryRequest request) { + return ResponseEntity.status(HttpStatus.CREATED).body(inventoryService.createInventory(request)); + } + + @PutMapping("/{id}") + public ResponseEntity updateInventory( + @PathVariable Long id, + @Valid @RequestBody InventoryRequest request) { + return ResponseEntity.ok(inventoryService.updateInventory(id, request)); + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteInventory(@PathVariable Long id) { + inventoryService.deleteInventory(id); + return ResponseEntity.noContent().build(); + } + + @PostMapping("/bulk-delete") + public ResponseEntity bulkDeleteInventory(@Valid @RequestBody BulkDeleteRequest request) { + inventoryService.bulkDeleteInventory(request); + return ResponseEntity.noContent().build(); + } +} diff --git a/backend/src/main/java/com/petshop/backend/controller/ProductSupplierController.java b/backend/src/main/java/com/petshop/backend/controller/ProductSupplierController.java new file mode 100644 index 00000000..20965a3d --- /dev/null +++ b/backend/src/main/java/com/petshop/backend/controller/ProductSupplierController.java @@ -0,0 +1,62 @@ +package com.petshop.backend.controller; + +import com.petshop.backend.dto.productsupplier.BulkDeleteProductSupplierRequest; +import com.petshop.backend.dto.productsupplier.ProductSupplierRequest; +import com.petshop.backend.dto.productsupplier.ProductSupplierResponse; +import com.petshop.backend.service.ProductSupplierService; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/api/v1/product-suppliers") +@RequiredArgsConstructor +@PreAuthorize("hasRole('ADMIN')") +public class ProductSupplierController { + + private final ProductSupplierService productSupplierService; + + @GetMapping + public ResponseEntity> getAllProductSuppliers(Pageable pageable) { + return ResponseEntity.ok(productSupplierService.getAllProductSuppliers(pageable)); + } + + @GetMapping("/{productId}/{supplierId}") + public ResponseEntity getProductSupplierById( + @PathVariable Long productId, + @PathVariable Long supplierId) { + return ResponseEntity.ok(productSupplierService.getProductSupplierById(productId, supplierId)); + } + + @PostMapping + public ResponseEntity createProductSupplier(@Valid @RequestBody ProductSupplierRequest request) { + return ResponseEntity.status(HttpStatus.CREATED).body(productSupplierService.createProductSupplier(request)); + } + + @PutMapping("/{productId}/{supplierId}") + public ResponseEntity updateProductSupplier( + @PathVariable Long productId, + @PathVariable Long supplierId, + @Valid @RequestBody ProductSupplierRequest request) { + return ResponseEntity.ok(productSupplierService.updateProductSupplier(productId, supplierId, request)); + } + + @DeleteMapping("/{productId}/{supplierId}") + public ResponseEntity deleteProductSupplier( + @PathVariable Long productId, + @PathVariable Long supplierId) { + productSupplierService.deleteProductSupplier(productId, supplierId); + return ResponseEntity.noContent().build(); + } + + @PostMapping("/bulk-delete") + public ResponseEntity bulkDeleteProductSuppliers(@Valid @RequestBody BulkDeleteProductSupplierRequest request) { + productSupplierService.bulkDeleteProductSuppliers(request); + return ResponseEntity.noContent().build(); + } +} diff --git a/backend/src/main/java/com/petshop/backend/controller/PurchaseOrderController.java b/backend/src/main/java/com/petshop/backend/controller/PurchaseOrderController.java new file mode 100644 index 00000000..fb0a8077 --- /dev/null +++ b/backend/src/main/java/com/petshop/backend/controller/PurchaseOrderController.java @@ -0,0 +1,29 @@ +package com.petshop.backend.controller; + +import com.petshop.backend.dto.purchaseorder.PurchaseOrderResponse; +import com.petshop.backend.service.PurchaseOrderService; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/api/v1/purchase-orders") +@RequiredArgsConstructor +@PreAuthorize("hasRole('ADMIN')") +public class PurchaseOrderController { + + private final PurchaseOrderService purchaseOrderService; + + @GetMapping + public ResponseEntity> getAllPurchaseOrders(Pageable pageable) { + return ResponseEntity.ok(purchaseOrderService.getAllPurchaseOrders(pageable)); + } + + @GetMapping("/{id}") + public ResponseEntity getPurchaseOrderById(@PathVariable Long id) { + return ResponseEntity.ok(purchaseOrderService.getPurchaseOrderById(id)); + } +} diff --git a/backend/src/main/java/com/petshop/backend/controller/SupplierController.java b/backend/src/main/java/com/petshop/backend/controller/SupplierController.java new file mode 100644 index 00000000..ebd4e68d --- /dev/null +++ b/backend/src/main/java/com/petshop/backend/controller/SupplierController.java @@ -0,0 +1,59 @@ +package com.petshop.backend.controller; + +import com.petshop.backend.dto.common.BulkDeleteRequest; +import com.petshop.backend.dto.supplier.SupplierRequest; +import com.petshop.backend.dto.supplier.SupplierResponse; +import com.petshop.backend.service.SupplierService; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/api/v1/suppliers") +@RequiredArgsConstructor +@PreAuthorize("hasRole('ADMIN')") +public class SupplierController { + + private final SupplierService supplierService; + + @GetMapping + public ResponseEntity> getAllSuppliers( + @RequestParam(required = false) String q, + Pageable pageable) { + return ResponseEntity.ok(supplierService.getAllSuppliers(q, pageable)); + } + + @GetMapping("/{id}") + public ResponseEntity getSupplierById(@PathVariable Long id) { + return ResponseEntity.ok(supplierService.getSupplierById(id)); + } + + @PostMapping + public ResponseEntity createSupplier(@Valid @RequestBody SupplierRequest request) { + return ResponseEntity.status(HttpStatus.CREATED).body(supplierService.createSupplier(request)); + } + + @PutMapping("/{id}") + public ResponseEntity updateSupplier( + @PathVariable Long id, + @Valid @RequestBody SupplierRequest request) { + return ResponseEntity.ok(supplierService.updateSupplier(id, request)); + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteSupplier(@PathVariable Long id) { + supplierService.deleteSupplier(id); + return ResponseEntity.noContent().build(); + } + + @PostMapping("/bulk-delete") + public ResponseEntity bulkDeleteSuppliers(@Valid @RequestBody BulkDeleteRequest request) { + supplierService.bulkDeleteSuppliers(request); + return ResponseEntity.noContent().build(); + } +} diff --git a/backend/src/main/java/com/petshop/backend/controller/UserController.java b/backend/src/main/java/com/petshop/backend/controller/UserController.java new file mode 100644 index 00000000..c316dbe0 --- /dev/null +++ b/backend/src/main/java/com/petshop/backend/controller/UserController.java @@ -0,0 +1,57 @@ +package com.petshop.backend.controller; + +import com.petshop.backend.dto.common.BulkDeleteRequest; +import com.petshop.backend.dto.user.UserRequest; +import com.petshop.backend.dto.user.UserResponse; +import com.petshop.backend.service.UserService; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/api/v1/users") +@RequiredArgsConstructor +@PreAuthorize("hasRole('ADMIN')") +public class UserController { + + private final UserService userService; + + @GetMapping + public ResponseEntity> getAllUsers(Pageable pageable) { + return ResponseEntity.ok(userService.getAllUsers(pageable)); + } + + @GetMapping("/{id}") + public ResponseEntity getUserById(@PathVariable Long id) { + return ResponseEntity.ok(userService.getUserById(id)); + } + + @PostMapping + public ResponseEntity createUser(@Valid @RequestBody UserRequest request) { + return ResponseEntity.status(HttpStatus.CREATED).body(userService.createUser(request)); + } + + @PutMapping("/{id}") + public ResponseEntity updateUser( + @PathVariable Long id, + @Valid @RequestBody UserRequest request) { + return ResponseEntity.ok(userService.updateUser(id, request)); + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteUser(@PathVariable Long id) { + userService.deleteUser(id); + return ResponseEntity.noContent().build(); + } + + @PostMapping("/bulk-delete") + public ResponseEntity bulkDeleteUsers(@Valid @RequestBody BulkDeleteRequest request) { + userService.bulkDeleteUsers(request); + return ResponseEntity.noContent().build(); + } +} diff --git a/backend/src/main/java/com/petshop/backend/dto/productsupplier/ProductSupplierKey.java b/backend/src/main/java/com/petshop/backend/dto/productsupplier/ProductSupplierKey.java index 191c8575..b86b6980 100644 --- a/backend/src/main/java/com/petshop/backend/dto/productsupplier/ProductSupplierKey.java +++ b/backend/src/main/java/com/petshop/backend/dto/productsupplier/ProductSupplierKey.java @@ -12,7 +12,7 @@ public class ProductSupplierKey { } @Data -class BulkDeleteProductSupplierRequest { +public class BulkDeleteProductSupplierRequest { @NotEmpty(message = "Keys list cannot be empty") private List keys; } diff --git a/backend/src/main/java/com/petshop/backend/dto/purchaseorder/PurchaseOrderResponse.java b/backend/src/main/java/com/petshop/backend/dto/purchaseorder/PurchaseOrderResponse.java index 657816ea..4a67865c 100644 --- a/backend/src/main/java/com/petshop/backend/dto/purchaseorder/PurchaseOrderResponse.java +++ b/backend/src/main/java/com/petshop/backend/dto/purchaseorder/PurchaseOrderResponse.java @@ -29,7 +29,7 @@ public class PurchaseOrderResponse { @Data @NoArgsConstructor @AllArgsConstructor -class PurchaseOrderItemResponse { +public class PurchaseOrderItemResponse { private Long id; private Long productId; private String productName; diff --git a/backend/src/main/java/com/petshop/backend/service/InventoryService.java b/backend/src/main/java/com/petshop/backend/service/InventoryService.java new file mode 100644 index 00000000..0599e255 --- /dev/null +++ b/backend/src/main/java/com/petshop/backend/service/InventoryService.java @@ -0,0 +1,107 @@ +package com.petshop.backend.service; + +import com.petshop.backend.dto.common.BulkDeleteRequest; +import com.petshop.backend.dto.inventory.InventoryRequest; +import com.petshop.backend.dto.inventory.InventoryResponse; +import com.petshop.backend.entity.Inventory; +import com.petshop.backend.entity.Product; +import com.petshop.backend.entity.Store; +import com.petshop.backend.exception.ResourceNotFoundException; +import com.petshop.backend.repository.InventoryRepository; +import com.petshop.backend.repository.ProductRepository; +import com.petshop.backend.repository.StoreRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; + +@Service +@RequiredArgsConstructor +public class InventoryService { + + private final InventoryRepository inventoryRepository; + private final ProductRepository productRepository; + private final StoreRepository storeRepository; + + public Page getAllInventory(Pageable pageable) { + return inventoryRepository.findAll(pageable).map(this::mapToResponse); + } + + public InventoryResponse getInventoryById(Long id) { + Inventory inventory = inventoryRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("Inventory not found with id: " + id)); + return mapToResponse(inventory); + } + + @Transactional + public InventoryResponse createInventory(InventoryRequest request) { + Product product = productRepository.findById(request.getProductId()) + .orElseThrow(() -> new ResourceNotFoundException("Product not found with id: " + request.getProductId())); + + Store store = storeRepository.findById(request.getStoreId()) + .orElseThrow(() -> new ResourceNotFoundException("Store not found with id: " + request.getStoreId())); + + Inventory inventory = new Inventory(); + inventory.setProduct(product); + inventory.setStore(store); + inventory.setQuantity(request.getQuantity()); + inventory.setReorderLevel(request.getReorderLevel()); + inventory.setLastRestocked(LocalDateTime.now()); + + inventory = inventoryRepository.save(inventory); + return mapToResponse(inventory); + } + + @Transactional + public InventoryResponse updateInventory(Long id, InventoryRequest request) { + Inventory inventory = inventoryRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("Inventory not found with id: " + id)); + + Product product = productRepository.findById(request.getProductId()) + .orElseThrow(() -> new ResourceNotFoundException("Product not found with id: " + request.getProductId())); + + Store store = storeRepository.findById(request.getStoreId()) + .orElseThrow(() -> new ResourceNotFoundException("Store not found with id: " + request.getStoreId())); + + inventory.setProduct(product); + inventory.setStore(store); + inventory.setQuantity(request.getQuantity()); + inventory.setReorderLevel(request.getReorderLevel()); + inventory.setLastRestocked(LocalDateTime.now()); + + inventory = inventoryRepository.save(inventory); + return mapToResponse(inventory); + } + + @Transactional + public void deleteInventory(Long id) { + if (!inventoryRepository.existsById(id)) { + throw new ResourceNotFoundException("Inventory not found with id: " + id); + } + inventoryRepository.deleteById(id); + } + + @Transactional + public void bulkDeleteInventory(BulkDeleteRequest request) { + inventoryRepository.deleteAllById(request.getIds()); + } + + private InventoryResponse mapToResponse(Inventory inventory) { + return new InventoryResponse( + inventory.getId(), + inventory.getProduct().getId(), + inventory.getProduct().getProductName(), + inventory.getProduct().getCategory().getCategoryName(), + inventory.getStore().getId(), + inventory.getStore().getStoreName(), + inventory.getQuantity(), + inventory.getReorderLevel(), + inventory.getLastRestocked(), + inventory.getCreatedAt(), + inventory.getUpdatedAt() + ); + } +} diff --git a/backend/src/main/java/com/petshop/backend/service/ProductSupplierService.java b/backend/src/main/java/com/petshop/backend/service/ProductSupplierService.java new file mode 100644 index 00000000..20c0bb66 --- /dev/null +++ b/backend/src/main/java/com/petshop/backend/service/ProductSupplierService.java @@ -0,0 +1,105 @@ +package com.petshop.backend.service; + +import com.petshop.backend.dto.productsupplier.BulkDeleteProductSupplierRequest; +import com.petshop.backend.dto.productsupplier.ProductSupplierRequest; +import com.petshop.backend.dto.productsupplier.ProductSupplierResponse; +import com.petshop.backend.entity.Product; +import com.petshop.backend.entity.ProductSupplier; +import com.petshop.backend.entity.Supplier; +import com.petshop.backend.exception.ResourceNotFoundException; +import com.petshop.backend.repository.ProductRepository; +import com.petshop.backend.repository.ProductSupplierRepository; +import com.petshop.backend.repository.SupplierRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class ProductSupplierService { + + private final ProductSupplierRepository productSupplierRepository; + private final ProductRepository productRepository; + private final SupplierRepository supplierRepository; + + public Page getAllProductSuppliers(Pageable pageable) { + return productSupplierRepository.findAll(pageable).map(this::mapToResponse); + } + + public ProductSupplierResponse getProductSupplierById(Long productId, Long supplierId) { + ProductSupplier.ProductSupplierId id = new ProductSupplier.ProductSupplierId(productId, supplierId); + ProductSupplier productSupplier = productSupplierRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException( + "ProductSupplier not found with productId: " + productId + " and supplierId: " + supplierId)); + return mapToResponse(productSupplier); + } + + @Transactional + public ProductSupplierResponse createProductSupplier(ProductSupplierRequest request) { + Product product = productRepository.findById(request.getProductId()) + .orElseThrow(() -> new ResourceNotFoundException("Product not found with id: " + request.getProductId())); + + Supplier supplier = supplierRepository.findById(request.getSupplierId()) + .orElseThrow(() -> new ResourceNotFoundException("Supplier not found with id: " + request.getSupplierId())); + + ProductSupplier productSupplier = new ProductSupplier(); + productSupplier.setProduct(product); + productSupplier.setSupplier(supplier); + productSupplier.setCostPrice(request.getCostPrice()); + productSupplier.setLeadTimeDays(request.getLeadTimeDays()); + productSupplier.setIsPreferred(request.getIsPreferred()); + + productSupplier = productSupplierRepository.save(productSupplier); + return mapToResponse(productSupplier); + } + + @Transactional + public ProductSupplierResponse updateProductSupplier(Long productId, Long supplierId, ProductSupplierRequest request) { + ProductSupplier.ProductSupplierId id = new ProductSupplier.ProductSupplierId(productId, supplierId); + ProductSupplier productSupplier = productSupplierRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException( + "ProductSupplier not found with productId: " + productId + " and supplierId: " + supplierId)); + + productSupplier.setCostPrice(request.getCostPrice()); + productSupplier.setLeadTimeDays(request.getLeadTimeDays()); + productSupplier.setIsPreferred(request.getIsPreferred()); + + productSupplier = productSupplierRepository.save(productSupplier); + return mapToResponse(productSupplier); + } + + @Transactional + public void deleteProductSupplier(Long productId, Long supplierId) { + ProductSupplier.ProductSupplierId id = new ProductSupplier.ProductSupplierId(productId, supplierId); + if (!productSupplierRepository.existsById(id)) { + throw new ResourceNotFoundException( + "ProductSupplier not found with productId: " + productId + " and supplierId: " + supplierId); + } + productSupplierRepository.deleteById(id); + } + + @Transactional + public void bulkDeleteProductSuppliers(BulkDeleteProductSupplierRequest request) { + request.getKeys().forEach(key -> { + ProductSupplier.ProductSupplierId id = new ProductSupplier.ProductSupplierId( + key.getProductId(), key.getSupplierId()); + productSupplierRepository.deleteById(id); + }); + } + + private ProductSupplierResponse mapToResponse(ProductSupplier productSupplier) { + return new ProductSupplierResponse( + productSupplier.getProduct().getId(), + productSupplier.getProduct().getProductName(), + productSupplier.getSupplier().getId(), + productSupplier.getSupplier().getSupplierName(), + productSupplier.getCostPrice(), + productSupplier.getLeadTimeDays(), + productSupplier.getIsPreferred(), + productSupplier.getCreatedAt(), + productSupplier.getUpdatedAt() + ); + } +} diff --git a/backend/src/main/java/com/petshop/backend/service/PurchaseOrderService.java b/backend/src/main/java/com/petshop/backend/service/PurchaseOrderService.java new file mode 100644 index 00000000..1e9c61f0 --- /dev/null +++ b/backend/src/main/java/com/petshop/backend/service/PurchaseOrderService.java @@ -0,0 +1,63 @@ +package com.petshop.backend.service; + +import com.petshop.backend.dto.purchaseorder.PurchaseOrderItemResponse; +import com.petshop.backend.dto.purchaseorder.PurchaseOrderResponse; +import com.petshop.backend.entity.PurchaseOrder; +import com.petshop.backend.entity.PurchaseOrderItem; +import com.petshop.backend.exception.ResourceNotFoundException; +import com.petshop.backend.repository.PurchaseOrderRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class PurchaseOrderService { + + private final PurchaseOrderRepository purchaseOrderRepository; + + public Page getAllPurchaseOrders(Pageable pageable) { + return purchaseOrderRepository.findAll(pageable).map(this::mapToResponse); + } + + public PurchaseOrderResponse getPurchaseOrderById(Long id) { + PurchaseOrder purchaseOrder = purchaseOrderRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("PurchaseOrder not found with id: " + id)); + return mapToResponse(purchaseOrder); + } + + private PurchaseOrderResponse mapToResponse(PurchaseOrder purchaseOrder) { + List items = purchaseOrder.getItems().stream() + .map(this::mapItemToResponse) + .collect(Collectors.toList()); + + return new PurchaseOrderResponse( + purchaseOrder.getId(), + purchaseOrder.getSupplier().getId(), + purchaseOrder.getSupplier().getSupplierName(), + purchaseOrder.getOrderDate(), + purchaseOrder.getExpectedDelivery(), + purchaseOrder.getStatus().toString(), + purchaseOrder.getTotalAmount(), + purchaseOrder.getNotes(), + items, + purchaseOrder.getCreatedAt(), + purchaseOrder.getUpdatedAt() + ); + } + + private PurchaseOrderItemResponse mapItemToResponse(PurchaseOrderItem item) { + return new PurchaseOrderItemResponse( + item.getId(), + item.getProduct().getId(), + item.getProduct().getProductName(), + item.getQuantity(), + item.getUnitCost(), + item.getSubtotal() + ); + } +} diff --git a/backend/src/main/java/com/petshop/backend/service/SupplierService.java b/backend/src/main/java/com/petshop/backend/service/SupplierService.java new file mode 100644 index 00000000..d86a8c13 --- /dev/null +++ b/backend/src/main/java/com/petshop/backend/service/SupplierService.java @@ -0,0 +1,93 @@ +package com.petshop.backend.service; + +import com.petshop.backend.dto.common.BulkDeleteRequest; +import com.petshop.backend.dto.supplier.SupplierRequest; +import com.petshop.backend.dto.supplier.SupplierResponse; +import com.petshop.backend.entity.Supplier; +import com.petshop.backend.exception.ResourceNotFoundException; +import com.petshop.backend.repository.SupplierRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class SupplierService { + + private final SupplierRepository supplierRepository; + + public Page getAllSuppliers(String query, Pageable pageable) { + Page suppliers; + if (query != null && !query.trim().isEmpty()) { + suppliers = supplierRepository.searchSuppliers(query, pageable); + } else { + suppliers = supplierRepository.findAll(pageable); + } + return suppliers.map(this::mapToResponse); + } + + public SupplierResponse getSupplierById(Long id) { + Supplier supplier = supplierRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("Supplier not found with id: " + id)); + return mapToResponse(supplier); + } + + @Transactional + public SupplierResponse createSupplier(SupplierRequest request) { + Supplier supplier = new Supplier(); + supplier.setSupplierName(request.getSupplierName()); + supplier.setSupplierContact(request.getSupplierContact()); + supplier.setSupplierEmail(request.getSupplierEmail()); + supplier.setSupplierPhone(request.getSupplierPhone()); + supplier.setSupplierAddress(request.getSupplierAddress()); + supplier.setActive(request.getActive()); + + supplier = supplierRepository.save(supplier); + return mapToResponse(supplier); + } + + @Transactional + public SupplierResponse updateSupplier(Long id, SupplierRequest request) { + Supplier supplier = supplierRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("Supplier not found with id: " + id)); + + supplier.setSupplierName(request.getSupplierName()); + supplier.setSupplierContact(request.getSupplierContact()); + supplier.setSupplierEmail(request.getSupplierEmail()); + supplier.setSupplierPhone(request.getSupplierPhone()); + supplier.setSupplierAddress(request.getSupplierAddress()); + supplier.setActive(request.getActive()); + + supplier = supplierRepository.save(supplier); + return mapToResponse(supplier); + } + + @Transactional + public void deleteSupplier(Long id) { + if (!supplierRepository.existsById(id)) { + throw new ResourceNotFoundException("Supplier not found with id: " + id); + } + supplierRepository.deleteById(id); + } + + @Transactional + public void bulkDeleteSuppliers(BulkDeleteRequest request) { + supplierRepository.deleteAllById(request.getIds()); + } + + private SupplierResponse mapToResponse(Supplier supplier) { + return new SupplierResponse( + supplier.getId(), + supplier.getSupplierName(), + supplier.getSupplierContact(), + supplier.getSupplierEmail(), + supplier.getSupplierPhone(), + supplier.getSupplierAddress(), + supplier.getActive(), + supplier.getCreatedAt(), + supplier.getUpdatedAt() + ); + } +} diff --git a/backend/src/main/java/com/petshop/backend/service/UserService.java b/backend/src/main/java/com/petshop/backend/service/UserService.java new file mode 100644 index 00000000..da028f9a --- /dev/null +++ b/backend/src/main/java/com/petshop/backend/service/UserService.java @@ -0,0 +1,90 @@ +package com.petshop.backend.service; + +import com.petshop.backend.dto.common.BulkDeleteRequest; +import com.petshop.backend.dto.user.UserRequest; +import com.petshop.backend.dto.user.UserResponse; +import com.petshop.backend.entity.User; +import com.petshop.backend.exception.ResourceNotFoundException; +import com.petshop.backend.repository.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class UserService { + + private final UserRepository userRepository; + private final PasswordEncoder passwordEncoder; + + public Page getAllUsers(Pageable pageable) { + return userRepository.findAll(pageable).map(this::mapToResponse); + } + + public UserResponse getUserById(Long id) { + User user = userRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("User not found with id: " + id)); + return mapToResponse(user); + } + + @Transactional + public UserResponse createUser(UserRequest request) { + User user = new User(); + user.setUsername(request.getUsername()); + user.setPassword(passwordEncoder.encode(request.getPassword())); + user.setFullName(request.getFullName()); + user.setEmail(request.getEmail()); + user.setRole(request.getRole()); + user.setActive(request.getActive()); + + user = userRepository.save(user); + return mapToResponse(user); + } + + @Transactional + public UserResponse updateUser(Long id, UserRequest request) { + User user = userRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("User not found with id: " + id)); + + user.setUsername(request.getUsername()); + if (request.getPassword() != null && !request.getPassword().trim().isEmpty()) { + user.setPassword(passwordEncoder.encode(request.getPassword())); + } + user.setFullName(request.getFullName()); + user.setEmail(request.getEmail()); + user.setRole(request.getRole()); + user.setActive(request.getActive()); + + user = userRepository.save(user); + return mapToResponse(user); + } + + @Transactional + public void deleteUser(Long id) { + if (!userRepository.existsById(id)) { + throw new ResourceNotFoundException("User not found with id: " + id); + } + userRepository.deleteById(id); + } + + @Transactional + public void bulkDeleteUsers(BulkDeleteRequest request) { + userRepository.deleteAllById(request.getIds()); + } + + private UserResponse mapToResponse(User user) { + return new UserResponse( + user.getId(), + user.getUsername(), + user.getFullName(), + user.getEmail(), + user.getRole().toString(), + user.getActive(), + user.getCreatedAt(), + user.getUpdatedAt() + ); + } +}