feat(frontend e back-end): termini e condizioni
All checks were successful
Build, Test and Deploy / test-backend (push) Successful in 38s
Build, Test and Deploy / build-and-push (push) Successful in 1m3s
Build, Test and Deploy / deploy (push) Successful in 11s

This commit is contained in:
2026-02-26 22:24:51 +01:00
parent 6f3e601f21
commit 80a41b0cc2
20 changed files with 504 additions and 31 deletions

View File

@@ -11,6 +11,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.multipart.MultipartFile;
import jakarta.validation.Valid;
import java.io.IOException;
import java.nio.file.Files;
@@ -61,9 +62,15 @@ public class CustomQuoteRequestController {
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@Transactional
public ResponseEntity<CustomQuoteRequest> createCustomQuoteRequest(
@RequestPart("request") com.printcalculator.dto.QuoteRequestDto requestDto,
@Valid @RequestPart("request") com.printcalculator.dto.QuoteRequestDto requestDto,
@RequestPart(value = "files", required = false) List<MultipartFile> files
) throws IOException {
if (!requestDto.isAcceptTerms() || !requestDto.isAcceptPrivacy()) {
throw new ResponseStatusException(
HttpStatus.BAD_REQUEST,
"Accettazione Termini e Privacy obbligatoria."
);
}
// 1. Create Request
CustomQuoteRequest request = new CustomQuoteRequest();

View File

@@ -14,6 +14,7 @@ import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import jakarta.validation.Valid;
import java.io.IOException;
import java.math.BigDecimal;
@@ -80,7 +81,7 @@ public class OrderController {
@Transactional
public ResponseEntity<OrderDto> createOrderFromQuote(
@PathVariable UUID quoteSessionId,
@RequestBody com.printcalculator.dto.CreateOrderRequest request
@Valid @RequestBody com.printcalculator.dto.CreateOrderRequest request
) {
Order order = orderService.createOrderFromQuote(quoteSessionId, request);
List<OrderItem> items = orderItemRepo.findByOrder_Id(order.getId());

View File

@@ -1,6 +1,7 @@
package com.printcalculator.dto;
import lombok.Data;
import jakarta.validation.constraints.AssertTrue;
@Data
public class CreateOrderRequest {
@@ -8,4 +9,10 @@ public class CreateOrderRequest {
private AddressDto billingAddress;
private AddressDto shippingAddress;
private boolean shippingSameAsBilling;
@AssertTrue(message = "L'accettazione dei Termini e Condizioni e obbligatoria.")
private boolean acceptTerms;
@AssertTrue(message = "L'accettazione dell'Informativa Privacy e obbligatoria.")
private boolean acceptPrivacy;
}

View File

@@ -1,6 +1,7 @@
package com.printcalculator.dto;
import lombok.Data;
import jakarta.validation.constraints.AssertTrue;
@Data
public class QuoteRequestDto {
@@ -12,4 +13,10 @@ public class QuoteRequestDto {
private String companyName;
private String contactPerson;
private String message;
@AssertTrue(message = "L'accettazione dei Termini e Condizioni e obbligatoria.")
private boolean acceptTerms;
@AssertTrue(message = "L'accettazione dell'Informativa Privacy e obbligatoria.")
private boolean acceptPrivacy;
}

View File

@@ -2,12 +2,16 @@ package com.printcalculator.exception;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ControllerAdvice
@@ -24,4 +28,34 @@ public class GlobalExceptionHandler {
return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Object> handleValidationException(
MethodArgumentNotValidException ex, WebRequest request) {
List<String> details = new ArrayList<>();
for (FieldError fieldError : ex.getBindingResult().getFieldErrors()) {
details.add(fieldError.getField() + ": " + fieldError.getDefaultMessage());
}
Map<String, Object> body = new LinkedHashMap<>();
body.put("timestamp", LocalDateTime.now());
body.put("message", "Dati non validi.");
body.put("error", "Validation Error");
body.put("details", details);
return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<Object> handleIllegalArgumentException(
IllegalArgumentException ex, WebRequest request) {
Map<String, Object> body = new LinkedHashMap<>();
body.put("timestamp", LocalDateTime.now());
body.put("message", ex.getMessage());
body.put("error", "Bad Request");
return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
}
}

View File

@@ -71,6 +71,10 @@ public class OrderService {
@Transactional
public Order createOrderFromQuote(UUID quoteSessionId, CreateOrderRequest request) {
if (!request.isAcceptTerms() || !request.isAcceptPrivacy()) {
throw new IllegalArgumentException("Accettazione Termini e Privacy obbligatoria.");
}
QuoteSession session = quoteSessionRepo.findById(quoteSessionId)
.orElseThrow(() -> new RuntimeException("Quote Session not found"));