littleshop/LittleShop/Validators/CreateOrderDtoValidator.cs
SysAdmin 68131b6549 Fix: Order creation validation - Support CustomerInfo without IdentityReference
## Issue
Order creation failing with 400 BadRequest when using CustomerInfo (Telegram users).
Validator required IdentityReference to always be populated, but it's null when using CustomerInfo.

## Root Cause
CreateOrderDtoValidator.cs:10-12 enforced NotEmpty() on IdentityReference unconditionally.
TeleBot sends CustomerInfo for identified users, leaving IdentityReference null.

## Solution
Updated validator to accept EITHER IdentityReference OR CustomerInfo:
- New rule: At least one must be provided
- IdentityReference validation only applies when it's provided (.When() condition)
- Maintains backward compatibility with anonymous orders

## Impact
 Telegram bot orders can now be created successfully
 Anonymous orders still require IdentityReference
 Proper validation error messages for both scenarios

## Testing Required
- Create order via Telegram bot (with CustomerInfo)
- Create anonymous order (with IdentityReference)
- Verify both scenarios work correctly

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-03 18:02:23 +01:00

52 lines
1.8 KiB
C#

using FluentValidation;
using LittleShop.DTOs;
namespace LittleShop.Validators;
public class CreateOrderDtoValidator : AbstractValidator<CreateOrderDto>
{
public CreateOrderDtoValidator()
{
// Either IdentityReference OR CustomerInfo must be provided
RuleFor(x => x)
.Must(x => !string.IsNullOrEmpty(x.IdentityReference) || x.CustomerInfo != null)
.WithMessage("Either IdentityReference or CustomerInfo must be provided");
// IdentityReference validation (when provided)
RuleFor(x => x.IdentityReference)
.MaximumLength(100).WithMessage("Identity reference cannot exceed 100 characters")
.When(x => !string.IsNullOrEmpty(x.IdentityReference));
RuleFor(x => x.ShippingName)
.NotEmpty().WithMessage("Shipping name is required");
RuleFor(x => x.ShippingAddress)
.NotEmpty().WithMessage("Shipping address is required");
RuleFor(x => x.ShippingCity)
.NotEmpty().WithMessage("Shipping city is required");
RuleFor(x => x.ShippingPostCode)
.NotEmpty().WithMessage("Shipping post code is required");
RuleFor(x => x.ShippingCountry)
.NotEmpty().WithMessage("Shipping country is required");
RuleFor(x => x.Items)
.NotEmpty().WithMessage("Order must contain at least one item");
RuleForEach(x => x.Items).SetValidator(new CreateOrderItemDtoValidator());
}
}
public class CreateOrderItemDtoValidator : AbstractValidator<CreateOrderItemDto>
{
public CreateOrderItemDtoValidator()
{
RuleFor(x => x.ProductId)
.NotEmpty().WithMessage("Product ID is required");
RuleFor(x => x.Quantity)
.GreaterThan(0).WithMessage("Quantity must be greater than 0");
}
}