import { consoleLogger } from "../../../actions/core/logger"; import OSPoint from "ospoint"; import { respondError, respondSuccess } from "../middleware/apiResponse"; import { relayGetData } from "../middleware/relayForwarding"; import transLookup from "../../../data/lookuptranslations.json"; import resolveCrmDisplayValue from "../../../lib/i18n/crmDisplay/resolveCrmDisplayValue"; const renameKeys = (obj) => { const keyMappings = { "pinswg_projectlocation": "location", "pinswg_mapzoomlevel": "zoomLevel", "pinswg_name": "projectName", "pinswg_anticipatedgridreferenceeastingtext": "easting", "pinswg_anticipatedgridreferencenorthingtext": "northing", "pinswg_anticipatedgridrefeasting": "easting", "pinswg_anticipatedgridrefnorthing": "northing", "pinswg_projectname": "projectTitle", "pinswg_dnsid": "dnsId", "pinswg_sipsid": "sipsId", "_pinswg_associatedlpa_value@OData.Community.Display.V1.FormattedValue": "lpaDisplayName", "_pinswg_associatedlpa_value": "lpaId", "_pinswg_appellant_value@OData.Community.Display.V1.FormattedValue": "appellantDisplayName", "_pinswg_appellant_value": "appellantId", "zoom": "mapZoom", "center": "locationCenter" }; let renamedObj = {}; Object.keys(obj).forEach((key) => { // Skip keys that need to be removed if (keysToRemove.includes(key)) { return; } // Skip nested case objects - we flatten them below if (key === "pinswg_sipscase" || key === "pinswg_DNSIds") { return; } // Check if the key exists in the mapping if (keyMappings[key]) { renamedObj[keyMappings[key]] = obj[key]; } else { renamedObj[key] = obj[key]; } }); // Flatten SIPS case response if (obj.pinswg_sipscase) { renamedObj.statusCode = obj.pinswg_sipscase.statuscode; renamedObj.statusCodeDescription = obj.pinswg_sipscase[ "statuscode@OData.Community.Display.V1.FormattedValue" ]; //renamedObj.description = obj.pinswg_sipscase.description; const descriptionText = obj?.pinswg_sipscase?.description || ""; let description = descriptionText; let description_cy = null; // Split on >>> first, otherwise ; const parts = descriptionText.includes(">>>") ? descriptionText.split(">>>") : descriptionText.includes(";") ? descriptionText.split(";") : null; if (parts && parts.length >= 2) { description = parts[0].trim(); description_cy = parts.slice(1).join(" ").trim(); } renamedObj.description = description; if (description_cy) { renamedObj.description_cy = description_cy; } renamedObj.incidentId = obj.pinswg_sipscase.incidentid; } // Flatten DNS case response if (obj.pinswg_DNSIds) { renamedObj.statusCode = obj.pinswg_DNSIds.statuscode; renamedObj.statusCodeDescription = obj.pinswg_DNSIds[ "statuscode@OData.Community.Display.V1.FormattedValue" ]; //renamedObj.description = obj.pinswg_DNSIds.description; const descriptionText = obj?.pinswg_DNSIds?.description || ""; let description = descriptionText; let description_cy = null; // Split on >>> first, otherwise ; const parts = descriptionText.includes(">>>") ? descriptionText.split(">>>") : descriptionText.includes(";") ? descriptionText.split(";") : null; if (parts && parts.length >= 2) { description = parts[0].trim(); description_cy = parts.slice(1).join(" ").trim(); } renamedObj.description = description; if (description_cy) { renamedObj.description_cy = description_cy; } renamedObj.incidentId = obj.pinswg_DNSIds.incidentid; } // Recursively rename keys in nested objects if (obj.center) { renamedObj.locationCenter = { lat: obj.center.lat, lng: obj.center.lng }; } if (renamedObj.easting) { renamedObj.easting = String(renamedObj.easting); } if (renamedObj.northing) { renamedObj.northing = String(renamedObj.northing); } renamedObj.lpaDisplayName_cy = resolveCrmDisplayValue({ value: renamedObj.lpaDisplayName, locale: "cy", translations: transLookup }); renamedObj.statusCodeDescription_cy = resolveCrmDisplayValue({ value: renamedObj.statusCodeDescription, locale: "cy", translations: transLookup }); return renamedObj; }; const keysToRemove = [ "_pinswg_associatedlpa_value@Microsoft.Dynamics.CRM.associatednavigationproperty", "_pinswg_appellant_value@Microsoft.Dynamics.CRM.associatednavigationproperty", "_pinswg_associatedlpa_value@Microsoft.Dynamics.CRM.lookuplogicalname", "_pinswg_appellant_value@Microsoft.Dynamics.CRM.lookuplogicalname", "pinswg_anticipatedgridrefeasting@OData.Community.Display.V1.FormattedValue", "pinswg_anticipatedgridrefnorthing@OData.Community.Display.V1.FormattedValue" // Add any other keys to remove here ]; export default async function ApiProxy(req, res) { const queryUrl = "pinswg_dnses?$select=pinswg_projectlocation,pinswg_mapzoomlevel,pinswg_name,pinswg_anticipatedgridreferenceeastingtext,pinswg_anticipatedgridreferencenorthingtext,pinswg_projectname,pinswg_dnsid,_pinswg_associatedlpa_value,_pinswg_appellant_value&$filter=pinswg_anticipatedgridreferencenorthingtext ne null and pinswg_anticipatedgridreferenceeastingtext ne null&$count=true&$expand=pinswg_DNSIds($select=description,statuscode)"; //console.log("dns ", queryUrl); const queryUrlSips = "pinswg_sipses?$select=pinswg_projectlocation,pinswg_mapzoomlevel,pinswg_name,pinswg_anticipatedgridrefeasting,pinswg_anticipatedgridrefnorthing,pinswg_projectname,pinswg_sipscase,_pinswg_associatedlpa_value,_pinswg_appellant_value&$filter=pinswg_anticipatedgridrefeasting ne null and pinswg_anticipatedgridrefnorthing ne null&$count=true&$expand=pinswg_sipscase($select=description,statuscode)"; const coordsObj = { value: [] }; try { // First relay request const dnsCoordsObj = await relayGetData({ queryUrl }); // Merge the first response's 'value' array into the coordsObj's value array if (Array.isArray(dnsCoordsObj.data.value)) { coordsObj.value = coordsObj.value.concat(dnsCoordsObj.data.value); // Concatenate arrays } else if (dnsCoordsObj.data.value) { coordsObj.value.push(dnsCoordsObj.data.value); // Push single value if it's not an array } // Second relay request const sipsCoordsObj = await relayGetData({ queryUrl: queryUrlSips }); // Merge the second response's 'value' array into the coordsObj's value array if (Array.isArray(sipsCoordsObj.data.value)) { coordsObj.value = coordsObj.value.concat(sipsCoordsObj.data.value); // Concatenate arrays } else if (sipsCoordsObj.data.value) { coordsObj.value.push(sipsCoordsObj.data.value); // Push single value if it's not an array } Object.assign(coordsObj, { "@odata.count": coordsObj.value.length }); coordsObj.value.forEach((item) => { // You can replace the following line with actual calculation logic for latitude // Here, we will just mock it as `easting / 1000` for demonstration. let point = new OSPoint( item.pinswg_anticipatedgridrefnorthing || item.pinswg_anticipatedgridreferencenorthingtext || 0, item.pinswg_anticipatedgridrefeasting || item.pinswg_anticipatedgridreferenceeastingtext || 0 ); let siteCoords = point.toOSGB36(); item.latitude = siteCoords.latitude; item.longitude = siteCoords.longitude; item.zoom = isNaN(parseFloat(siteCoords.latitude)) ? 7 : 12; item.center = { id: "", lat: isNaN(parseFloat(siteCoords.latitude)) ? 52.412272 : parseFloat(siteCoords.latitude), lng: isNaN(parseFloat(siteCoords.longitude)) ? -3.437989 : parseFloat(siteCoords.longitude) }; }); // Send the merged values as the response const updatedData = { value: coordsObj.value.map((item) => renameKeys(item)), "@odata.count": coordsObj["@odata.count"] }; return Object.prototype.hasOwnProperty.call(req.query, "fordmw") ? respondSuccess(res, updatedData) : respondSuccess(res, coordsObj); } catch (error) { // Catch any errors and send an error response consoleLogger(error); return respondError(res, { status: 400, code: "DNS_COORDS_FETCH_FAILED", message: "Failed to fetch DNS coordinates" }); } }