Files
yara724api/src/common/validators/repair-line-amount-toman.validator.ts
2026-05-20 11:08:47 +03:30

67 lines
2.1 KiB
TypeScript

import {
registerDecorator,
ValidationArguments,
ValidationOptions,
ValidatorConstraint,
ValidatorConstraintInterface,
} from "class-validator";
import {
REPAIR_LINE_AMOUNT_TOMAN,
} from "src/constants/repair-amount-limits";
import { parseMoneyAmountToman } from "src/utils/unicode-digits";
export type RepairLineAmountTomanOptions = {
/** When true, `0` is valid (e.g. expert `price` / `salary` split where one side is zero). */
allowZero?: boolean;
};
@ValidatorConstraint({ name: "isRepairLineAmountToman", async: false })
export class IsRepairLineAmountTomanConstraint
implements ValidatorConstraintInterface
{
validate(value: unknown, args: ValidationArguments): boolean {
const [minToman, maxToman, allowZero] = args.constraints as [
number,
number,
boolean | undefined,
];
if (value == null || value === "") return true;
const amount = parseMoneyAmountToman(value);
if (amount == null) return false;
if (allowZero && amount === 0) return true;
return amount >= minToman && amount <= maxToman;
}
defaultMessage(args: ValidationArguments): string {
const [minToman, maxToman, allowZero] = args.constraints as [
number,
number,
boolean | undefined,
];
const zeroHint = allowZero ? " Use 0 where one side of price/salary is unused." : "";
return (
`Amount must be in Toman between ${minToman.toLocaleString("en-US")} and ${maxToman.toLocaleString("en-US")}.${zeroHint}`
);
}
}
/** Optional repair-line amount in Toman (digits only after unicode normalize). */
export function IsRepairLineAmountToman(
options?: ValidationOptions & RepairLineAmountTomanOptions,
) {
const { allowZero, ...validationOptions } = options ?? {};
return (object: object, propertyName: string) => {
registerDecorator({
target: object.constructor,
propertyName,
options: validationOptions,
constraints: [
REPAIR_LINE_AMOUNT_TOMAN.MIN,
REPAIR_LINE_AMOUNT_TOMAN.MAX,
allowZero === true,
],
validator: IsRepairLineAmountTomanConstraint,
});
};
}