@PatchMapping("/orders/buy/{salesJourneyId}")
    @Operation(summary = "To create either card or cash order in cash-hub for BUY flow", description = "To create either card or cash order in cash-hub for BUY flow")
    public ResponseEntity newOrderBuyFlow(
            @RequestHeader("retailerId") String retailerId,
            @RequestHeader("source") String source,
            @RequestHeader("trackingId") String trackingId,
            @PathVariable("salesJourneyId") String salesJourneyId,
            @RequestBody @Valid SalesOrderSubmissionCardRequest orderRequest
    ) {
        validator.validateDealerLoginHeaders();
        ResponseEnvelop<Map<String, Object>> response = salesOrderService.processOrder(salesJourneyId, orderRequest,
                source, trackingId, retailerId);
        return ResponseEntity.ok(response);
    }
    @PatchMapping("/orders/buy/{salesJourneyId}")
        @Operation(summary = "To create either card or cash order in cash-hub for BUY flow", description = "To create either card or cash order in cash-hub for BUY flow")
        public ResponseEntity newOrderBuyFlow(
                @RequestHeader("retailerId") String retailerId,
                @RequestHeader("source") String source,
                @RequestHeader("trackingId") String trackingId,
                @PathVariable("salesJourneyId") String salesJourneyId,
                @RequestBody @Valid SalesOrderSubmissionCardRequest orderRequest
        ) {
            validator.validateDealerLoginHeaders();
            ResponseEnvelop<Map<String, Object>> response = salesOrderService.processOrder(salesJourneyId, orderRequest,
                    source, trackingId, retailerId);
            return ResponseEntity.ok(response);
        }
                                                                    String source, String trackingId, String retailerId) {
        logger.info("Processing order for Sales Journey ID: {}", salesJourneyId);
        validateRequest(orderRequest);
        Orders order = Orders.builder()
                .orderId(Long.valueOf(orderRequest.getOrderSummary().getId()))
                .orderType(orderRequest.getOrderSummary().getType())
                .description(orderRequest.getOrderSummary().getDescription())
                .amount(BigDecimal.valueOf(orderRequest.getOrderSummary().getTotal()))
                .phone(Long.valueOf(orderRequest.getCustomer().getPhone()))
                .zip(orderRequest.getCustomer().getZip())
                .customerRelationshipId(orderRequest.getCustomer().getCustomerRelationshipId())
                .salesJourneyId(salesJourneyId)
                .build();
        salesJourneyDao.saveOrder(order, source, trackingId, retailerId);
        for (PricePlan pricePlan : orderRequest.getPricePlans()) {
            for (Plan plan : pricePlan.getPlans()) {
                OrderItems orderItem = OrderItems.builder()
                        .ordersObjId(order.getOrderId())
                        .lob(pricePlan.getLob())
                        .planId(plan.getId())
                        .unitPrice(BigDecimal.valueOf(plan.getUnitPrice()))
                        .quantity(plan.getQuantity())
                        .build();
                salesJourneyDao.saveOrderItem(orderItem, source, trackingId);
            }
        }
        String paymentStatus = orderRequest.getBilling().getPaymentMethod().equals("CARD") ? Constants.COMPLETE : Constants.PENDING_POS;
        Payments payment = Payments.builder()
                .orderItemsObjId(order.getOrderId())    // Foreign key to OrderItems
                .cashhubRef(orderRequest.getBilling().getCashhubRef())
                .paymentMethod(orderRequest.getBilling().getPaymentMethod())
                .paymentType(orderRequest.getBilling().getPaymentType())
                .paymentStatus(paymentStatus)
                .build();
        salesJourneyDao.savePayment(payment, source, trackingId);
        Map<String, Object> responseData = new HashMap<>();
        responseData.put("hubConfNumber", orderRequest.getBilling().getCashhubRef());
        logger.info("Response prepared successfully for Order ID: {}", order.getOrderId());
        return ResponseEnvelop.<Map<String, Object>>builder()
                .data(responseData)
                .message("Order created successfully")
                .error(null)
                .build();
    }
