Are you need IT Support Engineer? Free Consultant

Test Post

  • By admin
  • October 22, 2025
  • 4387 Views

3. Complete method — GetNdaListFetcher.ts

I have kept the mapping in one place to make future changes straightforward.


interface NdaAttribute {
  ndaItemId: string;
  name: string;
  value: string;
  ndaConfigOption?: {
    name: string;
    code: string;
    description: string;
  };
}

const fieldMappings = [
  {
    field: "voa_plotsize",
    ndaItemId: "0a9e206d-b7b4-5d33-8408-7d5fa63d9bed",
    name: "Plot Size"
  },
  {
    field: "voa_rooms",
    ndaItemId: "42893cb8-b3ce-dd57-b8c9-889c30e1fbed",
    name: "Rooms"
  },
  {
    field: "voa_level",
    ndaItemId: "447d93ad-a66e-ff96-7152-be491ebfc5ec",
    name: "Level"
  },
  {
    field: "_voa_heatingcodeid_value",
    ndaItemId: "50539220-1d91-7c8c-5db2-cd738ebd8f43",
    name: "Heating"
  },
  {
    field: "_voa_housegroupid_value",
    ndaItemId: "72c20b60-ce3b-e044-7243-dcf23deb08f2",
    name: "Group"
  },
  {
    field: "_voa_conservatorytypeid_value",
    ndaItemId: "81ff6d97-e5d9-86b7-53c3-8636b831ebb7",
    name: "Conservatory Type"
  },
  {
    field: "voa_bedrooms",
    ndaItemId: "84f5d46c-691d-d9ce-bff9-78b9f9726694",
    name: "Bedrooms"
  },
  {
    field: "voa_conservatoryarea",
    ndaItemId: "b113f2be-e9a5-fb44-38a5-b582477d441f",
    name: "Conservatory Area"
  },
  {
    field: "_voa_agecode_value",
    ndaItemId: "b2de447a-440d-7c4f-f592-4af9b1714621",
    name: "Age Code"
  },
  {
    field: "voa_baths",
    ndaItemId: "b61520a7-dbf1-a8ae-6240-4d9861e9ee9a",
    name: "Bathrooms"
  },
  {
    field: "_voa_parkingcodeid_value",
    ndaItemId: "c6387014-a505-bb10-c0e6-993022b2d408",
    name: "Parking"
  },
  {
    field: "voa_floors",
    ndaItemId: "c68e24c6-b081-1e6a-35e6-6030624d72e0",
    name: "Floors"
  },
  {
    field: "voa_area",
    ndaItemId: "eaabc07e-276f-956c-3800-3c3858a147c6",
    name: "Area of Dwelling"
  },
  {
    field: "_voa_housetypecodegrouplinkid_value",
    ndaItemId: "feeae5ad-a5b3-20e5-998b-55c699bc0a89",
    name: "Type"
  }
];

export async function getNdaAttributes(
  entityType: string,
  recordId: string,
  webAPI: ComponentFramework.WebApi
): Promise<NdaAttribute[]> {

  // Reserved for future entity-specific logic
  void entityType;

  const id = recordId.replace(/[{}]/g, "");

  const guidRegex =
    /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;

  if (!guidRegex.test(id)) {
    throw new Error("Invalid customer submitted information ID");
  }

  // Build the select fields from the mapping
  const selectFields = fieldMappings
    .map(item => item.field)
    .join(",");

  const query =
    `?$select=${selectFields}` +
    `&$filter=voa_customersubmittedinformationid eq ${id}` +
    `&$top=1`;

  const result = await webAPI.retrieveMultipleRecords(
    "voa_customersubmittedinformation",
    query
  );

  if (!result.entities.length) {
    return [];
  }

  const record = result.entities[0] as Record<string, any>;

  const attributes: NdaAttribute[] = fieldMappings.map(item => {

    const isLookup =
      item.field.startsWith("_") &&
      item.field.endsWith("_value");

    const rawValue = record[item.field];

    // Read the lookup display text
    const formattedValue =
      record[
        `${item.field}@OData.Community.Display.V1.FormattedValue`
      ];

    let value = "";

    if (isLookup) {
      if (rawValue != null && rawValue !== "" &&
          (typeof formattedValue !== "string" ||
           !formattedValue.trim() ||
           guidRegex.test(formattedValue.trim()))) {
        throw new Error(
          `Lookup display text unavailable: ${item.field}`
        );
      }

      value = typeof formattedValue === "string"
        ? formattedValue.trim()
        : "";
    } else {
      value = rawValue == null ? "" : String(rawValue);
    }

    const attribute: NdaAttribute = {
      ndaItemId: item.ndaItemId,
      name: item.name,
      value
    };

    // Only lookups have ndaConfigOption
    if (isLookup && value) {

      const hyphenIndex = value.indexOf("-");

      const code = hyphenIndex >= 0
        ? value.substring(0, hyphenIndex).trim()
        : value;

      const description = hyphenIndex >= 0
        ? value.substring(hyphenIndex + 1).trim()
        : value;

      attribute.ndaConfigOption = {
        name: value,
        code,
        description
      };
    }

    return attribute;
  });

  // Reason Code is not part of the query
  attributes.push({
    ndaItemId: "e7c6b1e4-e8ba-d742-4464-0e2d9345a050",
    name: "Reason Code",
    value: "V - Validated",
    ndaConfigOption: {
      name: "V - Validated",
      code: "V",
      description: "Validated"
    }
  });

  return attributes;
}

4. Calling the method

From your PCF control:

const ndaAttributes = await getNdaAttributes(
  entityType,
  "aea1419d-d0ce-f111-a05c-6045bd0b3072",
  context.webAPI
);

console.log("Dynamic NDA Attributes:", ndaAttributes);

entityType is accepted but deliberately not used yet, as requested. The record ID comes from the query in your screenshot; replace it when you have the current record’s ID.

import pyspark.sql.functions as F


spark = ...  # initialization

df = spark.table("a").where(F.col("country") == "abc")
df_unique = df.distinct()
users_without_kids = df_unique.where(F.col("kid_count") == 0)

obser = Observation()
observed_df = users_without_kids.observe(observation, F.count(F.lit(1)).alias("row_count"))

observed_df.writeTo("b")
print(observation.get["row_count"])

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.

Add Your Heading Text Here

Leave a Reply

Your email address will not be published. Required fields are marked *