diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..13566b81b018ad684f3a35fee301741b2734c8f4 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/backend/src/main/java/kisbe32/backend/JsonConfig.java b/backend/src/main/java/kisbe32/backend/JsonConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..a7aac8fc8f72bc34ceb79ff130ab617742d83040 --- /dev/null +++ b/backend/src/main/java/kisbe32/backend/JsonConfig.java @@ -0,0 +1,19 @@ +package kisbe32.backend; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; + +@Configuration +public class JsonConfig { + + @Bean + public Jackson2ObjectMapperBuilder jacksonBuilder() { + Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); + builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + builder.modules(new JavaTimeModule()); + return builder; + } +} \ No newline at end of file diff --git a/backend/src/main/java/kisbe32/backend/OrderController.java b/backend/src/main/java/kisbe32/backend/OrderController.java new file mode 100644 index 0000000000000000000000000000000000000000..a563803be18d5959b1b214165b4a2366affdfb7b --- /dev/null +++ b/backend/src/main/java/kisbe32/backend/OrderController.java @@ -0,0 +1,177 @@ +package kisbe32.backend; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +@RestController +@RequestMapping("/api/orders") +public class OrderController { + + @Autowired + private OrderRepository orderRepository; + + @Autowired + private OrderItemRepository orderItemRepository; + + @Autowired + private UserRepository userRepository; + + @Autowired + private ProductRepository productRepository; + + @PostMapping + public ResponseEntity<?> createOrder(@RequestBody Map<String, Object> payload) { + try { + // Extract order data from payload + Integer userId = (Integer) payload.get("userId"); + String status = (String) payload.get("status"); + + // Find user + Optional<User> userOptional = userRepository.findById(userId); + if (!userOptional.isPresent()) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body("User not found with ID: " + userId); + } + + User user = userOptional.get(); + + // Parse totalAmount + BigDecimal totalAmount; + Object totalAmountObj = payload.get("totalAmount"); + if (totalAmountObj instanceof Integer) { + totalAmount = BigDecimal.valueOf((Integer) totalAmountObj); + } else if (totalAmountObj instanceof Double) { + totalAmount = BigDecimal.valueOf((Double) totalAmountObj); + } else if (totalAmountObj instanceof String) { + try { + totalAmount = new BigDecimal((String) totalAmountObj); + } catch (NumberFormatException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body("Invalid totalAmount format: " + totalAmountObj); + } + } else { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body("Invalid or missing totalAmount"); + } + + // Create new order + Order order = new Order(user, status, totalAmount); + + // Parse order date if provided + String orderDateStr = (String) payload.get("orderDate"); + if (orderDateStr != null && !orderDateStr.isEmpty()) { + try { + LocalDateTime orderDate = LocalDateTime.parse(orderDateStr); + order.setOrderDate(orderDate); + } catch (Exception e) { + try { + // Try with ISO formatter + DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME; + LocalDateTime orderDate = LocalDateTime.parse(orderDateStr, formatter); + order.setOrderDate(orderDate); + } catch (Exception ex) { + // Log but keep using default date + System.err.println("Failed to parse order date: " + orderDateStr); + } + } + } + + // Save order first to get its ID + order = orderRepository.save(order); + + // Extract and save order items + List<Map<String, Object>> itemsData = (List<Map<String, Object>>) payload.get("items"); + List<OrderItem> orderItems = new ArrayList<>(); + + if (itemsData != null) { + for (Map<String, Object> itemData : itemsData) { + Integer productId = (Integer) itemData.get("productId"); + Integer quantity = (Integer) itemData.get("quantity"); + + // Parse price + BigDecimal price; + Object priceObj = itemData.get("price"); + if (priceObj instanceof Integer) { + price = BigDecimal.valueOf((Integer) priceObj); + } else if (priceObj instanceof Double) { + price = BigDecimal.valueOf((Double) priceObj); + } else if (priceObj instanceof String) { + try { + price = new BigDecimal((String) priceObj); + } catch (NumberFormatException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body("Invalid price format for product ID: " + productId); + } + } else { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body("Invalid price format for product ID: " + productId); + } + + // Find product + Optional<Product> productOptional = productRepository.findById(productId); + if (!productOptional.isPresent()) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body("Product not found with ID: " + productId); + } + + Product product = productOptional.get(); + + // Create order item + OrderItem orderItem = new OrderItem(order, product, quantity, price); + orderItems.add(orderItem); + } + + // Save all order items + orderItemRepository.saveAll(orderItems); + } + + return ResponseEntity.status(HttpStatus.CREATED).body(order); + + } catch (Exception e) { + e.printStackTrace(); // Log the error + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("Error creating order: " + e.getMessage()); + } + } + + @GetMapping + public ResponseEntity<List<Order>> getAllOrders() { + List<Order> orders = orderRepository.findAll(); + return ResponseEntity.ok(orders); + } + + @GetMapping("/user/{userId}") + public ResponseEntity<List<Order>> getOrdersByUser(@PathVariable Integer userId) { + try { + System.out.println("Fetching orders for user ID: " + userId); + List<Order> orders = orderRepository.findByUser_Id(userId); + System.out.println("Found " + orders.size() + " orders"); + return ResponseEntity.ok(orders); + } catch (Exception e) { + System.err.println("Error fetching orders for user ID " + userId + ": " + e.getMessage()); + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + } + + @GetMapping("/{orderId}") + public ResponseEntity<?> getOrderById(@PathVariable Integer orderId) { + Optional<Order> orderOptional = orderRepository.findById(orderId); + if (orderOptional.isPresent()) { + return ResponseEntity.ok(orderOptional.get()); + } else { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body("Order not found with ID: " + orderId); + } + } +} \ No newline at end of file