Sprint 2 - Sales Frontend: - Add frontend services, hooks, and pages for Sales module - Update router with Sales routes Sprint 3 - Commissions Backend: - Add Commissions module with entities, DTOs, services, controllers - Add DDL schema for commissions tables - Register CommissionsModule in AppModule Sprint 4 - Commissions Frontend: - Add frontend services, hooks, and pages for Commissions module - Add dashboard, schemes, entries, periods, and my-earnings pages - Update router with Commissions routes Update submodule references: backend, database, frontend Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
104 lines
2.6 KiB
TypeScript
104 lines
2.6 KiB
TypeScript
import {
|
|
IsString,
|
|
IsOptional,
|
|
IsEnum,
|
|
IsNumber,
|
|
IsBoolean,
|
|
IsArray,
|
|
ValidateNested,
|
|
Min,
|
|
Max,
|
|
IsUUID,
|
|
} from 'class-validator';
|
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
import { Type } from 'class-transformer';
|
|
import { SchemeType, AppliesTo, TierConfig } from '../entities/commission-scheme.entity';
|
|
|
|
export class TierConfigDto {
|
|
@ApiProperty({ description: 'Tier lower bound (inclusive)' })
|
|
@IsNumber()
|
|
@Min(0)
|
|
from: number;
|
|
|
|
@ApiPropertyOptional({ description: 'Tier upper bound (exclusive), null for unlimited' })
|
|
@IsOptional()
|
|
@IsNumber()
|
|
@Min(0)
|
|
to: number | null;
|
|
|
|
@ApiProperty({ description: 'Commission rate for this tier (0-100)' })
|
|
@IsNumber()
|
|
@Min(0)
|
|
@Max(100)
|
|
rate: number;
|
|
}
|
|
|
|
export class CreateSchemeDto {
|
|
@ApiProperty({ description: 'Scheme name' })
|
|
@IsString()
|
|
name: string;
|
|
|
|
@ApiPropertyOptional({ description: 'Scheme description' })
|
|
@IsOptional()
|
|
@IsString()
|
|
description?: string;
|
|
|
|
@ApiProperty({ enum: SchemeType, description: 'Commission calculation type', default: SchemeType.PERCENTAGE })
|
|
@IsEnum(SchemeType)
|
|
type: SchemeType;
|
|
|
|
@ApiPropertyOptional({ description: 'Commission rate for percentage type (0-100)', default: 0 })
|
|
@IsOptional()
|
|
@IsNumber()
|
|
@Min(0)
|
|
@Max(100)
|
|
rate?: number;
|
|
|
|
@ApiPropertyOptional({ description: 'Fixed commission amount', default: 0 })
|
|
@IsOptional()
|
|
@IsNumber()
|
|
@Min(0)
|
|
fixed_amount?: number;
|
|
|
|
@ApiPropertyOptional({ description: 'Tier configurations for tiered type', type: [TierConfigDto] })
|
|
@IsOptional()
|
|
@IsArray()
|
|
@ValidateNested({ each: true })
|
|
@Type(() => TierConfigDto)
|
|
tiers?: TierConfig[];
|
|
|
|
@ApiPropertyOptional({ enum: AppliesTo, description: 'What the commission applies to', default: AppliesTo.ALL })
|
|
@IsOptional()
|
|
@IsEnum(AppliesTo)
|
|
applies_to?: AppliesTo;
|
|
|
|
@ApiPropertyOptional({ description: 'Product IDs when applies_to is "products"', type: [String] })
|
|
@IsOptional()
|
|
@IsArray()
|
|
@IsUUID('4', { each: true })
|
|
product_ids?: string[];
|
|
|
|
@ApiPropertyOptional({ description: 'Category IDs when applies_to is "categories"', type: [String] })
|
|
@IsOptional()
|
|
@IsArray()
|
|
@IsUUID('4', { each: true })
|
|
category_ids?: string[];
|
|
|
|
@ApiPropertyOptional({ description: 'Minimum sale amount to qualify for commission', default: 0 })
|
|
@IsOptional()
|
|
@IsNumber()
|
|
@Min(0)
|
|
min_amount?: number;
|
|
|
|
@ApiPropertyOptional({ description: 'Maximum commission per sale (cap)' })
|
|
@IsOptional()
|
|
@IsNumber()
|
|
@Min(0)
|
|
max_amount?: number;
|
|
|
|
@ApiPropertyOptional({ description: 'Whether the scheme is active', default: true })
|
|
@IsOptional()
|
|
@IsBoolean()
|
|
is_active?: boolean;
|
|
}
|