forked from Yara724/api
Merge pull request 'Added required documents for blame, added 2 sms' (#37) from s.yahyaee/yara724-api:main into main
Reviewed-on: Yara724/api#37
This commit is contained in:
@@ -5,7 +5,8 @@ export enum ResendItemType {
|
|||||||
CAR_CERTIFICATE = "carCertificate",
|
CAR_CERTIFICATE = "carCertificate",
|
||||||
DRIVING_LICENSE = "drivingLicense",
|
DRIVING_LICENSE = "drivingLicense",
|
||||||
CAR_GREEN_CARD = "carGreenCard",
|
CAR_GREEN_CARD = "carGreenCard",
|
||||||
|
PLATE = "plate",
|
||||||
|
CAR_PLATE = "carPlate",
|
||||||
// Media evidence
|
// Media evidence
|
||||||
VOICE = "voice",
|
VOICE = "voice",
|
||||||
VIDEO = "video",
|
VIDEO = "video",
|
||||||
|
|||||||
@@ -4345,8 +4345,8 @@ export class ClaimRequestManagementService {
|
|||||||
let remaining = 0;
|
let remaining = 0;
|
||||||
|
|
||||||
if (!isResendUpload) {
|
if (!isResendUpload) {
|
||||||
// Check if all documents are uploaded (7 for CAR_BODY, 13 for THIRD_PARTY)
|
// Check if all documents are uploaded (8 for CAR_BODY, 13 for THIRD_PARTY)
|
||||||
const totalDocsRequired = isCarBodyUpload ? 7 : 13;
|
const totalDocsRequired = isCarBodyUpload ? 8 : 13;
|
||||||
const currentDocs = claimCase.requiredDocuments || new Map();
|
const currentDocs = claimCase.requiredDocuments || new Map();
|
||||||
const uploadedCount =
|
const uploadedCount =
|
||||||
(currentDocs instanceof Map ? currentDocs.size : Object.keys(currentDocs).length) + 1;
|
(currentDocs instanceof Map ? currentDocs.size : Object.keys(currentDocs).length) + 1;
|
||||||
|
|||||||
@@ -6,9 +6,16 @@ import { ExpertBlameController } from "./expert-blame.controller";
|
|||||||
import { ExpertBlameV2Controller } from "./expert-blame.v2.controller";
|
import { ExpertBlameV2Controller } from "./expert-blame.v2.controller";
|
||||||
import { ExpertBlameService } from "./expert-blame.service";
|
import { ExpertBlameService } from "./expert-blame.service";
|
||||||
import { RequestManagementModule } from "src/request-management/request-management.module";
|
import { RequestManagementModule } from "src/request-management/request-management.module";
|
||||||
|
import { SmsOrchestrationModule } from "src/sms-orchestration/sms-orchestration.module";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [UsersModule, ClientModule, RequestManagementModule, PlatesModule],
|
imports: [
|
||||||
|
UsersModule,
|
||||||
|
ClientModule,
|
||||||
|
RequestManagementModule,
|
||||||
|
PlatesModule,
|
||||||
|
SmsOrchestrationModule,
|
||||||
|
],
|
||||||
controllers: [ExpertBlameController, ExpertBlameV2Controller],
|
controllers: [ExpertBlameController, ExpertBlameV2Controller],
|
||||||
providers: [ExpertBlameService],
|
providers: [ExpertBlameService],
|
||||||
exports: [ExpertBlameService],
|
exports: [ExpertBlameService],
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import { UserSignDbService } from "src/request-management/entities/db-service/si
|
|||||||
import { RequestManagementService } from "src/request-management/request-management.service";
|
import { RequestManagementService } from "src/request-management/request-management.service";
|
||||||
import { snapshotFromFieldExpert } from "src/helpers/expert-profile-snapshot";
|
import { snapshotFromFieldExpert } from "src/helpers/expert-profile-snapshot";
|
||||||
import { ExpertModel } from "src/users/entities/schema/expert.schema";
|
import { ExpertModel } from "src/users/entities/schema/expert.schema";
|
||||||
|
import { SmsOrchestrationService } from "src/sms-orchestration/sms-orchestration.service";
|
||||||
|
|
||||||
interface CheckedRequestEntry {
|
interface CheckedRequestEntry {
|
||||||
CheckedRequest?: {
|
CheckedRequest?: {
|
||||||
@@ -85,6 +86,7 @@ export class ExpertBlameService {
|
|||||||
private readonly blameDocumentDbService: BlameDocumentDbService,
|
private readonly blameDocumentDbService: BlameDocumentDbService,
|
||||||
private readonly userSignDbService: UserSignDbService,
|
private readonly userSignDbService: UserSignDbService,
|
||||||
private readonly requestManagementService: RequestManagementService,
|
private readonly requestManagementService: RequestManagementService,
|
||||||
|
private readonly smsOrchestrationService: SmsOrchestrationService,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
/** Load immutable profile fields from `expert` for the acting field expert. */
|
/** Load immutable profile fields from `expert` for the acting field expert. */
|
||||||
@@ -946,6 +948,23 @@ export class ExpertBlameService {
|
|||||||
// Update expert stats (reusing existing helper)
|
// Update expert stats (reusing existing helper)
|
||||||
await this.updateDamageExpertStats(actorDetail.sub, requestId, "checked");
|
await this.updateDamageExpertStats(actorDetail.sub, requestId, "checked");
|
||||||
|
|
||||||
|
if (request.type === BlameRequestType.THIRD_PARTY) {
|
||||||
|
const phones = (request.parties || [])
|
||||||
|
.map((p: any) => p?.person?.phoneNumber)
|
||||||
|
.filter((p: unknown): p is string => typeof p === "string" && p.length > 0);
|
||||||
|
const expertLastName =
|
||||||
|
actorDetail?.fullName?.trim()?.split(/\s+/).pop() || "کارشناس";
|
||||||
|
for (const phone of phones) {
|
||||||
|
await this.smsOrchestrationService.sendThirdPartyExpertStartedReviewNotice(
|
||||||
|
{
|
||||||
|
receptor: phone,
|
||||||
|
publicId: request.publicId,
|
||||||
|
expertLastName,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return { _id: requestId, lock: true };
|
return { _id: requestId, lock: true };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof HttpException) throw error;
|
if (error instanceof HttpException) throw error;
|
||||||
|
|||||||
@@ -1182,6 +1182,46 @@ export class RequestManagementService {
|
|||||||
req.workflow.nextStep = undefined;
|
req.workflow.nextStep = undefined;
|
||||||
req.status = CaseStatus.WAITING_FOR_SIGNATURES;
|
req.status = CaseStatus.WAITING_FOR_SIGNATURES;
|
||||||
closedByMutualAgreement = true;
|
closedByMutualAgreement = true;
|
||||||
|
|
||||||
|
if (
|
||||||
|
isSecondThirdParty &&
|
||||||
|
closedByMutualAgreement &&
|
||||||
|
req.status === CaseStatus.WAITING_FOR_SIGNATURES &&
|
||||||
|
req.blameStatus === BlameStatus.AGREED
|
||||||
|
) {
|
||||||
|
const firstIdx = this.getPartyIndex(req, PartyRole.FIRST);
|
||||||
|
const secondIdx = this.getPartyIndex(req, PartyRole.SECOND);
|
||||||
|
const firstPhone = (req.parties?.[firstIdx]?.person as any)?.phoneNumber;
|
||||||
|
const secondPhone = (req.parties?.[secondIdx]?.person as any)?.phoneNumber;
|
||||||
|
const baseUrl = process.env.URL;
|
||||||
|
const token = String(req._id);
|
||||||
|
const targets = [
|
||||||
|
firstPhone
|
||||||
|
? {
|
||||||
|
receptor: firstPhone,
|
||||||
|
link: `${baseUrl}/user?token=${token}`,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
secondPhone
|
||||||
|
? {
|
||||||
|
receptor: secondPhone,
|
||||||
|
link: `${baseUrl}/user2?token=${token}`,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
].filter(
|
||||||
|
(t): t is { receptor: string; link: string } => !!t?.receptor && !!t?.link,
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const target of targets) {
|
||||||
|
await this.smsOrchestrationService.sendThirdPartyAgreementSignNotice(
|
||||||
|
{
|
||||||
|
receptor: target.receptor,
|
||||||
|
publicId: req.publicId,
|
||||||
|
link: target.link,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -94,6 +94,36 @@ export class SmsOrchestrationService implements OnModuleInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async sendThirdPartyAgreementSignNotice(params: {
|
||||||
|
receptor: string;
|
||||||
|
publicId: string;
|
||||||
|
link: string;
|
||||||
|
}): Promise<boolean> {
|
||||||
|
return this.sendTemplate({
|
||||||
|
template: "yara-blame-agreement",
|
||||||
|
receptor: params.receptor,
|
||||||
|
token: params.publicId,
|
||||||
|
token2: params.link,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async sendThirdPartyExpertStartedReviewNotice(
|
||||||
|
params: {
|
||||||
|
receptor: string;
|
||||||
|
publicId: string;
|
||||||
|
expertLastName: string;
|
||||||
|
},
|
||||||
|
): Promise<boolean> {
|
||||||
|
return this.sendTemplate({
|
||||||
|
template:
|
||||||
|
process.env.SMS_TEMPLATE_THIRD_PARTY_EXPERT_LOCK ||
|
||||||
|
"yara-blame-expert-lock",
|
||||||
|
receptor: params.receptor,
|
||||||
|
token: params.publicId,
|
||||||
|
token2: params.expertLastName || "کارشناس",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private async sendTemplate(args: TemplateArgs): Promise<boolean> {
|
private async sendTemplate(args: TemplateArgs): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
await this.smsGatewayService.verifyLookUp(args);
|
await this.smsGatewayService.verifyLookUp(args);
|
||||||
|
|||||||
Reference in New Issue
Block a user