Subversion Repositories SmartDukaan

Rev

Rev 36321 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.spice.profitmandi.web.v2.controller;

import com.spice.profitmandi.common.model.ProfitMandiResponse;
import com.spice.profitmandi.common.model.ResponseStatus;
import com.spice.profitmandi.web.v2.response.ApiResponse;
import com.spice.profitmandi.web.v2.response.ErrorDetail;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

public abstract class V2BaseController {

    /**
     * Bridges a v1 controller's ResponseEntity into the v2 ApiResponse envelope.
     *
     * Fix for silent-success bug: v1 code often signals validation failure by
     * returning {@code responseSender.badRequest(payload)} — a 4xx response
     * whose body carries context (e.g. cart with price-changed messages from
     * {@code OrderController.createOrder}). The previous version blindly wrapped
     * everything as {@code ApiResponse.success} + 200, so the React client
     * treated a rejected order as a placed order and navigated to "Order
     * Placed!" while no transaction was written. We now preserve the v1 status
     * so axios rejects and the caller's catch-block runs.
     */
    @SuppressWarnings("rawtypes")
    protected ResponseEntity<ApiResponse<?>> wrapResponse(ResponseEntity<?> v1Response) {
        Object body = v1Response.getBody();
        Object data = body;
        boolean v1FailureFlag = false;

        if (body instanceof ProfitMandiResponse) {
            ProfitMandiResponse pmr = (ProfitMandiResponse) body;
            data = pmr.getResponse();
            v1FailureFlag = pmr.getResponseStatus() == ResponseStatus.FAILURE;
        }

        HttpStatus status = v1Response.getStatusCode();
        boolean httpError = status != null && status.value() >= 400;

        if (httpError || v1FailureFlag) {
            HttpStatus errorStatus = httpError ? status : HttpStatus.BAD_REQUEST;
            String message = extractMessage(data, errorStatus);
            ErrorDetail detail = new ErrorDetail();
            detail.setType("V1BadRequest");
            detail.setMessage(message);
            @SuppressWarnings({"unchecked", "rawtypes"})
            ApiResponse errorResponse = ApiResponse.error(errorStatus.value(), message, detail);
            // Preserve v1's original payload so the client can still surface
            // context (e.g. price-changed cart messages) if it wants to.
            errorResponse.setData(data);
            return ResponseEntity.status(errorStatus).body(errorResponse);
        }

        ApiResponse<?> apiResponse = ApiResponse.success(data);
        return ResponseEntity.ok(apiResponse);
    }

    private String extractMessage(Object data, HttpStatus fallbackStatus) {
        if (data == null) return fallbackStatus.getReasonPhrase();
        try {
            java.lang.reflect.Method m = data.getClass().getMethod("getCartMessages");
            Object messages = m.invoke(data);
            if (messages instanceof java.util.List && !((java.util.List<?>) messages).isEmpty()) {
                Object first = ((java.util.List<?>) messages).get(0);
                java.lang.reflect.Method textMethod = first.getClass().getMethod("getMessageText");
                Object text = textMethod.invoke(first);
                if (text != null && !text.toString().isEmpty()) return text.toString();
            }
        } catch (Exception ignore) {
            // fall through to generic message
        }
        try {
            java.lang.reflect.Method m = data.getClass().getMethod("getMessage");
            Object text = m.invoke(data);
            if (text != null && !text.toString().isEmpty()) return text.toString();
        } catch (Exception ignore) {
            // fall through
        }
        return fallbackStatus.getReasonPhrase();
    }
}