forked from Yara724/api
Fixed daqi being enforced on REPAIR
This commit is contained in:
@@ -43,4 +43,22 @@ describe("SubmitExpertReplyV2Dto", () => {
|
|||||||
|
|
||||||
expect(await validate(dto)).toHaveLength(0);
|
expect(await validate(dto)).toHaveLength(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("accepts a repair part without daghi", async () => {
|
||||||
|
const dto = plainToInstance(SubmitExpertReplyV2Dto, {
|
||||||
|
description: "Damage assessment",
|
||||||
|
parts: [
|
||||||
|
{
|
||||||
|
partId: 201,
|
||||||
|
typeOfDamage: TypeOfDamage.Repair,
|
||||||
|
price: "10000",
|
||||||
|
salary: "0",
|
||||||
|
totalPayment: "10000",
|
||||||
|
factorNeeded: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(await validate(dto)).toHaveLength(0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -94,11 +94,17 @@ export class PartPricingV2Dto {
|
|||||||
@IsRepairLineAmountToman({ allowZero: true })
|
@IsRepairLineAmountToman({ allowZero: true })
|
||||||
totalPayment: string;
|
totalPayment: string;
|
||||||
|
|
||||||
@ApiProperty({ type: DaghiDetailsV2Dto })
|
@ApiPropertyOptional({
|
||||||
|
type: DaghiDetailsV2Dto,
|
||||||
|
description: "Required for change lines; omit for repair lines.",
|
||||||
|
})
|
||||||
|
@ValidateIf(
|
||||||
|
(part: PartPricingV2Dto) => part.typeOfDamage === TypeOfDamage.Change,
|
||||||
|
)
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@ValidateNested()
|
@ValidateNested()
|
||||||
@Type(() => DaghiDetailsV2Dto)
|
@Type(() => DaghiDetailsV2Dto)
|
||||||
daghi: DaghiDetailsV2Dto;
|
daghi?: DaghiDetailsV2Dto;
|
||||||
|
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
example: false,
|
example: false,
|
||||||
|
|||||||
@@ -27,6 +27,31 @@ function createService() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe("ExpertClaimService expert-reply pricing", () => {
|
describe("ExpertClaimService expert-reply pricing", () => {
|
||||||
|
it("allows a repair line without daghi and removes a stray daghi payload", () => {
|
||||||
|
const service = createService() as any;
|
||||||
|
|
||||||
|
expect(
|
||||||
|
service.validateAndNormalizeDaghiForExpertReplyV2([
|
||||||
|
{
|
||||||
|
partId: 201,
|
||||||
|
typeOfDamage: TypeOfDamage.Repair,
|
||||||
|
price: "10000",
|
||||||
|
salary: "0",
|
||||||
|
totalPayment: "10000",
|
||||||
|
daghi: { option: DaghiOption.NO_VALUE },
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
).toEqual([
|
||||||
|
{
|
||||||
|
partId: 201,
|
||||||
|
typeOfDamage: TypeOfDamage.Repair,
|
||||||
|
price: "10000",
|
||||||
|
salary: "0",
|
||||||
|
totalPayment: "10000",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
it("rejects a blank pricing line on the legacy submit endpoint before changing status", async () => {
|
it("rejects a blank pricing line on the legacy submit endpoint before changing status", async () => {
|
||||||
const service = createService() as any;
|
const service = createService() as any;
|
||||||
const findAndUpdate = jest.fn();
|
const findAndUpdate = jest.fn();
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ import { ClaimFactorsImageDbService } from "src/claim-request-management/entites
|
|||||||
import { ClaimRequiredDocumentDbService } from "src/claim-request-management/entites/db-service/claim-required-document.db.service";
|
import { ClaimRequiredDocumentDbService } from "src/claim-request-management/entites/db-service/claim-required-document.db.service";
|
||||||
import { FactorStatus } from "src/Types&Enums/claim-request-management/factor-status.enum";
|
import { FactorStatus } from "src/Types&Enums/claim-request-management/factor-status.enum";
|
||||||
import { DaghiOption } from "src/Types&Enums/claim-request-management/daghi-option.enum";
|
import { DaghiOption } from "src/Types&Enums/claim-request-management/daghi-option.enum";
|
||||||
|
import { TypeOfDamage } from "src/Types&Enums/claim-request-management/type-of-damage.enum";
|
||||||
import { BranchDbService } from "src/client/entities/db-service/branch.db.service";
|
import { BranchDbService } from "src/client/entities/db-service/branch.db.service";
|
||||||
import { ClaimSubmitResendV2Dto } from "./dto/expert-claim-v2.dto";
|
import { ClaimSubmitResendV2Dto } from "./dto/expert-claim-v2.dto";
|
||||||
import { BlameRequestDbService } from "src/request-management/entities/db-service/blame-request.db.service";
|
import { BlameRequestDbService } from "src/request-management/entities/db-service/blame-request.db.service";
|
||||||
@@ -947,6 +948,7 @@ export class ExpertClaimService {
|
|||||||
parts: import("./dto/expert-claim-v2.dto").PartPricingV2Dto[],
|
parts: import("./dto/expert-claim-v2.dto").PartPricingV2Dto[],
|
||||||
) {
|
) {
|
||||||
for (const part of parts) {
|
for (const part of parts) {
|
||||||
|
if (part.typeOfDamage === TypeOfDamage.Repair) continue;
|
||||||
if (!part.daghi || !part.daghi.option) {
|
if (!part.daghi || !part.daghi.option) {
|
||||||
throw new BadRequestException(
|
throw new BadRequestException(
|
||||||
`Daghi option is required for part ${part.partId}`,
|
`Daghi option is required for part ${part.partId}`,
|
||||||
@@ -972,16 +974,23 @@ export class ExpertClaimService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return parts.map((part) => ({
|
return parts.map((part) => {
|
||||||
...part,
|
if (part.typeOfDamage === TypeOfDamage.Repair) {
|
||||||
daghi: {
|
const { daghi: _daghi, ...repairPart } = part;
|
||||||
option: part.daghi.option,
|
return repairPart;
|
||||||
...(part.daghi.price && { price: part.daghi.price }),
|
}
|
||||||
...(part.daghi.branchId && Types.ObjectId.isValid(part.daghi.branchId) && {
|
return {
|
||||||
branchId: new Types.ObjectId(part.daghi.branchId),
|
...part,
|
||||||
}),
|
daghi: {
|
||||||
},
|
option: part.daghi!.option,
|
||||||
}));
|
...(part.daghi!.price && { price: part.daghi!.price }),
|
||||||
|
...(part.daghi!.branchId &&
|
||||||
|
Types.ObjectId.isValid(part.daghi!.branchId) && {
|
||||||
|
branchId: new Types.ObjectId(part.daghi!.branchId),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private findClosestCar(input: string, cars: { carName: string }[]) {
|
private findClosestCar(input: string, cars: { carName: string }[]) {
|
||||||
@@ -1711,6 +1720,7 @@ export class ExpertClaimService {
|
|||||||
// Validate daghi fields
|
// Validate daghi fields
|
||||||
if (reply.parts && reply.parts.length > 0) {
|
if (reply.parts && reply.parts.length > 0) {
|
||||||
for (const part of reply.parts) {
|
for (const part of reply.parts) {
|
||||||
|
if (part.typeOfDamage === TypeOfDamage.Repair) continue;
|
||||||
if (!part.daghi || !part.daghi.option) {
|
if (!part.daghi || !part.daghi.option) {
|
||||||
throw new BadRequestException(
|
throw new BadRequestException(
|
||||||
`Daghi option is required for part ${part.partId}`,
|
`Daghi option is required for part ${part.partId}`,
|
||||||
@@ -1758,16 +1768,22 @@ export class ExpertClaimService {
|
|||||||
: ClaimStepsEnum.WaitingForUserToReact;
|
: ClaimStepsEnum.WaitingForUserToReact;
|
||||||
|
|
||||||
// Process parts: convert branchId string to ObjectId if present
|
// Process parts: convert branchId string to ObjectId if present
|
||||||
const processedParts = reply.parts.map((part) => ({
|
const processedParts = reply.parts.map((part) => {
|
||||||
...part,
|
if (part.typeOfDamage === TypeOfDamage.Repair) {
|
||||||
daghi: {
|
const { daghi: _daghi, ...repairPart } = part;
|
||||||
option: part.daghi.option,
|
return repairPart;
|
||||||
...(part.daghi.price && { price: part.daghi.price }),
|
}
|
||||||
...(part.daghi.branchId && {
|
return {
|
||||||
branchId: new Types.ObjectId(part.daghi.branchId),
|
...part,
|
||||||
}),
|
daghi: {
|
||||||
},
|
option: part.daghi!.option,
|
||||||
}));
|
...(part.daghi!.price && { price: part.daghi!.price }),
|
||||||
|
...(part.daghi!.branchId && {
|
||||||
|
branchId: new Types.ObjectId(part.daghi!.branchId),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
const expertProfileSnapshot = await this.snapshotDamageExpert(userId.sub);
|
const expertProfileSnapshot = await this.snapshotDamageExpert(userId.sub);
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,20 @@ describe("getExpertReplyPricingValidationError", () => {
|
|||||||
).toBeNull();
|
).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("accepts a repair line without daghi", () => {
|
||||||
|
expect(
|
||||||
|
getExpertReplyPricingValidationError([
|
||||||
|
{
|
||||||
|
partId: 201,
|
||||||
|
typeOfDamage: TypeOfDamage.Repair,
|
||||||
|
price: "10000",
|
||||||
|
salary: "0",
|
||||||
|
totalPayment: "10000",
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
it("rejects a repair line without a price", () => {
|
it("rejects a repair line without a price", () => {
|
||||||
expect(
|
expect(
|
||||||
getExpertReplyPricingValidationError([
|
getExpertReplyPricingValidationError([
|
||||||
|
|||||||
@@ -42,9 +42,11 @@ export function getExpertReplyPricingValidationError(
|
|||||||
return `${label} requires typeOfDamage to be either '${TypeOfDamage.Repair}' or '${TypeOfDamage.Change}'.`;
|
return `${label} requires typeOfDamage to be either '${TypeOfDamage.Repair}' or '${TypeOfDamage.Change}'.`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const daghi = part.daghi;
|
||||||
if (
|
if (
|
||||||
!part.daghi ||
|
part.typeOfDamage === TypeOfDamage.Change &&
|
||||||
!Object.values(DaghiOption).includes(part.daghi.option as DaghiOption)
|
(!daghi ||
|
||||||
|
!Object.values(DaghiOption).includes(daghi.option as DaghiOption))
|
||||||
) {
|
) {
|
||||||
return `${label} requires a valid daghi option.`;
|
return `${label} requires a valid daghi option.`;
|
||||||
}
|
}
|
||||||
@@ -52,7 +54,7 @@ export function getExpertReplyPricingValidationError(
|
|||||||
const price = parseMoneyAmountToman(part.price);
|
const price = parseMoneyAmountToman(part.price);
|
||||||
const salary = parseMoneyAmountToman(part.salary);
|
const salary = parseMoneyAmountToman(part.salary);
|
||||||
const totalPayment = parseMoneyAmountToman(part.totalPayment);
|
const totalPayment = parseMoneyAmountToman(part.totalPayment);
|
||||||
const daghiPrice = parseMoneyAmountToman(part.daghi.price);
|
const daghiPrice = parseMoneyAmountToman(daghi?.price);
|
||||||
const hasPrice =
|
const hasPrice =
|
||||||
part.price != null &&
|
part.price != null &&
|
||||||
(typeof part.price !== "string" || part.price.trim() !== "");
|
(typeof part.price !== "string" || part.price.trim() !== "");
|
||||||
@@ -80,7 +82,7 @@ export function getExpertReplyPricingValidationError(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
part.daghi.option === DaghiOption.RECYCLED_PARTS_VALUE &&
|
daghi?.option === DaghiOption.RECYCLED_PARTS_VALUE &&
|
||||||
(daghiPrice === null ||
|
(daghiPrice === null ||
|
||||||
daghiPrice < REPAIR_LINE_AMOUNT_TOMAN.MIN ||
|
daghiPrice < REPAIR_LINE_AMOUNT_TOMAN.MIN ||
|
||||||
daghiPrice > REPAIR_LINE_AMOUNT_TOMAN.MAX)
|
daghiPrice > REPAIR_LINE_AMOUNT_TOMAN.MAX)
|
||||||
|
|||||||
Reference in New Issue
Block a user