private void validateRequest(SalesOrderSubmissionCardRequest orderRequest) {
        if (orderRequest.getCustomer() == null || orderRequest.getPricePlans() == null || orderRequest.getOrderSummary() == null || orderRequest.getBilling() == null) {
            throw new InvalidRequestException("Missing required fields");
        }
    }```
Repository
```@Repository
public class SalesJourneyDaoImpl implements SalesJourneyDao {
    private final JdbcTemplate jdbcTemplate;
    @Value("${insert.salesJourney}")
    private String insertSalesJourneyQuery;
    @Value("${select.byId}")
    private String selectByIdQuery;
    @Value("${select.bySalesJourneyId}")
    private String selectBySalesJourneyIdQuery;
    @Value("${exists.bySalesJourneyId}")
    private String existsBySalesJourneyIdQuery;
    @Value("${insert.order}")
    private String insertOrderQuery;
    @Value("${insert.orderItem}")
    private String insertOrderItemQuery;
    @Value("${insert.payment}")
    private String insertPaymentQuery;
    @Autowired
    public SalesJourneyDaoImpl(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
    @Override
    public void save(Orders salesJourney) {
        jdbcTemplate.update(
                insertSalesJourneyQuery,
                salesJourney.getSalesJourneyId(),
                salesJourney.getRetailerId(),
                salesJourney.getSource(),
                salesJourney.getTrackingId(),
                Timestamp.valueOf(LocalDateTime.now(ZoneId.of("America/New_York")))
        );
    }
    @Override
    public Optional<Orders> findById(Long id) {
        try {
            Orders salesJourney = jdbcTemplate.queryForObject(
                    selectByIdQuery,
                    salesJourneyRowMapper(),
                    id
            );
            return Optional.ofNullable(salesJourney);
        } catch (EmptyResultDataAccessException e) {
            return Optional.empty();
        }
    }
    @Override
    public Optional<Orders> findBySalesJourneyId(String salesJourneyId) {
        try {
            Orders salesJourney = jdbcTemplate.queryForObject(
                    selectBySalesJourneyIdQuery,
                    salesJourneyRowMapper(),
                    salesJourneyId
            );
            return Optional.ofNullable(salesJourney);
        } catch (EmptyResultDataAccessException e) {
            return Optional.empty();
        }
    }
    @Override
    public boolean existsBySalesJourneyId(String salesJourneyId) {
        Integer count = jdbcTemplate.queryForObject(
                existsBySalesJourneyIdQuery,
                Integer.class,
                salesJourneyId
        );
        return count != null && count > 0;
    }
    private RowMapper<Orders> salesJourneyRowMapper() {
        return new RowMapper<Orders>() {
            @Override
            public Orders mapRow(ResultSet rs, int rowNum) throws SQLException {
                Orders salesJourney = new Orders();
                salesJourney.setId(rs.getLong("id"));
                salesJourney.setSalesJourneyId(rs.getString("sales_journey_id"));
                salesJourney.setRetailerId(rs.getString("retailer_id"));
                salesJourney.setSource(rs.getString("source"));
                salesJourney.setTrackingId(rs.getString("tracking_id"));
                salesJourney.setCreateDate(rs.getTimestamp("created_at").toLocalDateTime());
                return salesJourney;
            }
        };
    }
    public void saveOrder(Orders order, String source, String trackingId, String retailerId) {
        jdbcTemplate.update(insertOrderQuery, order.getOrderId(), order.getOrderType(), order.getDescription(), order.getAmount(),
                order.getPhone(), order.getZip(), order.getCustomerRelationshipId(), order.getSalesJourneyId(), source, trackingId, retailerId,
                Timestamp.valueOf(LocalDateTime.now(ZoneId.of("America/New_York"))));
    }
    public void saveOrderItem(OrderItems orderItem, String source, String trackingId) {
        jdbcTemplate.update(insertOrderItemQuery, orderItem.getOrdersObjId(), orderItem.getLob(), orderItem.getPlanId(), orderItem.getUnitPrice(),
                orderItem.getQuantity(), source, trackingId, Timestamp.valueOf(LocalDateTime.now(ZoneId.of("America/New_York"))));
    }
    public void savePayment(Payments payment, String source, String trackingId) {
        jdbcTemplate.update(insertPaymentQuery, payment.getOrderItemsObjId(), payment.getPaymentMethod(), payment.getPaymentStatus(),
                payment.getCashhubRef(), source, trackingId, Timestamp.valueOf(LocalDateTime.now(ZoneId.of("America/New_York"))));
    }
}```
controller advice
```@RestControllerAdvice
public class GlobalControllerAdvice extends ResponseEntityExceptionHandler {
    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalControllerAdvice.class);
    @Autowired
    @Qualifier("MessageSource")
    private ResourceBundleMessageSource messageSource;
    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException exception,
                                                                  HttpHeaders httpHeaders, HttpStatus httpStatus, WebRequest webRequest) {
        // Map validation errors to the Error class
        List<ErrorCashhub> errors = exception.getBindingResult()
                .getFieldErrors()
                .stream()
                .map(fieldError -> ErrorCashhub.builder()
                        .code("ERR_VALIDATION")
                        .message(fieldError.getDefaultMessage())
                        .details("Field: " + fieldError.getField())
                        .build())
                .collect(Collectors.toList());
        return new ResponseEntity<>(errors, httpHeaders, HttpStatus.BAD_REQUEST);
    }
    @ExceptionHandler(CashHubException.class)
    public ResponseEntity<CashHubResponseEnvelop<Void>> handleDealerPortalException(CashHubException ex) {
        return ResponseEntity
                .status(ex.getHttpStatus())
                .body(new CashHubResponseEnvelop<>(ex.getApiError()));
    }
    @ExceptionHandler(MissingRequestHeaderException.class)
    public ResponseEntity<CashHubResponseEnvelop<ErrorCashhub>> handleMissingRequestHeaderException(MissingRequestHeaderException ex) {
        ErrorCashhub error = ErrorCashhub.builder()
                .code(ENUMConfig.ERR_VALIDATION.toString())
                .message(ENUMConfig.ERR_VALIDATION.getValue())
                .details("Required header is missing: " + ex.getHeaderName())
                .build();
        CashHubResponseEnvelop<ErrorCashhub> response = new CashHubResponseEnvelop<>(error);
        return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
    }
    @ExceptionHandler(InvalidHeaderException.class)
    public ResponseEntity<CashHubResponseEnvelop<ErrorCashhub>> handleInvalidHeaderException(InvalidHeaderException ex, HttpServletRequest request) {
        ErrorCashhub error = ErrorCashhub.builder()
                .code(ENUMConfig.ERR_VALIDATION.toString())
                .message(ENUMConfig.ERR_VALIDATION.getValue())
                .details(ex.getMessage())
                .build();
        CashHubResponseEnvelop<ErrorCashhub> response = new CashHubResponseEnvelop<>(error);
        return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
    }
    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception ex) {
        return new ResponseEntity<>("Internal Server Error: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }
    @ExceptionHandler(InvalidRequestException.class)
    public ResponseEntity<ErrorCashhub> handleInvalidRequestException(InvalidRequestException ex) {
        ErrorCashhub errorResponse = ErrorCashhub.builder()
                .code(ENUMConfig.ERR_VALIDATION.toString())
                .message(ENUMConfig.ERR_VALIDATION.getValue())
                .details("Invalid request parameters: " + ex.getMessage())
                .build();
        return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
    }
    @ExceptionHandler(DataAccessException.class)
    public ResponseEntity<ErrorCashhub> handleDatabaseException(DataAccessException ex) {
        ErrorCashhub errorResponse = ErrorCashhub.builder()
                .code(ENUMConfig.DATABASE_EXCEPTION_109.toString())
                .message(ENUMConfig.DATABASE_EXCEPTION_109.getValue())
                .details("Error while accessing the database")
                .build();
        return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}```
Validator:
```Component
public class Validator {
    private static final String SPLIT_REGEX = "\\s*,\\s*";
    private final Logger log = LoggerFactory.getLogger(Validator.class);
    @Autowired
    private WebRequest webRequest;
    @Value("${eligible.sources}")
    private String eligibleSourcesStr;
    @Value("${eligible.dealerLogin.sources}")
    private String eligibleDealerLoginSourcesStr;
    private List<String> eligibleSourceList;
    private List<String> eligibleDealerLoginSourceList;
    Validator() {
        log.info("Validator initialized!");
    }
    @PostConstruct
    private void initFields() {
        if (!empty(eligibleSourcesStr)) {
            eligibleSourceList = Arrays.asList(eligibleSourcesStr.toUpperCase().split(SPLIT_REGEX));
        }
        log.info("eligibleSources: {} ", eligibleSourceList);
    }
    private boolean empty(final String s) {
        return s == null || s.trim().isEmpty();
    }
    public void validateDealerLoginHeaders() {
        final String trackingId = webRequest.getHeader(Constants.HEADER_TRACKING_ID);
        final String source = webRequest.getHeader(Constants.HEADER_SOURCE);
        final String retailerId = webRequest.getHeader(Constants.HEADER_RETAILER_ID);
        if (!isInputValid(trackingId)) {
            log.error(Constants.VALIDATION_ERROR_PRECONDITION_FAILED, ENUMConfig.DEALERPORTAL_SERVICE_COMMON_002);
            throw new InvalidHeaderException("Header '" + trackingId + "' must not be null or empty.");
        } else if (!isInputValid(source)) {
            log.error(Constants.VALIDATION_ERROR_PRECONDITION_FAILED, ENUMConfig.DEALERPORTAL_SERVICE_COMMON_001);
            throw new InvalidHeaderException("Header '" + source + "' must not be null or empty.");
        } else if (!isInputValid(retailerId)) {
            log.error(Constants.VALIDATION_ERROR_PRECONDITION_FAILED, ENUMConfig.DEALERPORTAL_SERVICE_COMMON_004);
            throw new InvalidHeaderException("Header '" + retailerId + "' must not be null or empty.");
        }
        if (!isDealerLoginSourceAuthorized(source)) {
            log.error(Constants.VALIDATION_ERROR_FORBIDDEN, ENUMConfig.DEALERPORTAL_SERVICE_COMMON_003);
            throw new InvalidHeaderException("Header '" + source + "' unauthorized.");
        }
    }
    private boolean isInputValid(String input) {
        return input != null && !input.trim().equals("");
    }
    private boolean isDealerLoginSourceAuthorized(String source) {
        return CollectionUtils.isEmpty(eligibleSourceList) ||
                eligibleSourceList.contains(source.trim().toUpperCase());
    }
}
public CashHubResponseEnvelop<Map<String, Object>> processOrder(String salesJourneyId, SalesOrderSubmissionCardRequest orderRequest,
                                                                    String source, String trackingId, String retailerId) {
        logger.info("Processing order for Sales Journey ID: {}", salesJourneyId);
        validateRequest(orderRequest);
        Orders order = Orders.builder()
                .orderId(Long.valueOf(orderRequest.getOrderSummary().getId()))
                .orderType(orderRequest.getOrderSummary().getType())
                .description(orderRequest.getOrderSummary().getDescription())
                .amount(BigDecimal.valueOf(orderRequest.getOrderSummary().getTotal()))
                .phone(Long.valueOf(orderRequest.getCustomer().getPhone()))
                .zip(orderRequest.getCustomer().getZip())
                .customerRelationshipId(orderRequest.getCustomer().getCustomerRelationshipId())
                .salesJourneyId(salesJourneyId)
                .build();
        salesJourneyDao.saveOrder(order, source, trackingId, retailerId);
        for (PricePlan pricePlan : orderRequest.getPricePlans()) {
            for (Plan plan : pricePlan.getPlans()) {
                OrderItems orderItem = OrderItems.builder()
                        .ordersObjId(order.getOrderId())
                        .lob(pricePlan.getLob())
                        .planId(plan.getId())
                        .unitPrice(BigDecimal.valueOf(plan.getUnitPrice()))
                        .quantity(plan.getQuantity())
                        .build();
                salesJourneyDao.saveOrderItem(orderItem, source, trackingId);
            }
        }
        String paymentStatus = orderRequest.getBilling().getPaymentMethod().equals("CARD") ? Constants.COMPLETE : Constants.PENDING_POS;
        Payments payment = Payments.builder()
                .orderItemsObjId(order.getOrderId())    // Foreign key to OrderItems
                .cashhubRef(orderRequest.getBilling().getCashhubRef())
                .paymentMethod(orderRequest.getBilling().getPaymentMethod())
                .paymentType(orderRequest.getBilling().getPaymentType())
                .paymentStatus(paymentStatus)
                .build();
        salesJourneyDao.savePayment(payment, source, trackingId);
        Map<String, Object> responseData = new HashMap<>();
        responseData.put("hubConfNumber", orderRequest.getBilling().getCashhubRef());
        logger.info("Response prepared successfully for Order ID: {}", order.getOrderId());
        return ResponseEnvelop.<Map<String, Object>>builder()
                .data(responseData)
                .message("Order created successfully")
                .error(null)
                .build();
    }
private void validateRequest(SalesOrderSubmissionCardRequest orderRequest) {
        if (orderRequest.getCustomer() == null || orderRequest.getPricePlans() == null || orderRequest.getOrderSummary() == null || orderRequest.getBilling() == null) {
            throw new InvalidRequestException("Missing required fields");
        }
    }
Repository
@Repository
public class SalesJourneyDaoImpl implements SalesJourneyDao {
    private final JdbcTemplate jdbcTemplate;
    @Value("${insert.salesJourney}")
    private String insertSalesJourneyQuery;
    @Value("${select.byId}")
    private String selectByIdQuery;
    @Value("${select.bySalesJourneyId}")
    private String selectBySalesJourneyIdQuery;
    @Value("${exists.bySalesJourneyId}")
    private String existsBySalesJourneyIdQuery;
    @Value("${insert.order}")
    private String insertOrderQuery;
    @Value("${insert.orderItem}")
    private String insertOrderItemQuery;
    @Value("${insert.payment}")
    private String insertPaymentQuery;
    @Autowired
    public SalesJourneyDaoImpl(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
    @Override
    public void save(Orders salesJourney) {
        jdbcTemplate.update(
                insertSalesJourneyQuery,
                salesJourney.getSalesJourneyId(),
                salesJourney.getRetailerId(),
                salesJourney.getSource(),
                salesJourney.getTrackingId(),
                Timestamp.valueOf(LocalDateTime.now(ZoneId.of("America/New_York")))
        );
    }
    @Override
    public Optional<Orders> findById(Long id) {
        try {
            Orders salesJourney = jdbcTemplate.queryForObject(
                    selectByIdQuery,
                    salesJourneyRowMapper(),
                    id
            );
            return Optional.ofNullable(salesJourney);
        } catch (EmptyResultDataAccessException e) {
            return Optional.empty();
        }
    }
    @Override
    public Optional<Orders> findBySalesJourneyId(String salesJourneyId) {
        try {
            Orders salesJourney = jdbcTemplate.queryForObject(
                    selectBySalesJourneyIdQuery,
                    salesJourneyRowMapper(),
                    salesJourneyId
            );
            return Optional.ofNullable(salesJourney);
        } catch (EmptyResultDataAccessException e) {
            return Optional.empty();
        }
    }
    @Override
    public boolean existsBySalesJourneyId(String salesJourneyId) {
        Integer count = jdbcTemplate.queryForObject(
                existsBySalesJourneyIdQuery,
                Integer.class,
                salesJourneyId
        );
        return count != null && count > 0;
    }
    private RowMapper<Orders> salesJourneyRowMapper() {
        return new RowMapper<Orders>() {
            @Override
            public Orders mapRow(ResultSet rs, int rowNum) throws SQLException {
                Orders salesJourney = new Orders();
                salesJourney.setId(rs.getLong("id"));
                salesJourney.setSalesJourneyId(rs.getString("sales_journey_id"));
                salesJourney.setRetailerId(rs.getString("retailer_id"));
                salesJourney.setSource(rs.getString("source"));
                salesJourney.setTrackingId(rs.getString("tracking_id"));
                salesJourney.setCreateDate(rs.getTimestamp("created_at").toLocalDateTime());
                return salesJourney;
            }
        };
    }
    public void saveOrder(Orders order, String source, String trackingId, String retailerId) {
        jdbcTemplate.update(insertOrderQuery, order.getOrderId(), order.getOrderType(), order.getDescription(), order.getAmount(),
                order.getPhone(), order.getZip(), order.getCustomerRelationshipId(), order.getSalesJourneyId(), source, trackingId, retailerId,
                Timestamp.valueOf(LocalDateTime.now(ZoneId.of("America/New_York"))));
    }
    public void saveOrderItem(OrderItems orderItem, String source, String trackingId) {
        jdbcTemplate.update(insertOrderItemQuery, orderItem.getOrdersObjId(), orderItem.getLob(), orderItem.getPlanId(), orderItem.getUnitPrice(),
                orderItem.getQuantity(), source, trackingId, Timestamp.valueOf(LocalDateTime.now(ZoneId.of("America/New_York"))));
    }
    public void savePayment(Payments payment, String source, String trackingId) {
        jdbcTemplate.update(insertPaymentQuery, payment.getOrderItemsObjId(), payment.getPaymentMethod(), payment.getPaymentStatus(),
                payment.getCashhubRef(), source, trackingId, Timestamp.valueOf(LocalDateTime.now(ZoneId.of("America/New_York"))));
    }
}
controller advice
@RestControllerAdvice
public class GlobalControllerAdvice extends ResponseEntityExceptionHandler {
    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalControllerAdvice.class);
    @Autowired
    @Qualifier("MessageSource")
    private ResourceBundleMessageSource messageSource;
    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException exception,
                                                                  HttpHeaders httpHeaders, HttpStatus httpStatus, WebRequest webRequest) {
        // Map validation errors to the Error class
        List<ErrorCashhub> errors = exception.getBindingResult()
                .getFieldErrors()
                .stream()
                .map(fieldError -> ErrorCashhub.builder()
                        .code("ERR_VALIDATION")
                        .message(fieldError.getDefaultMessage())
                        .details("Field: " + fieldError.getField())
                        .build())
                .collect(Collectors.toList());
        return new ResponseEntity<>(errors, httpHeaders, HttpStatus.BAD_REQUEST);
    }
    @ExceptionHandler(CashHubException.class)
    public ResponseEntity<CashHubResponseEnvelop<Void>> handleDealerPortalException(CashHubException ex) {
        return ResponseEntity
                .status(ex.getHttpStatus())
                .body(new CashHubResponseEnvelop<>(ex.getApiError()));
    }
    @ExceptionHandler(MissingRequestHeaderException.class)
    public ResponseEntity<CashHubResponseEnvelop<ErrorCashhub>> handleMissingRequestHeaderException(MissingRequestHeaderException ex) {
        ErrorCashhub error = ErrorCashhub.builder()
                .code(ENUMConfig.ERR_VALIDATION.toString())
                .message(ENUMConfig.ERR_VALIDATION.getValue())
                .details("Required header is missing: " + ex.getHeaderName())
                .build();
        CashHubResponseEnvelop<ErrorCashhub> response = new CashHubResponseEnvelop<>(error);
        return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
    }
    @ExceptionHandler(InvalidHeaderException.class)
    public ResponseEntity<CashHubResponseEnvelop<ErrorCashhub>> handleInvalidHeaderException(InvalidHeaderException ex, HttpServletRequest request) {
        ErrorCashhub error = ErrorCashhub.builder()
                .code(ENUMConfig.ERR_VALIDATION.toString())
                .message(ENUMConfig.ERR_VALIDATION.getValue())
                .details(ex.getMessage())
                .build();
        CashHubResponseEnvelop<ErrorCashhub> response = new CashHubResponseEnvelop<>(error);
        return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
    }
    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception ex) {
        return new ResponseEntity<>("Internal Server Error: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }
    @ExceptionHandler(InvalidRequestException.class)
    public ResponseEntity<ErrorCashhub> handleInvalidRequestException(InvalidRequestException ex) {
        ErrorCashhub errorResponse = ErrorCashhub.builder()
                .code(ENUMConfig.ERR_VALIDATION.toString())
                .message(ENUMConfig.ERR_VALIDATION.getValue())
                .details("Invalid request parameters: " + ex.getMessage())
                .build();
        return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
    }
    @ExceptionHandler(DataAccessException.class)
    public ResponseEntity<ErrorCashhub> handleDatabaseException(DataAccessException ex) {
        ErrorCashhub errorResponse = ErrorCashhub.builder()
                .code(ENUMConfig.DATABASE_EXCEPTION_109.toString())
                .message(ENUMConfig.DATABASE_EXCEPTION_109.getValue())
                .details("Error while accessing the database")
                .build();
        return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
Validator:
@Component
public class Validator {
    private static final String SPLIT_REGEX = "\\s*,\\s*";
    private final Logger log = LoggerFactory.getLogger(Validator.class);
    @Autowired
    private WebRequest webRequest;
    @Value("${eligible.sources}")
    private String eligibleSourcesStr;
    @Value("${eligible.dealerLogin.sources}")
    private String eligibleDealerLoginSourcesStr;
    private List<String> eligibleSourceList;
    private List<String> eligibleDealerLoginSourceList;
    Validator() {
        log.info("Validator initialized!");
    }
    @PostConstruct
    private void initFields() {
        if (!empty(eligibleSourcesStr)) {
            eligibleSourceList = Arrays.asList(eligibleSourcesStr.toUpperCase().split(SPLIT_REGEX));
        }
        log.info("eligibleSources: {} ", eligibleSourceList);
    }
    private boolean empty(final String s) {
        return s == null || s.trim().isEmpty();
    }
    public void validateDealerLoginHeaders() {
        final String trackingId = webRequest.getHeader(Constants.HEADER_TRACKING_ID);
        final String source = webRequest.getHeader(Constants.HEADER_SOURCE);
        final String retailerId = webRequest.getHeader(Constants.HEADER_RETAILER_ID);
        if (!isInputValid(trackingId)) {
            log.error(Constants.VALIDATION_ERROR_PRECONDITION_FAILED, ENUMConfig.DEALERPORTAL_SERVICE_COMMON_002);
            throw new InvalidHeaderException("Header '" + trackingId + "' must not be null or empty.");
        } else if (!isInputValid(source)) {
            log.error(Constants.VALIDATION_ERROR_PRECONDITION_FAILED, ENUMConfig.DEALERPORTAL_SERVICE_COMMON_001);
            throw new InvalidHeaderException("Header '" + source + "' must not be null or empty.");
        } else if (!isInputValid(retailerId)) {
            log.error(Constants.VALIDATION_ERROR_PRECONDITION_FAILED, ENUMConfig.DEALERPORTAL_SERVICE_COMMON_004);
            throw new InvalidHeaderException("Header '" + retailerId + "' must not be null or empty.");
        }
        if (!isDealerLoginSourceAuthorized(source)) {
            log.error(Constants.VALIDATION_ERROR_FORBIDDEN, ENUMConfig.DEALERPORTAL_SERVICE_COMMON_003);
            throw new InvalidHeaderException("Header '" + source + "' unauthorized.");
        }
    }
    private boolean isInputValid(String input) {
        return input != null && !input.trim().equals("");
    }
    private boolean isDealerLoginSourceAuthorized(String source) {
        return CollectionUtils.isEmpty(eligibleSourceList) ||
                eligibleSourceList.contains(source.trim().toUpperCase());
    }
}