fix(search): address [object Object], suprafata from folosinte, owner tree separation
- Address: handle street/locality/county as objects (extract .name) Fixes 'Str. [object Object], Feleacu' 'Str. X, Feleacu' - Suprafata: fallback to total area from folosinte endpoint when immovable list and documentation APIs return null - Owners: use tree traversal (nodeId/parentNodeId) to detect radiated inscriptions. Walk up parent chain to check radiationDate/cancelled/ isActive/closed/status on ancestor inscription nodes. - Enhanced logging: first/last 3 partTwoRegs entries + node types for debugging owner structure in Dozzle
This commit is contained in:
@@ -105,13 +105,26 @@ function formatAddress(item?: any) {
|
|||||||
// addressDescription may contain the full text address already
|
// addressDescription may contain the full text address already
|
||||||
if (address.addressDescription) {
|
if (address.addressDescription) {
|
||||||
const desc = String(address.addressDescription).trim();
|
const desc = String(address.addressDescription).trim();
|
||||||
// If it looks like a complete address (has comma or street), use it directly
|
if (desc.length > 3 && !desc.includes("[object")) return desc;
|
||||||
if (desc.length > 3) return desc;
|
|
||||||
}
|
}
|
||||||
if (address.street) parts.push(`Str. ${address.street}`);
|
// street can be a string OR an object { name: "..." }
|
||||||
|
const streetName =
|
||||||
|
typeof address.street === "string"
|
||||||
|
? address.street
|
||||||
|
: address.street?.name ?? "";
|
||||||
|
if (streetName) parts.push(`Str. ${streetName}`);
|
||||||
if (address.buildingNo) parts.push(`Nr. ${address.buildingNo}`);
|
if (address.buildingNo) parts.push(`Nr. ${address.buildingNo}`);
|
||||||
if (address.locality?.name) parts.push(address.locality.name);
|
// locality can also be a string or object
|
||||||
if (address.county?.name) parts.push(`Jud. ${address.county.name}`);
|
const localityName =
|
||||||
|
typeof address.locality === "string"
|
||||||
|
? address.locality
|
||||||
|
: address.locality?.name ?? "";
|
||||||
|
if (localityName) parts.push(localityName);
|
||||||
|
const countyName =
|
||||||
|
typeof address.county === "string"
|
||||||
|
? address.county
|
||||||
|
: address.county?.name ?? "";
|
||||||
|
if (countyName) parts.push(`Jud. ${countyName}`);
|
||||||
return parts.length ? parts.join(", ") : "";
|
return parts.length ? parts.join(", ") : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,15 +311,23 @@ export async function POST(req: Request) {
|
|||||||
let suprafata: number | null = null;
|
let suprafata: number | null = null;
|
||||||
|
|
||||||
// Try multiple area fields
|
// Try multiple area fields
|
||||||
const areaStr = item?.area ?? item?.areaValue ?? item?.areaMP ?? item?.suprafata;
|
const areaStr =
|
||||||
|
item?.area ?? item?.areaValue ?? item?.areaMP ?? item?.suprafata;
|
||||||
if (areaStr != null) {
|
if (areaStr != null) {
|
||||||
const parsed = Number(areaStr);
|
const parsed = Number(areaStr);
|
||||||
if (Number.isFinite(parsed) && parsed > 0) suprafata = parsed;
|
if (Number.isFinite(parsed) && parsed > 0) suprafata = parsed;
|
||||||
}
|
}
|
||||||
// Log raw item keys once for debugging (first item only)
|
// Log raw item keys once for debugging (first item only)
|
||||||
if (results.length === 0) {
|
if (results.length === 0) {
|
||||||
console.log("[search] immovable item keys:", Object.keys(item ?? {}));
|
console.log(
|
||||||
console.log("[search] area fields:", { area: item?.area, areaValue: item?.areaValue, areaMP: item?.areaMP });
|
"[search] immovable item keys:",
|
||||||
|
Object.keys(item ?? {}),
|
||||||
|
);
|
||||||
|
console.log("[search] area fields:", {
|
||||||
|
area: item?.area,
|
||||||
|
areaValue: item?.areaValue,
|
||||||
|
areaMP: item?.areaMP,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Fetch documentation data (CF, proprietari)
|
// 2. Fetch documentation data (CF, proprietari)
|
||||||
@@ -336,40 +357,74 @@ export async function POST(req: Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Extract owners from partTwoRegs — separate active vs cancelled
|
// Extract owners from partTwoRegs — separate active vs cancelled
|
||||||
|
// using tree structure: "P" (person) nodes are children of
|
||||||
|
// inscription nodes. If a parent inscription has radiationDate,
|
||||||
|
// its person entries are former owners.
|
||||||
const activeOwners: string[] = [];
|
const activeOwners: string[] = [];
|
||||||
const cancelledOwners: string[] = [];
|
const cancelledOwners: string[] = [];
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const regs = docResponse?.partTwoRegs ?? [];
|
const regs: any[] = docResponse?.partTwoRegs ?? [];
|
||||||
if (regs.length > 0) {
|
if (regs.length > 0 && results.length === 0) {
|
||||||
console.log("[search] partTwoRegs[0] keys:", Object.keys(regs[0]));
|
console.log(
|
||||||
console.log("[search] partTwoRegs sample:", JSON.stringify(regs[0]).slice(0, 500));
|
"[search] partTwoRegs count:",
|
||||||
|
regs.length,
|
||||||
|
"types:",
|
||||||
|
[...new Set(regs.map((r: any) => r?.nodeType))],
|
||||||
|
);
|
||||||
|
// Log first 3 entries fully
|
||||||
|
regs.slice(0, 3).forEach((r: any, i: number) =>
|
||||||
|
console.log(`[search] partTwoRegs[${i}]:`, JSON.stringify(r).slice(0, 600)),
|
||||||
|
);
|
||||||
|
// Log last 3 entries
|
||||||
|
regs.slice(-3).forEach((r: any, i: number) =>
|
||||||
|
console.log(`[search] partTwoRegs[${regs.length - 3 + i}]:`, JSON.stringify(r).slice(0, 600)),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build nodeId → entry map for tree traversal
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
regs.forEach((reg: any) => {
|
const nodeMap = new Map<string | number, any>();
|
||||||
if (
|
for (const reg of regs) {
|
||||||
String(reg?.nodeType ?? "").toUpperCase() === "P" &&
|
const nid = reg?.nodeId ?? reg?.id;
|
||||||
reg?.nodeName
|
if (nid != null) nodeMap.set(nid, reg);
|
||||||
) {
|
}
|
||||||
const name = String(reg.nodeName).trim();
|
|
||||||
if (!name) return;
|
// Check if an entry or any ancestor is radiated
|
||||||
// Check if this entry is cancelled/radiated
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const isCancelled =
|
const isRadiated = (entry: any): boolean => {
|
||||||
reg?.cancelled === true ||
|
// Direct checks on the entry itself
|
||||||
reg?.isActive === false ||
|
if (entry?.radiationDate != null) return true;
|
||||||
reg?.radiat === true ||
|
if (entry?.cancelled === true) return true;
|
||||||
String(reg?.status ?? "").toUpperCase() === "RADIAT" ||
|
if (entry?.isActive === false) return true;
|
||||||
String(reg?.status ?? "").toUpperCase() === "CANCELLED" ||
|
if (entry?.closed === true) return true;
|
||||||
reg?.radiationDate != null;
|
const st = String(entry?.status ?? "").toUpperCase();
|
||||||
if (isCancelled) {
|
if (st === "RADIAT" || st === "CANCELLED" || st === "CLOSED") return true;
|
||||||
cancelledOwners.push(name);
|
// Walk up to parent
|
||||||
} else {
|
const pid = entry?.parentNodeId ?? entry?.parentId;
|
||||||
activeOwners.push(name);
|
if (pid != null) {
|
||||||
}
|
const parent = nodeMap.get(pid);
|
||||||
|
if (parent) return isRadiated(parent);
|
||||||
}
|
}
|
||||||
});
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const reg of regs) {
|
||||||
|
if (
|
||||||
|
String(reg?.nodeType ?? "").toUpperCase() !== "P" ||
|
||||||
|
!reg?.nodeName
|
||||||
|
) continue;
|
||||||
|
const name = String(reg.nodeName).trim();
|
||||||
|
if (!name) continue;
|
||||||
|
if (isRadiated(reg)) {
|
||||||
|
cancelledOwners.push(name);
|
||||||
|
} else {
|
||||||
|
activeOwners.push(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
proprietariActuali = Array.from(new Set(activeOwners));
|
proprietariActuali = Array.from(new Set(activeOwners));
|
||||||
proprietariVechi = Array.from(new Set(cancelledOwners))
|
proprietariVechi = Array.from(new Set(cancelledOwners)).filter(
|
||||||
.filter((n) => !proprietariActuali.includes(n));
|
(n) => !proprietariActuali.includes(n),
|
||||||
|
);
|
||||||
} catch {
|
} catch {
|
||||||
// Documentation fetch failed — continue with basic data
|
// Documentation fetch failed — continue with basic data
|
||||||
}
|
}
|
||||||
@@ -408,6 +463,16 @@ export async function POST(req: Request) {
|
|||||||
(fol ?? []).map((f: any) => f?.intravilan ?? ""),
|
(fol ?? []).map((f: any) => f?.intravilan ?? ""),
|
||||||
);
|
);
|
||||||
categorie = formatCategories(fol ?? []);
|
categorie = formatCategories(fol ?? []);
|
||||||
|
// Extract total area from folosinte as fallback
|
||||||
|
if (suprafata == null || suprafata <= 0) {
|
||||||
|
let totalArea = 0;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
for (const f of (fol ?? []) as any[]) {
|
||||||
|
const a = Number(f?.suprafata ?? 0);
|
||||||
|
if (Number.isFinite(a)) totalArea += a;
|
||||||
|
}
|
||||||
|
if (totalArea > 0) suprafata = totalArea;
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// folosinta fetch failed
|
// folosinta fetch failed
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1034,7 +1034,9 @@ export function ParcelSyncModule() {
|
|||||||
p.proprietariVechi
|
p.proprietariVechi
|
||||||
? `Proprietari vechi: ${p.proprietariVechi}`
|
? `Proprietari vechi: ${p.proprietariVechi}`
|
||||||
: null,
|
: null,
|
||||||
!p.proprietariActuali && !p.proprietariVechi && p.proprietari
|
!p.proprietariActuali &&
|
||||||
|
!p.proprietariVechi &&
|
||||||
|
p.proprietari
|
||||||
? `Proprietari: ${p.proprietari}`
|
? `Proprietari: ${p.proprietari}`
|
||||||
: null,
|
: null,
|
||||||
p.solicitant
|
p.solicitant
|
||||||
@@ -1142,14 +1144,16 @@ export function ParcelSyncModule() {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{!p.proprietariActuali && !p.proprietariVechi && p.proprietari && (
|
{!p.proprietariActuali &&
|
||||||
<div>
|
!p.proprietariVechi &&
|
||||||
<span className="text-xs text-muted-foreground block">
|
p.proprietari && (
|
||||||
Proprietari
|
<div>
|
||||||
</span>
|
<span className="text-xs text-muted-foreground block">
|
||||||
<span>{p.proprietari}</span>
|
Proprietari
|
||||||
</div>
|
</span>
|
||||||
)}
|
<span>{p.proprietari}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{p.solicitant && (
|
{p.solicitant && (
|
||||||
|
|||||||
Reference in New Issue
Block a user