Untitled

 avatar
unknown
plain_text
a month ago
9.2 kB
4
Indexable
var ACWAPP = ACWAPP || {};
var Sdk = window.Sdk || {};

ACWAPP.JoinAwardReview = (function () {

  const WEBR_CTRL_NAME = "WebResource_JoinAwardReview";
  const RELATED_SUBGRID_NAME = "RelatedCaseRef";
  const RELATIONSHIP_NAME = "acwapp_acwapp_abusecases_acwapp_abusecases";

  const CASE_LOGICAL = "acwapp_abusecases";
  const ALLEG_LOGICAL = "acwapp_suspectedabuse";

  const CASECATEGORY_YES = 100000000;
  const CASESTATUS_AWARD = 100000005;

  const CASE_ID = "acwapp_abusecasesid";
  const CASE_NUMBER_FIELD = "acwapp_name";
  const CASE_STAGE_FIELD = "acwapp_casestatus";
  const CASE_CATEGORY_FIELD = "acwapp_casecategory";
  const CASE_PROPERTY_LOOKUP_VALUE = "_acwapp_propertycodemainflat_value";
  const CASE_COT_FIELD = "acwapp_commencementoftenancydate";
  const CASE_ESTATE_LOOKUP_VALUE = "_acwapp_estate_value";
  const CASE_SOURCE_OF_ALLEGATION = "acwapp_sourceofallegation";

  const ALLEG_CASE_LOOKUP_VALUE = "_acwapp_abusecase_value";
  const ALLEG_TYPE_FIELD = "acwapp_typeofsuspectedabuse";
  const ALLEG_REFER_TO_MOT = "acwapp_refertomot";
  const ALLEG_RESULT_FIELD = "acwapp_investigationresult";
  const ALLEG_RESULT_MOT_FIELD = "acwapp_suggestedinvestigationresult2";
  const ALLEG_SUGGESTED_ACTION_FIELD = "acwapp_suggestedtenancyactions";
  const ALLEG_STATUS_FIELD = "acwapp_allegationstatus";
  const ALLEG_ACTIONS_FOR_SUGGESTED_TENANCY = "acwapp_actionsforsuggestedtenancy";
  const ALLEG_REASON_NO_TENANCY_ACTION = "acwapp_reasonofnotenancyactionrequired";

  const REFER_TO_MOT = {
    NO: 100000000,
    YES: 100000001
  };
    const Role = {
        ADMIN: "System Administrator",
        EO_USER: "EO User",
        EO_AM: "EO AM",
        EO_SENIOR_MANAGER: "EO Senior Manager",
        HRMO_OFFICER: "HRMO(MOT) Officer",
        HRMO_AM: "HRMO(MOT) AM",
        HRMO_SENIOR_MANAGER: "HRMO(MOT) Senior Manager"
    };

    const BLOCKED_ADD_ROLES = [
        Role.EO_USER,
        Role.EO_AM,
        Role.EO_SENIOR_MANAGER
    ];

    function userHasRole(roleNames) {
        const roles = Xrm.Utility.getGlobalContext().userSettings.roles;
        return [...roles].some(r => roleNames.includes(r.name));
    }

    function canClickAddButton() {
        return !userHasRole(BLOCKED_ADD_ROLES);
    }

  function stripBraces(id) {
    return (id || "").replace(/[{}]/g, "");
  }

  function escapeHtml(s) {
    return (s ?? "").toString()
      .replace(/&/g, "&")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;");
  }

  function fmt(e, f) {
    return e?.[`${f}@OData.Community.Display.V1.FormattedValue`] ?? e?.[f] ?? "";
  }

  function fmtLookup(e, f) {
    return e?.[`${f}@OData.Community.Display.V1.FormattedValue`] ?? "";
  }

  function formatDate(d) {
    if (!d) return "";
    const dt = new Date(d);
    return `${dt.getFullYear()}-${String(dt.getMonth() + 1).padStart(2, "0")}-${String(dt.getDate()).padStart(2, "0")}`;
  }

  // ✅ FIXED SAME DAY LOGIC (LOCAL TIME)
  function dayRangeUtc(dateValue) {
    const d = new Date(dateValue);

    const start = new Date(d);
    start.setHours(0, 0, 0, 0);

    const end = new Date(d);
    end.setHours(23, 59, 59, 999);

    return { start, end };
  }

  async function getRoot(formContext) {
    const ctrl = formContext.getControl(WEBR_CTRL_NAME);
    const win = await ctrl.getContentWindow();
    return win.document.getElementById("root");
  }

  function getRelatedCaseIds(formContext) {
    const set = new Set();
    const grid = formContext.getControl(RELATED_SUBGRID_NAME);
    if (!grid || !grid.getGrid) return set;

    try {
      grid.getGrid().getRows().forEach(r => {
        const id = stripBraces(r.getData().getEntity().getId());
        if (id) set.add(id);
      });
    } catch {}

    return set;
  }

  function renderTable(root, rows, formContext, relatedSet) {
    root.innerHTML = `
      <table style="width:100%;border-collapse:collapse">
        <thead>
          <tr style="background:#f5f5f5">
            <th></th>
            <th>Case Number</th>
            <th>Estate</th>
            <th>Allegation</th>
            <th>Property Code</th>
            <th>COT</th>
            <th>Case Stage</th>
            <th>Allegation Result</th>
            <th>Suggested Action</th>
            <th>Allegation Status</th>
            <th>Actions for Suggested Tenancy</th>
            <th>Reason of No Tenancy Action Required</th>
          </tr>
        </thead>
        <tbody>
          ${rows.map(r => {
            const added = relatedSet.has(stripBraces(r.caseId));
            return `
              <tr data-id="${r.caseId}">
                <td>
                  <button class="add-btn" ${added || !canClickAddButton() ? "disabled" : ""}>
                    ${added ? "Added" : "Add"}
                  </button>
                </td>
                <td>${escapeHtml(r.caseNumber)}</td>
                <td>${escapeHtml(r.estate)}</td>
                <td>${escapeHtml(r.allegation)}</td>
                <td>${escapeHtml(r.property)}</td>
                <td>${escapeHtml(r.cot)}</td>
                <td>${escapeHtml(r.stage)}</td>
                <td>${escapeHtml(r.result)}</td>
                <td>${escapeHtml(r.action)}</td>
                <td>${escapeHtml(r.allegStatus)}</td>
                <td>${escapeHtml(r.actionsForSuggestedTenancy)}</td>
                <td>${escapeHtml(r.reasonNoTenancyAction)}</td>
              </tr>
            `;
          }).join("")}
        </tbody>
      </table>
    `;
  }

  async function render(executionContext) {
    const formContext = executionContext.getFormContext();
    const root = await getRoot(formContext);

    root.innerHTML = "Loading Join Award Review…";

    const parentId = stripBraces(formContext.data.entity.getId());

    const parent = await Xrm.WebApi.retrieveRecord(
      CASE_LOGICAL,
      parentId,
      `?$select=${CASE_COT_FIELD},${CASE_PROPERTY_LOOKUP_VALUE}`
    );

    const { start, end } = dayRangeUtc(parent[CASE_COT_FIELD]);
    const propId = stripBraces(parent[CASE_PROPERTY_LOOKUP_VALUE]);

    const filterCases =
      `${CASE_PROPERTY_LOOKUP_VALUE} eq ${propId}` +
      ` and ${CASE_COT_FIELD} ge ${start.toISOString()}` +
      ` and ${CASE_COT_FIELD} le ${end.toISOString()}` +
      ` and ${CASE_CATEGORY_FIELD} eq ${CASECATEGORY_YES}` +
      ` and ${CASE_STAGE_FIELD} le ${CASESTATUS_AWARD}`;

    const cases = (await Xrm.WebApi.retrieveMultipleRecords(
      CASE_LOGICAL,
      `?$select=${CASE_ID},
                ${CASE_NUMBER_FIELD},
                ${CASE_STAGE_FIELD},
                ${CASE_COT_FIELD},
                ${CASE_ESTATE_LOOKUP_VALUE},
                ${CASE_PROPERTY_LOOKUP_VALUE},
                ${CASE_SOURCE_OF_ALLEGATION}` +
      `&$filter=${filterCases}`
    )).entities;

    if (!cases.length) {
      root.innerHTML = "No related cases found.";
      return;
    }

    const caseMap = {};
    cases.forEach(c => caseMap[c[CASE_ID]] = c);

    const filterAlleg = cases
      .map(c => `${ALLEG_CASE_LOOKUP_VALUE} eq ${c[CASE_ID]}`)
      .join(" or ");

    const allegs = (await Xrm.WebApi.retrieveMultipleRecords(
      ALLEG_LOGICAL,
      `?$select=${ALLEG_CASE_LOOKUP_VALUE},
                ${ALLEG_TYPE_FIELD},
                ${ALLEG_REFER_TO_MOT},
                ${ALLEG_RESULT_FIELD},
                ${ALLEG_RESULT_MOT_FIELD},
                ${ALLEG_SUGGESTED_ACTION_FIELD},
                ${ALLEG_STATUS_FIELD},
                ${ALLEG_ACTIONS_FOR_SUGGESTED_TENANCY},
                ${ALLEG_REASON_NO_TENANCY_ACTION}` +
      `&$filter=${filterAlleg}`
    )).entities;

    const rows = allegs.map(a => {
      const c = caseMap[a[ALLEG_CASE_LOOKUP_VALUE]];
      if (!c) return null;

      const source = c[CASE_SOURCE_OF_ALLEGATION];
      const referToMot = a[ALLEG_REFER_TO_MOT] === REFER_TO_MOT.YES;

      let resultValue = "";

      if (source === 100000002 || source === 100000003) {
        resultValue = fmt(a, ALLEG_RESULT_MOT_FIELD);
      } else if (source === 100000000 || source === 100000001) {
        resultValue = referToMot
          ? fmt(a, ALLEG_RESULT_MOT_FIELD)
          : fmt(a, ALLEG_RESULT_FIELD);
      }

      return {
        caseId: c[CASE_ID],
        caseNumber: fmt(c, CASE_NUMBER_FIELD),
        estate: fmtLookup(c, CASE_ESTATE_LOOKUP_VALUE),
        property: fmtLookup(c, CASE_PROPERTY_LOOKUP_VALUE),
        cot: formatDate(c[CASE_COT_FIELD]),
        stage: fmt(c, CASE_STAGE_FIELD),
        allegation: fmt(a, ALLEG_TYPE_FIELD),
        result: resultValue,
        action: fmt(a, ALLEG_SUGGESTED_ACTION_FIELD),
        allegStatus: fmt(a, ALLEG_STATUS_FIELD),
        actionsForSuggestedTenancy: fmt(a, ALLEG_ACTIONS_FOR_SUGGESTED_TENANCY),
        reasonNoTenancyAction: fmt(a, ALLEG_REASON_NO_TENANCY_ACTION)
      };
    }).filter(Boolean);

    renderTable(root, rows, formContext, getRelatedCaseIds(formContext));
  }

  return { render };
})();
Editor is loading...
Leave a Comment