Files
CRM_Montzar/apps/api/src/sales/dto.ts
T
MahdiandCursor 32af147237 Redesign sales goals and forecast with typed targets and live progress.
Match desktop/mobile mockups and compute current amounts, status, and KPIs from real CRM data.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-05 18:38:11 +03:30

173 lines
2.4 KiB
TypeScript

import {
IsIn,
IsNumber,
IsOptional,
IsString,
Max,
MaxLength,
Min,
MinLength,
} from 'class-validator';
import { Type } from 'class-transformer';
const SALES_GOAL_TYPES = [
'sales',
'customer',
'revenue',
'deal',
'activity',
'quality',
] as const;
const SALES_GOAL_STATUSES = [
'in_progress',
'completed',
'needs_attention',
] as const;
export class CreateSalesGoalDto {
@IsString()
@MinLength(2)
@MaxLength(200)
title!: string;
@IsString()
periodStart!: string;
@IsString()
periodEnd!: string;
@Type(() => Number)
@IsNumber()
@Min(0)
targetAmount!: number;
@IsOptional()
@IsString()
@IsIn(SALES_GOAL_TYPES)
type?: string;
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(0)
forecastAmount?: number | null;
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(0)
@Max(100)
probability?: number | null;
@IsOptional()
@IsString()
@MaxLength(8)
currency?: string;
@IsOptional()
@IsString()
@MaxLength(2000)
notes?: string;
@IsOptional()
@IsString()
userId?: string | null;
}
export class UpdateSalesGoalDto {
@IsOptional()
@IsString()
@MinLength(2)
@MaxLength(200)
title?: string;
@IsOptional()
@IsString()
periodStart?: string;
@IsOptional()
@IsString()
periodEnd?: string;
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(0)
targetAmount?: number;
@IsOptional()
@IsString()
@IsIn(SALES_GOAL_TYPES)
type?: string;
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(0)
forecastAmount?: number | null;
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(0)
@Max(100)
probability?: number | null;
@IsOptional()
@IsString()
@MaxLength(8)
currency?: string;
@IsOptional()
@IsString()
@MaxLength(2000)
notes?: string | null;
@IsOptional()
@IsString()
userId?: string | null;
}
export class ForecastQueryDto {
@IsOptional()
@IsString()
from?: string;
@IsOptional()
@IsString()
to?: string;
@IsOptional()
@IsString()
userId?: string;
}
export class ListGoalsQueryDto {
@IsOptional()
@IsString()
from?: string;
@IsOptional()
@IsString()
to?: string;
@IsOptional()
@IsString()
userId?: string;
@IsOptional()
@IsString()
q?: string;
@IsOptional()
@IsString()
@IsIn(SALES_GOAL_STATUSES)
status?: string;
@IsOptional()
@IsString()
@IsIn(SALES_GOAL_TYPES)
type?: string;
}