TariffV2CalculationController.java
package com.github.jenkaby.bikerental.tariff.web.query;
import com.github.jenkaby.bikerental.shared.config.OpenApiConfig;
import com.github.jenkaby.bikerental.tariff.TariffV2Facade;
import com.github.jenkaby.bikerental.tariff.web.query.dto.CostCalculationRequest;
import com.github.jenkaby.bikerental.tariff.web.query.dto.CostCalculationResponse;
import com.github.jenkaby.bikerental.tariff.web.query.mapper.BatchCalculationMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ProblemDetail;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Validated
@Slf4j
@RestController
@RequestMapping("/api/v2/tariffs")
@Tag(name = OpenApiConfig.Tags.TARIFFS, description = "Tariff V2 API")
public class TariffV2CalculationController {
private final TariffV2Facade tariffV2Facade;
private final BatchCalculationMapper requestMapper;
TariffV2CalculationController(TariffV2Facade tariffV2Facade, BatchCalculationMapper requestMapper) {
this.tariffV2Facade = tariffV2Facade;
this.requestMapper = requestMapper;
}
@PostMapping("/calculate")
@Operation(summary = "Calculate rental cost for multiple equipment items",
description = "Supports normal mode (auto-select tariffs, apply discount) and SPECIAL mode (fixed group price)")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "Cost calculation result",
content = @Content(schema = @Schema(implementation = CostCalculationResponse.class))),
@ApiResponse(responseCode = "400", description = "Validation error",
content = @Content(schema = @Schema(implementation = ProblemDetail.class))),
@ApiResponse(responseCode = "404", description = "No suitable tariff found for an equipment type",
content = @Content(schema = @Schema(implementation = ProblemDetail.class)))
})
public ResponseEntity<CostCalculationResponse> calculateCost(@Valid @RequestBody CostCalculationRequest request) {
log.info("[POST] Batch cost calculation for {} equipment item(s)", request.equipments().size());
var command = requestMapper.toCommand(request);
var result = tariffV2Facade.calculateRentalCost(command);
return ResponseEntity.ok(requestMapper.toResponse(result));
}
}