using System.ComponentModel.DataAnnotations; using System.Text.Json; using Tiku.Application.Commerce; using Tiku.Domain.Commerce; using Tiku.Domain.Common; using Tiku.Domain.Tenancy; namespace Tiku.Api.Contracts; public sealed class TenantCommerceQueryDto { [StringLength(50)] public string? Provider { get; set; } [StringLength(32)] public string? Status { get; set; } [Range(1, 200)] public int? Limit { get; set; } public Guid? UserId { get; set; } public Guid? RegionId { get; set; } } public sealed class UpsertPaymentAccountDto { [Required] [StringLength(50)] public string Provider { get; set; } = string.Empty; public TenantPaymentMode Mode { get; set; } = TenantPaymentMode.TenantCollect; [StringLength(200)] public string? DisplayName { get; set; } public TenantPaymentAccountStatus Status { get; set; } = TenantPaymentAccountStatus.Disabled; public JsonElement ConfigPublic { get; set; } = JsonDefaults.Object(); public UpsertPaymentAccountCommand ToCommand() { return new UpsertPaymentAccountCommand(Provider, Mode, DisplayName, Status, ConfigPublic); } } public sealed class UpsertTenantSecretDto { [Required] [StringLength(80)] public string Purpose { get; set; } = "payment"; [Required] [StringLength(50)] public string Provider { get; set; } = string.Empty; [Required] [StringLength(120)] public string SecretKey { get; set; } = string.Empty; [StringLength(300)] public string SecretRef { get; set; } = string.Empty; public TenantSecretStatus Status { get; set; } = TenantSecretStatus.Active; public JsonElement SecretPayload { get; set; } = JsonDefaults.Object(); public DateTimeOffset? ExpiresAt { get; set; } public UpsertTenantSecretCommand ToCommand() { return new UpsertTenantSecretCommand( Purpose, Provider, SecretKey, SecretRef, Status, SecretPayload, ExpiresAt); } } public sealed class CreateCodeBatchDto { [Required] [StringLength(200)] public string Name { get; set; } = string.Empty; [Range(1, 1000)] public int TotalCount { get; set; } [Range(1, 3650)] public int Days { get; set; } public Guid? RegionId { get; set; } [StringLength(50)] public string? SaleType { get; set; } [StringLength(100)] public string? Channel { get; set; } [Range(0, int.MaxValue)] public int? DefaultUnitPriceCents { get; set; } [Range(0, int.MaxValue)] public int? CostPriceCents { get; set; } [StringLength(1000)] public string? Remark { get; set; } public CreateCodeBatchCommand ToCommand() { return new CreateCodeBatchCommand( Name, TotalCount, Days, RegionId, SaleType, Channel, DefaultUnitPriceCents, CostPriceCents, Remark); } } public sealed class RedeemActivationCodeDto { [Required] [StringLength(100)] public string Code { get; set; } = string.Empty; [Required] public Guid UserId { get; set; } public Guid? RegionId { get; set; } public RedeemActivationCodeCommand ToCommand() { return new RedeemActivationCodeCommand(Code, UserId, RegionId); } } public sealed class UpsertPointTaskDto { public Guid? Id { get; set; } [Required] [StringLength(100)] public string TaskKey { get; set; } = string.Empty; [Required] [StringLength(200)] public string Title { get; set; } = string.Empty; [StringLength(1000)] public string? Description { get; set; } public PointActivityTaskType TaskType { get; set; } = PointActivityTaskType.Manual; public PointActivityTaskStatus Status { get; set; } = PointActivityTaskStatus.Active; [Range(1, int.MaxValue)] public int Points { get; set; } [Range(1, 1000)] public int MaxClaimsPerUser { get; set; } = 1; public DateTimeOffset? StartsAt { get; set; } public DateTimeOffset? EndsAt { get; set; } public int SortOrder { get; set; } public JsonElement Rules { get; set; } = JsonDefaults.Object(); public JsonElement Metadata { get; set; } = JsonDefaults.Object(); public UpsertPointTaskCommand ToCommand() { return new UpsertPointTaskCommand( Id, TaskKey, Title, Description, TaskType, Status, Points, MaxClaimsPerUser, StartsAt, EndsAt, SortOrder, Rules, Metadata); } } public sealed class UpsertPointExchangeItemDto { public Guid? Id { get; set; } public Guid? RegionId { get; set; } [Required] [StringLength(100)] public string ItemKey { get; set; } = string.Empty; [Required] [StringLength(200)] public string Name { get; set; } = string.Empty; [StringLength(1000)] public string? Description { get; set; } public PointExchangeItemType ItemType { get; set; } = PointExchangeItemType.Entitlement; public PointExchangeItemStatus Status { get; set; } = PointExchangeItemStatus.Active; [Range(1, int.MaxValue)] public int PointsCost { get; set; } [Range(0, int.MaxValue)] public int? Stock { get; set; } [Range(0, 3650)] public int? Days { get; set; } public int SortOrder { get; set; } public DateTimeOffset? StartsAt { get; set; } public DateTimeOffset? EndsAt { get; set; } public JsonElement FulfillmentPayload { get; set; } = JsonDefaults.Object(); public JsonElement Metadata { get; set; } = JsonDefaults.Object(); public UpsertPointExchangeItemCommand ToCommand() { return new UpsertPointExchangeItemCommand( Id, RegionId, ItemKey, Name, Description, ItemType, Status, PointsCost, Stock, Days, SortOrder, StartsAt, EndsAt, FulfillmentPayload, Metadata); } } public sealed class UpdatePointExchangeOrderStatusDto { [Required] public Guid OrderId { get; set; } public PointExchangeOrderStatus Status { get; set; } public UpdatePointExchangeOrderStatusCommand ToCommand() { return new UpdatePointExchangeOrderStatusCommand(OrderId, Status); } } public sealed class UpsertTenantCouponDto { public Guid? Id { get; set; } [Required] [StringLength(100)] public string Code { get; set; } = string.Empty; public Guid? PlanId { get; set; } public DiscountType DiscountType { get; set; } = DiscountType.Fixed; [Range(typeof(decimal), "0.01", "999999")] public decimal DiscountValue { get; set; } public DateTimeOffset? ValidFrom { get; set; } public DateTimeOffset? ValidTo { get; set; } [Range(1, int.MaxValue)] public int? MaxUses { get; set; } [StringLength(50)] public string? Source { get; set; } [StringLength(1000)] public string? Remark { get; set; } public UpsertCouponCommand ToCommand() { return new UpsertCouponCommand( Id, Code, PlanId, DiscountType, DiscountValue, ValidFrom, ValidTo, MaxUses, Source, Remark); } }