Files
yara724api/src/helpers/expert-reply-pricing.ts

60 lines
2.1 KiB
TypeScript

import { REPAIR_LINE_AMOUNT_TOMAN } from "src/constants/repair-amount-limits";
import { parseMoneyAmountToman } from "src/utils/unicode-digits";
type ExpertReplyPricingPart = {
partId?: unknown;
price?: unknown;
salary?: unknown;
totalPayment?: unknown;
};
/**
* Validates the pricing that an expert must provide for every submitted
* damaged-part line. This is deliberately independent of DTO validation:
* legacy endpoints and deployments without a global ValidationPipe call the
* service directly.
*/
export function getExpertReplyPricingValidationError(
parts: unknown,
): string | null {
if (!Array.isArray(parts) || parts.length === 0) {
return "At least one damaged part with pricing is required to submit an expert reply.";
}
for (const [index, rawPart] of parts.entries()) {
const part = rawPart as ExpertReplyPricingPart | null;
const label =
part && part.partId != null && String(part.partId).trim() !== ""
? `Part ${String(part.partId)}`
: `Damaged part ${index + 1}`;
if (!part || typeof part !== "object") {
return `${label} must include price, salary, and totalPayment.`;
}
const price = parseMoneyAmountToman(part.price);
const salary = parseMoneyAmountToman(part.salary);
const totalPayment = parseMoneyAmountToman(part.totalPayment);
const splitAmountIsValid = (amount: number | null) =>
amount !== null &&
(amount === 0 ||
(amount >= REPAIR_LINE_AMOUNT_TOMAN.MIN &&
amount <= REPAIR_LINE_AMOUNT_TOMAN.MAX));
const totalIsValid =
totalPayment !== null &&
totalPayment >= REPAIR_LINE_AMOUNT_TOMAN.MIN &&
totalPayment <= REPAIR_LINE_AMOUNT_TOMAN.MAX;
if (
!splitAmountIsValid(price) ||
!splitAmountIsValid(salary) ||
!totalIsValid
) {
return `${label} requires valid price, salary, and totalPayment. Price and salary may be 0; totalPayment must be between ${REPAIR_LINE_AMOUNT_TOMAN.MIN.toLocaleString("en-US")} and ${REPAIR_LINE_AMOUNT_TOMAN.MAX.toLocaleString("en-US")} Toman.`;
}
}
return null;
}