1
0
forked from Yara724/api

Merge pull request 'refresh script modified' (#105) from s.hajizadeh/yara724api:main into main

Reviewed-on: Yara724/api#105
This commit is contained in:
2026-06-01 18:14:57 +03:30

View File

@@ -1,8 +1,9 @@
#!/usr/bin/env node #!/usr/bin/env node
/* /*
* One-time script to replace mocked blameCases party vehicle inquiry data with * One-time script to replace mocked blameCases party vehicle inquiry data.
* Tejarat block inquiry responses. * THIRD_PARTY cases use Tejarat block inquiry; CAR_BODY cases use both
* Tejarat third-party block inquiry and car-body inquiry.
* *
* Defaults to DRY_RUN=true. Set DRY_RUN=false to write changes. * Defaults to DRY_RUN=true. Set DRY_RUN=false to write changes.
*/ */
@@ -150,20 +151,26 @@ async function main() {
const party = parties[index]; const party = parties[index];
const partyLabel = `${label} parties[${index}] role=${party && party.role ? party.role : "-"}`; const partyLabel = `${label} parties[${index}] role=${party && party.role ? party.role : "-"}`;
const input = buildInquiryInput(doc, party); const input = buildInquiryInputs(doc, party);
if (!input.ok) { if (!input.ok) {
summary.partiesSkipped += 1; summary.partiesSkipped += 1;
console.warn(`[skip] ${partyLabel}: ${input.reason}`); console.warn(`[skip] ${partyLabel}: ${input.reason}`);
continue; continue;
} }
console.log(`[request] ${partyLabel} body=${JSON.stringify(input.body)}`); let nextParty = party;
let partyChanged = false;
for (const request of input.requests) {
console.log(
`[request] ${partyLabel} type=${request.type} body=${JSON.stringify(request.body)}`,
);
try { try {
const inquiryResponse = await inquiryWithRetry(doc.type, input.body); const inquiryResponse = await inquiryWithRetry(request.type, request.body);
const successful = isInquirySuccessful(doc.type, inquiryResponse); const successful = isInquirySuccessful(request.type, inquiryResponse);
console.log( console.log(
`[response] ${partyLabel} successful=${successful} body=${JSON.stringify(inquiryResponse)}`, `[response] ${partyLabel} type=${request.type} successful=${successful} body=${JSON.stringify(inquiryResponse)}`,
); );
if (!successful) { if (!successful) {
@@ -171,12 +178,18 @@ async function main() {
continue; continue;
} }
parties[index] = applyInquiryToParty(doc.type, party, inquiryResponse, input.plate); nextParty = applyInquiryToParty(request.type, nextParty, inquiryResponse, input.plate);
summary.partiesInquired += 1; summary.partiesInquired += 1;
docChanged = true; partyChanged = true;
} catch (error) { } catch (error) {
summary.partiesFailed += 1; summary.partiesFailed += 1;
console.error(`[error] ${partyLabel}: ${error.message}`); console.error(`[error] ${partyLabel} type=${request.type}: ${error.message}`);
}
}
if (partyChanged) {
parties[index] = nextParty;
docChanged = true;
} }
} }
@@ -207,7 +220,7 @@ async function main() {
console.log(`[done] ${JSON.stringify(summary)}`); console.log(`[done] ${JSON.stringify(summary)}`);
} }
function buildInquiryInput(doc, party) { function buildInquiryInputs(doc, party) {
if (!party || typeof party !== "object") return { ok: false, reason: "party is empty" }; if (!party || typeof party !== "object") return { ok: false, reason: "party is empty" };
if (!party.vehicle || typeof party.vehicle !== "object") { if (!party.vehicle || typeof party.vehicle !== "object") {
return { ok: false, reason: "party.vehicle is missing" }; return { ok: false, reason: "party.vehicle is missing" };
@@ -224,24 +237,31 @@ function buildInquiryInput(doc, party) {
const serialLetter = NUMBER_TO_LETTER[String(plate.Plk2)] || cleanString(plate.Plk2); const serialLetter = NUMBER_TO_LETTER[String(plate.Plk2)] || cleanString(plate.Plk2);
if (!serialLetter) return { ok: false, reason: `no Persian letter mapping for Plk2=${plate.Plk2}` }; if (!serialLetter) return { ok: false, reason: `no Persian letter mapping for Plk2=${plate.Plk2}` };
if (doc.type === "CAR_BODY") {
return {
ok: true,
plate,
body: {
part1: toNumber(plate.Plk1),
part2: serialLetter,
part3: toNumber(plate.Plk3),
part4: toNumber(plate.PlkSrl),
nationalCode,
},
};
}
if (doc.type === "THIRD_PARTY") { if (doc.type === "THIRD_PARTY") {
return { return {
ok: true, ok: true,
plate, plate,
requests: [buildThirdPartyRequest(plate, serialLetter, nationalCode)],
};
}
if (doc.type === "CAR_BODY") {
return {
ok: true,
plate,
requests: [
buildThirdPartyRequest(plate, serialLetter, nationalCode),
buildCarBodyRequest(plate, serialLetter, nationalCode),
],
};
}
return { ok: false, reason: `unsupported type=${doc.type}` };
}
function buildThirdPartyRequest(plate, serialLetter, nationalCode) {
return {
type: "THIRD_PARTY",
body: { body: {
leftTwoDigits: String(plate.Plk1), leftTwoDigits: String(plate.Plk1),
serialLetter, serialLetter,
@@ -250,9 +270,19 @@ function buildInquiryInput(doc, party) {
nationalCode, nationalCode,
}, },
}; };
} }
return { ok: false, reason: `unsupported type=${doc.type}` }; function buildCarBodyRequest(plate, serialLetter, nationalCode) {
return {
type: "CAR_BODY",
body: {
part1: toNumber(plate.Plk1),
part2: serialLetter,
part3: toNumber(plate.Plk3),
part4: toNumber(plate.PlkSrl),
nationalCode,
},
};
} }
function parsePlateId(plateId) { function parsePlateId(plateId) {
@@ -377,52 +407,34 @@ function isInquirySuccessful(type, response) {
} }
function applyInquiryToParty(type, party, response, originalPlate) { function applyInquiryToParty(type, party, response, originalPlate) {
if (type === "CAR_BODY") return applyCarBodyInquiryToParty(party, response, originalPlate);
return applyThirdPartyInquiryToParty(party, response, originalPlate);
}
function applyThirdPartyInquiryToParty(party, response, originalPlate) {
const next = clone(party); const next = clone(party);
if (!next.vehicle) next.vehicle = {}; if (!next.vehicle) next.vehicle = {};
if (!next.insurance) next.insurance = {}; if (!next.insurance) next.insurance = {};
const mapped = type === "CAR_BODY" const mapped = normalizeThirdPartyResponse(response, originalPlate);
? normalizeCarBodyResponse(response, originalPlate)
: normalizeThirdPartyResponse(response, originalPlate);
const plateId = buildPlateId(originalPlate); const plateId = buildPlateId(originalPlate);
next.vehicle.plateId = plateId || next.vehicle.plateId; next.vehicle.plateId = plateId || next.vehicle.plateId;
next.vehicle.inquiry = { next.vehicle.inquiry = {
source: type === "CAR_BODY" ? "TEJARAT_CAR_BODY_BLOCK_INQUIRY" : "TEJARAT_BLOCK_INQUIRY", source: "TEJARAT_BLOCK_INQUIRY",
raw: type === "CAR_BODY" ? normalizeCarBodyRaw(response, originalPlate) : response, raw: response,
mapped, mapped,
refreshedAt: new Date().toISOString(), refreshedAt: new Date().toISOString(),
}; };
if (party.vehicle && party.vehicle.inquiry && party.vehicle.inquiry.carBody) {
if (type === "CAR_BODY") { next.vehicle.inquiry.carBody = party.vehicle.inquiry.carBody;
next.vehicle.inquiry.responseMeta = {
isSuccess: response.isSuccess,
statusCode: response.statusCode,
message: response.message,
};
}
if (type === "CAR_BODY") {
next.vehicle.name = mapped.vehicleSystemTitle || next.vehicle.name;
next.vehicle.type = mapped.vehicleGroupTitle || next.vehicle.type;
next.insurance.policyNumber = mapped.printNumber || next.insurance.policyNumber;
next.insurance.company = mapped.companyName || next.insurance.company;
next.insurance.startDate = mapped.beginDate || next.insurance.startDate;
next.insurance.endDate = mapped.endDate || next.insurance.endDate;
next.insurance.carBodyInsurance = {
policyNumber: mapped.printNumber,
startDate: mapped.beginDate,
endDate: mapped.endDate,
insurerCompany: mapped.companyName,
coverages: Array.isArray(mapped.coverages) ? mapped.coverages : [],
};
return next;
} }
next.vehicle.name = mapped.vehiclePersianName || mapped.MapTypNam || "اطلاعات این گزینه در استعلام موجود نیست"; next.vehicle.name = mapped.vehiclePersianName || mapped.MapTypNam || "اطلاعات این گزینه در استعلام موجود نیست";
next.vehicle.type = mapped.persianCarType || mapped.MapUsageName || next.vehicle.type; next.vehicle.type = mapped.persianCarType || mapped.MapUsageName || next.vehicle.type;
next.insurance.policyNumber = mapped.insuranceNumber || next.insurance.policyNumber; next.insurance.policyNumber =
mapped.LastCompanyDocumentNumber || mapped.insuranceNumber || next.insurance.policyNumber;
next.insurance.company = mapped.companyPersianName || next.insurance.company; next.insurance.company = mapped.companyPersianName || next.insurance.company;
next.insurance.financialCeiling = mapped.financeCoverage || next.insurance.financialCeiling; next.insurance.financialCeiling = mapped.financeCoverage || next.insurance.financialCeiling;
next.insurance.startDate = mapped.persianStartDate || next.insurance.startDate; next.insurance.startDate = mapped.persianStartDate || next.insurance.startDate;
@@ -430,6 +442,50 @@ function applyInquiryToParty(type, party, response, originalPlate) {
return next; return next;
} }
function applyCarBodyInquiryToParty(party, response, originalPlate) {
const next = clone(party);
if (!next.vehicle) next.vehicle = {};
if (!next.insurance) next.insurance = {};
const mapped = normalizeCarBodyResponse(response, originalPlate);
const plateId = buildPlateId(originalPlate);
next.vehicle.plateId = plateId || next.vehicle.plateId;
if (!next.vehicle.inquiry || typeof next.vehicle.inquiry !== "object") {
next.vehicle.inquiry = {};
}
next.vehicle.inquiry.carBody = {
source: "TEJARAT_CAR_BODY_INQUIRY",
raw: response,
mapped,
refreshedAt: new Date().toISOString(),
};
next.vehicle.name = mapped.vehicleSystemTitle || next.vehicle.name;
next.vehicle.type = mapped.vehicleGroupTitle || next.vehicle.type;
next.insurance.carBodyInsurance = {
policyNumber: mapped.policyNumber,
companyId: mapped.companyId,
companyName: mapped.CompanyName,
insurerName: mapped.insurerName,
insurerNationalCode: mapped.insurerNationalCode,
ownerNationalCode: mapped.ownerNationalCode,
chassisNumber: mapped.chassisNumber,
vin: mapped.vin,
motorNumber: mapped.motorNumber,
vehicleGroup: mapped.vehicleGroupTitle,
vehicleSystem: mapped.vehicleSystemTitle,
startDate: mapped.StartDate,
endDate: mapped.EndDate,
issueDate: mapped.IssueDate,
noLossYearsCount: mapped.noLossYearsCount,
lossDocuments: Array.isArray(mapped.lossDocuments) ? mapped.lossDocuments : [],
hasEndorsement: mapped.hasEndorsement,
};
return next;
}
function buildPlateId(plate) { function buildPlateId(plate) {
if (!plate) return ""; if (!plate) return "";
const serialLetter = NUMBER_TO_LETTER[String(plate.Plk2)] || cleanString(plate.Plk2); const serialLetter = NUMBER_TO_LETTER[String(plate.Plk2)] || cleanString(plate.Plk2);
@@ -454,24 +510,19 @@ function normalizeThirdPartyResponse(response, originalPlate) {
PlkSrl: toNumber(originalPlate.PlkSrl), PlkSrl: toNumber(originalPlate.PlkSrl),
CompanyName: response.companyPersianName, CompanyName: response.companyPersianName,
CompanyCode: response.companyId, CompanyCode: response.companyId,
LastCompanyDocumentNumber: response.insuranceNumber, LastCompanyDocumentNumber: response.lastCompanyInsuranceNumber || response.insuranceNumber,
FinancialCvrCptl: response.financeCoverage, FinancialCvrCptl: response.financeCoverage,
IssueDate: response.hIsuDte || response.persianStartDate, IssueDate: response.hIsuDte || response.persianStartDate,
SatrtDate: response.persianStartDate, SatrtDate: response.persianStartDate,
EndDate: response.persianEndDate, EndDate: response.persianEndDate,
MapTypNam: response.vehiclePersianName, MapTypNam: response.vehiclePersianName,
MapUsageName: response.MapUsageName, MapUsageName: response.MapUsageName || response.persianCarType,
}; UsageField: response.persianCarType,
} UsageCode: response.usgCod,
VehicleSystemCode: response.vehSysCod,
function normalizeCarBodyRaw(response, originalPlate) { CarGroupCode: response.carGrpCod,
const data = response.data || {}; EdrsJson: Array.isArray(response.edrSes) ? JSON.stringify(response.edrSes) : response.EdrsJson,
return { InsuranceFullName: response.fullname,
...data,
Plk1: toNumber(originalPlate.Plk1),
Plk2: toNumber(originalPlate.Plk2),
Plk3: toNumber(originalPlate.Plk3),
PlkSrl: toNumber(originalPlate.PlkSrl),
}; };
} }
@@ -483,16 +534,24 @@ function normalizeCarBodyResponse(response, originalPlate) {
Plk2: toNumber(originalPlate.Plk2), Plk2: toNumber(originalPlate.Plk2),
Plk3: toNumber(originalPlate.Plk3), Plk3: toNumber(originalPlate.Plk3),
PlkSrl: toNumber(originalPlate.PlkSrl), PlkSrl: toNumber(originalPlate.PlkSrl),
policyNumber: data.printNumber,
CompanyName: data.companyName, CompanyName: data.companyName,
CompanyCode: data.companyId, CompanyCode: data.companyId,
LastCompanyDocumentNumber: data.printNumber, LastCompanyDocumentNumber: data.printNumber,
InsuranceFullName: data.insurerName,
IssueDate: data.issueDate, IssueDate: data.issueDate,
StartDate: data.beginDate,
SatrtDate: data.beginDate, SatrtDate: data.beginDate,
EndDate: data.endDate, EndDate: data.endDate,
EngineNumberField: data.motorNumber,
MtrNum: data.motorNumber, MtrNum: data.motorNumber,
ChassisNumberField: data.chassisNumber,
ShsNum: data.chassisNumber, ShsNum: data.chassisNumber,
VinNumberField: data.vin, VinNumberField: data.vin,
MapTypNam: data.vehicleSystemTitle, MapTypNam: data.vehicleGroupTitle,
isSuccess: response.isSuccess,
statusCode: response.statusCode,
message: response.message,
}; };
} }