Skip to content

Asbestos Survey — Overview

Peter Steele: "Asbestos data — a whole world of pain."

The Asbestos Survey is one of the most complex form ecosystems in Versaa. It has its own dedicated workflows for loading, data enrichment, and completion — completely separate from the generic Property Check Appointment pipeline.


Forms

Form Current Version Purpose
Asbestos Survey 12 (27/05/2026) Primary surveyor form
Asbestos Data 42 (27/05/2026) Lightweight test/debug form — bypasses property screen, directly loads asbestos data
Asbestos Reinspection 70 (27/05/2026) Reinspection of previously surveyed components
Asbestos Site Audit 78 (as of 14/08/2026) Site-level audit form
Asbestos Edit DataList 3 Data list editing form
Asbestos reassign review 6 (27/05/2026) Reassign/review routing form

Asbestos Data form as a debug tool: Peter confirmed the Asbestos Data form is "a relatively quick form that doesn't actually involve pressing any buttons" — it exists specifically to test that data loading works. It bypasses the property screen and loads asbestos data directly. If the Asbestos Data form loads correctly, the data pipeline is confirmed working.


Workflows

Workflow Current Version Trigger Purpose
Asbestos Get Property Data 4 (27/05/2026) *.GetAsbestosPropertyData Orchestrates data load — checks idempotency, fires AppendPCAData, waits for callback
Asbestos Survey Load Data 8 (27/05/2026) Asbestos Survey.AppendPCAData / Asbestos Data.AppendPCAData Loads all QL property + asbestos component data into the task
Asbestos Survey Completion 4 Asbestos Survey.PCACompletion Handles asbestos-specific completion — updates Property Data and Components Data in QL
Asbestos Reins Concat Groups 21 Concatenates reinspection group data
Asbestos Reference Data 1 Handles reference data for asbestos forms
Asbestos Get Property Data 1 Earlier version/variant
Asbestos site audit conc 1 Site audit concatenation step
Asbestos QL Update 0 QL update step

Workflow Variables

Variable Value Purpose
Asbestos_SurveyCycle 5 Cycle number used when filtering asbestos components from QL
Asbestos_ReferenceDataFolder Path to reference data files
Asbestos_PropertySearch Property search SQL/config
Asbestos_FileLocation File storage path
Asbestos_OrderNotIssuedRecipient Email recipient for unissued orders
Asbestos_ConvertTaskDataToRefData XSLT for data conversion
AsbestosReinspectionDescriptionConcat Concat template for reinspection
AsbestosReferenceDataFolder Alternate reference data path
AsbestosQLPropertySearch QL property search config
AsbestosLocationsSQL SQL for locations list
AsbestosDocumotiveFileLocation Documotive (document storage) path
asbestos_site_audit_xslt XSLT for site audit output

How Data Loading Works

Why Asbestos is NOT in the generic PCA workflow

The generic Property Check Appoint LoadDat workflow handles *.AppendPCAData for most forms. However, it contains an explicit exclusion list at the first step. If the incoming event name contains any of the following, the workflow exits immediately with status "Ignored":

  • Asbestos Survey.
  • Asbestos Data.
  • Building Safety Check.
  • Fire Risk Assessment.
  • Estate Assessment Inspection.
  • (and 10+ others)

This means asbestos forms must be handled by their own dedicated workflow.

The Two-Workflow Pattern

Asbestos data loading uses two workflows in sequence:

Form button press
[Form sends: FormName.GetAsbestosPropertyData]
Asbestos Get Property Data workflow starts
  ├─ Checks if "Asbestos Data Loaded" = "Yes" → if yes, exits (idempotency)
  ├─ Sends: FormName.AppendPCAData
  ├─ Waits for: AppendPCADataCallBack
Asbestos Survey Load Data workflow starts
  ├─ Tag Workflow ($Tag FRA$)
  ├─ Tag Form Name (from task formTypeName)
  ├─ Tag AD User Name (from task userName)
  ├─ Append Extended Property Task Data (QL property details)
  ├─ Clear Components (DELETE FROM QLPrtyCm_Components)
  ├─ Append Component Task Data (appendAsbestos=true, cycle=$Asbestos_SurveyCycle$)
  ├─ Append Original Cycle No (SQL transform + status normalisation)
  ├─ Append Property Extra Extended Task Data
  ├─ Append Loaded Flag (sets "Asbestos Data Loaded" = "Yes")
  └─ Send Callback Event → returns to Get Property Data
Get Property Data workflow receives callback
  └─ Unpacks PCA data, sets AsbestosDataLoaded = "Yes", ends

Component Data Details

The Append Component Task Data step: - Sets appendAsbestos="true" — only asbestos components are loaded - All other types (appendDecentHomes, appendNormal, appendLettings, appendUndefined) = false - Uses $Asbestos_SurveyCycle$ (currently 5) as the cycle number filter - Data lands in the QLPrtyCm_Components group

The Append Original Cycle No step runs SQL against the in-memory QLPrtyCm_Components group:

SELECT *, 
  QLPrtyCy_cycle_no AS cycle_no_original,
  CASE QLPrtyCm_cmpnt_status 
    WHEN 'Existing' THEN 'Active' 
    ELSE 'Historical' 
  END AS Component_Status
FROM QLPrtyCm_Components
ORDER BY QLPrtyCm_location

Key transformations: - cycle_no_original preserves the original cycle number before any edits - Component_Status: ExistingActive; anything else → Historical - Components sorted by QLPrtyCm_location

Note on Tag Mapping

The Tag Workflow step uses $Tag FRA$ — this reuses the Fire Risk Assessment tag mapping. This is deliberate (shared tag structure between FRA and Asbestos Survey inspection types).


Completion Flow

The Asbestos Survey Completion workflow fires on Asbestos Survey.PCACompletion.

Steps: 1. Unpack Data 2. Set status "Asbestos Survey.Starting" 3. Set Tags ($Tag Property Check$) 4. Tag Form Name + AD User Name 5. Abandonment check — if Form_AbandonProcessing = Yes, routes to abandoned branch 6. Update Property Data — writes property record back to QL (UpdatePropertyWorkflowStep) 7. Update Property Components Data — writes component changes back to QL (UpdateComponentsWorkflowStep)


Active Development (18/05/2026)

As of 18 May 2026, active package iterations:

Package Versions built Notes
asbestos_get_property_data_v2/v3/v4_180526.ftpackage v1→v4 today Multiple iterations fixing data load issues
asbestos_survey_load_data_v5/v6/v7/v8_180526.ftpackage v5→v8 Load data workflow; v8 reverts useless Clear Components step
asbestos_data_form_v39/v40/v41_190526.ftpackage v38→v41 Form fix; v39/v40 failed SQL 8152 (long manifest comment); v41 imported OK

Known bug fixed (v41, Asbestos Data form, 19/05/2026): - Root cause: GetAsbestosPropertyData Request FormItem had sendAllItems=False and items=GenBP_Key_PropertyId; only — Asbestos Data Loaded was never sent with the event, so the guard in Asbestos Get Property Data v4 always saw an empty value and never triggered "already loaded" - Fix: Set sendAllItems=True on the Get Asbestos Data request — form now sends all DataItems (including Asbestos Data Loaded) with the event; guard works correctly on second open - Import failures (v39, v40): Both failed with SQL 8152 due to overly long comment attribute in manifest.xml. Form manifest comment must be kept to ~100 chars or fewer.

Asbestos Site Audit fixes (v75, 20/05/2026) — Halo ticket 7930 items 5 & 6:

Item 5 — "Any Other Comments" duplicating inside Issues Identified: - Root cause: QLcrm_Full Description formula expression included +$formItem.Tenant_Comments, so "Any Other Comments" appeared inside the "Issues Identified:" section of the QL full description - Fix (form): Removed +$formItem.Tenant_Comments from QLcrm_Full Description formula expression - Fix (XSLT variable): Added <xsl:value-of select="//Task[not(ancestor::Task)]/DataItems/DataItem[@name='Tenant Comments']"/> after the </xsl:for-each> in the XSLT, so "Any Other Comments" now appears at the end of the QL full description, outside Issues Identified - Watch out: The XSLT value in the .variable file is double-entity-encoded in the raw XML (&amp;lt; for <). When editing with Python's xml.etree, elem.text gives the singly-decoded version. Edit there and write back, or do the raw string edit at the double-encoded level.

Item 6 — QL contact has no classification when no issues identified: - Root cause: QLcrm_Class Level 1 formula had 10 conditions (Q1–Q10 = "No" or Q8 = "Yes"), but the final fallback Summary used <Value type="NoValue" />. If none of the 10 triggered (all questions = "Yes", no defects found), all 5 classification levels returned empty → QL contact received no classification - Fix: Changed final Summary Value type from NoValue to Constant with value COMPLIANCE - Result: All Asbestos Site Audit completions now generate a COMPLIANCE > POSTINSPEC > ASBESTOS > DEFECT classification in QL, regardless of whether issues were found - Watch out: The form XML stores self-closing tags as <Value type="NoValue"></Value> (not <Value type="NoValue" />). String replacements must match the actual file format.

Asbestos Site Audit fixes (v76, 19/06/2026) — Halo ticket 7930 (Kelly's 11/06/2026 re-test):

Blocker — could not submit; "VALIDATION ERRORS: QLcrm_DefaultAction_Action Outcome: A value is required": - Root cause: QLcrm_DefaultAction_Action Outcome (Data List, source Aareon.QL-x.TenancyContactOutcomes.list) had isMandatory=True, even though it sits under the red "Optional, rarely used" label. Surveyors could not move past it. Because QLcrm_CreateDefaultAction defaults to Yes, a contact action is always created; being forced to pick an Outcome is also why the contact action came through "already completed" (Kelly set it to completed just to proceed). - Fix (form): Set isMandatory False on QLcrm_DefaultAction_Action Outcome. With Outcome/Completed left blank by default the QL contact action is created open in the Compliance worktray. - Watch out: Q2/4/6/8 ("A value is required" in Kelly's screenshots) are legitimately mandatory survey questions (isMandatory=True) — not a bug, just unanswered.

Relabel + reorder of the QL contact description (Kelly request): - Relabel (form): The Tenant Comments calculated field emitted " Any Other Comments: "; changed to " Any other comments from the tenant: ". - Reorder (XSLT variable): asbestos_site_audit_xslt FullDescription emitted Additional Comments before Any Other Comments. Moved the Tenant Comments <xsl:value-of> to before the z_Additional Information + Additional Information for-each, so the QL order (Issues Identified → Any Other Comments → Additional Comments) matches the on-form flow (on the form, "Any other comments" precedes the Additional Information grid).

Asbestos Site Audit layout fix (v77, 19/06/2026) — Ticket 7930, Kelly: "questions 1, 3 and 5 are to the right and 2, 4, 6, 8 are below, they used to be side by side": - How the two columns are actually built: a SectionBreakElement carries the width of the section it opens (largeDeviceControlWidth / regularDeviceControlWidth). The Audit block opens three consecutive 50%-wide sections on a large device: the Front Photo section, then Q1/Q3/Q5/Q7, then Q2/Q4/Q6/Q8. The odd/even split is deliberate — with two 50% sections side by side, each row reads Q1|Q2, Q3|Q4, Q5|Q6, Q7|Q8. - Root cause: three 50% sections cannot fit two columns. The photo section took column 1, the odd questions were pushed into column 2, and the even questions wrapped onto the next row — exactly what Kelly saw. - Fix: Front Photo section break largeDeviceControlWidth 50100, so the photo occupies its own full-width row and the two question sections pair up again. - Why it only broke on desktop: the photo section was already regularDeviceControlWidth=100, so phones were always correct. Kelly tested on the Windows desktop app (large device). - Watch out: the question order in the XML is Q1 Q3 Q5 Q7 Q2 Q4 Q6 Q8 and is identical in every version back to v10 — it is not a regression and must not be "corrected" to 1–8, or the column pairing breaks.

Asbestos Site Audit PDF de-duplication (v78, 14/08/2026) — Ticket 7930, Kelly 07/08: - Symptom: the completed-form PDF showed the tenant-comment label twice — Any other comments from the tenant with regards to the survey? immediately followed by Any other comments from the tenant: she was very happy. - Root cause — the PDF is a Word template, not an auto-render. extracted/document_templates/DocumentTemplates/Asbestos+Site+Audit.template (selected by the form's Form_DocumentTemplateName="Asbestos Site Audit") contains static heading text "Any other comments from the tenant with regards to the survey?" and binds a merge field Tenant Comments:1d8ba2f9-…. The v76 relabel had put "Any other comments from the tenant:" inside the Tenant Comments calc value, so the merge field re-printed the label the heading already showed. The raw z_Tenant Comments is not bound in the template. - Fix (scriptable — no template edit): changed the Tenant Comments calc field to emit the raw answer only ($formItem.z_Tenant_Comments ? $formItem.z_Tenant_Comments : ""). The merge field now prints just the answer under the static heading → question/answer format, matching Q1–Q12. The Any other comments from the tenant: label was moved into the XSLT variable (<xsl:if> on non-empty) so the QL work tray full description is unchanged. - Also: aligned the two on-form TextBoxElement captions customertenant (app now matches PDF/QL). - Gotcha — the duplicated label was static text baked into the Word template, not a form field. When a completed-form PDF shows unexpected/duplicated text, check the .template word/document.xml (static runs + descr="FieldName:GUID" merge bindings), not just the form. A bound merge field renders even with the form item's availableForDocumentRendering=False.

CPL017 action code (carried over from 2025 item 7) — NOT a Versaa change: - CPL017 is allocated to user COGGIJ; Kelly wants it allocated to COMPLIANCE. CPL017/COGGIJ appear nowhere in the form or workflow — this is QL action-type configuration. Handle as a separate QL admin SQL change (see Common Issues row below).


Asbestos Data form — duplication FIXED + VERIFIED, and the blank "Location" column (Ticket 17337, Kelly 11/06/2026):

Two genuinely separate defects; keep them apart.

1. The duplication (the ticket's actual subject) — FIXED, verified by Kelly in Test 11/06/2026: - Root cause: sendAllItems=False on the Get Asbestos Data request meant the Asbestos Data Loaded DataItem never reached the Asbestos Get Property Data idempotency guard. The guard always saw an empty value, never short-circuited, and the load workflow ran twice — appending every component a second time ("duplicates below the yellow line"). - Fix: sendAllItems=True on the form (on-disk package labelled _41/_42; MS Dev active is v40 — MS assigns its own version and ignores the package label, so track the MS number not the filename). - Verified by Kelly across 6 properties — B47461, D52521, B45526, D54386, D34586, B47451 — no duplicates anywhere. She tested TEST, where the form is v12. - Version audit (21/07/2026, live MS query — numbers are NOT comparable across envs, each auto-increments on import):

Artefact Dev Test (verified) Live
Asbestos Data (form) 40 12 6
Asbestos Get Property Data (wf) 5 3 4
Asbestos Survey Load Data (wf) 8 4 4
Property Check Appoint LoadDat (wf) 31 24 8
  • Live deployment still OUTSTANDING — and a content diff (not just versions) shows the fix has 3 parts, of which Live is missing 2 (compare_asbestos_test_live.py, 21/07):
  • Asbestos Data form (Test v12) — sends sendAllItems=True on the Get Asbestos Data request (the "loaded" flag). Promote (Live v6 predates the fix).
  • Asbestos Get Property Data (Test v3) — the idempotency guard (XPathConditionalTarget on Asbestos Data Loaded). Live v4 has ZERO guard — despite the higher number, Live's content is the unfixed one (numbers aren't comparable across envs). Promote — core fix.
  • Property Check Appoint LoadDat — Live v8's exclusion list is missing Asbestos Data, so in Live the generic workflow also loads it (a duplication source). ⛔ DO NOT promote Test v24 — a full structural diff (27/07) found three unrelated generic changes riding along: (a) it would DROP Void Weekly Flushing from the exclusion list (present in Live v8, absent in Test v24) → recreates this same double-load bug on that form; (b) it adds a third component-load pass (AppendPCAComponent3CallBack) affecting every PCA form; (c) it removes the terminal End SetUserStatus step. ✅ Correct fix = surgical one-token edit to Live v8's existing XPath: append or contains(//Event[not(ancestor::Event)]/@name, 'Asbestos Data.') — mind the trailing dot (entries match the event prefix, e.g. Asbestos Data.PCALoadData).
  • Skip Asbestos Survey Load Data — Test v4 vs Live v4 differ only by a Clear Components step that Dev reverted at v8 as ineffective; not part of the working fix.
  • Manual MS Export-from-Test → Import-to-Live (I can't drive imports); re-test on Live after. Scripts: versaa-rag/audit_asbestos_versions.py, compare_asbestos_test_live.py; checklist scratch/halo_tickets/ticket_17337_live_deployment_check.md. Live has run the duplicating version since 21/11/2025.
  • Gotcha reinforced: the generic PCA Property Check Appoint LoadDat must exclude both Asbestos Data and Asbestos Survey; if either is missing from the ignored-forms XPath, that form gets double-loaded (generic PCA + its own asbestos workflow).
  • Generic-workflow rule (learned here): never promote a shared workflow wholesale to fix one form. Its ignored-forms list diverges in both directions between envs, so an import can silently remove another form's exclusion. Diff the exclusion lists as sets before importing, and prefer editing the target env's existing version.
  • Possible unreported double-loads in Live: four forms are excluded in Test but not Live — Damp and Mould Inspection, Red Flag Reporting, Component Replacement Request, Family Survey 2 MW. If any is live with its own loader it may be duplicating now. Check with Mark/Peter; don't fix blind.

2. Blank "Location" column on Laundry rows — NOT the duplication bug, and NOT a Versaa change: - Symptom: on B47451 and B3701, the grid's Location cell is empty for Laundry components; every other location on the same property renders correctly. QL itself shows these components perfectly (location = LAUNDRY, Location Desc = Laundry). - How the column resolves: grid column z_QLPrtyCm_location lookup (Data List, datasource Aareon.QL-x.AsbestosLocations.list) displays the description matching the component's QLPrtyCm_location code. That list is built by the AsbestosLocationsSQL variable from cmpgencd (mod_id='HSG', category_id='LOCATION'), minus an exclusion list, and is a snapshot — not live — so it must be rebuilt after any cat/gen-code change. - ⚠️ TWO workflows write this same datalist, and the one you'd expect is NOT the scheduled one:

Workflow Writes Aareon.QL-x.AsbestosLocations Trigger Notifies devices
QL Asbestos Base Data yes, via $AsbestosLocationsSQL$ none — bare <Start>, no timer/message, allowRunFromPortal="false"manual only yes (SendNotificationStep, RefData, userNames="*")
QL Property Survey Base Data yes, near-identical inline SQL (extra desn not like 'CAT&GENCODE%'; uses $1T_DB_ProviderType$ not $QL_DB_ProviderType$) scheduled daily 20:20 (Frequency=Minutely, RepeatDelay=1440) yes

Last writer wins, so a manual QL Asbestos Base Data run is a temporary override — the nightly QL Property Survey Base Data overwrites it the same evening. The durable fix is always the cmpgencd data itself. Schedules are per-environment: confirm the nightly exists and is running in the env you care about before assuming a rebuild happened. - The Asbestos Data form is the outlier. Every other asbestos consumer (Append Asbestos By Property, Load Asbestos Data Config, EleLoadAsbestosData, Electrical Cert AdHoc) resolves the description server-side with a cmpgencd join. Only this form resolves it client-side against the cached datalist — which is exactly why a code can be perfect in QL and blank here, and why a stale device cache can break it on one device but not another. - Reading the deployed list: .list files are gzipped XML (that is why Versaa_Exports_md/reference_lists/*.md render as *(parse error)*). Use versaa-rag/fetch_reference_list.py --env <env> --name AsbestosLocations — it fetches a single list, which matters because Live's ~6,255 reference-data items make a whole-category export 504 every time. - Root cause — duplicate-description collision. ONE row survives, and it is the lowest code_id. cmpgencd held two HSG/LOCATION codes both described LaundryLAUNDR (used by nothing) and LAUNDRY (93 asbestos components across 33 properties). The list writer keeps one row per unique Name; AsbestosLocationsSQL is order by desn with no DISTINCT and no tie-break, so ties fall to physical/index order (code_id ascending). LAUNDR sorts before LAUNDRY, so the dead code won the slot and the in-use code had no entry → blank cell. - ⚠️ This corrects the "neither row is written" mechanism previously recorded here (attributed to Peter Steele, 21/07/2026). It was tested against the deployed artefact on 18/08/2026 and does not hold. .list files are gzipped XML; decompressing Aareon.QL-x.AsbestosLocations.list at three commits shows the broken list contained exactly one row for every duplicate pair, always the lower code_id:

| Export | Laundry row | Items | Duplicate Names |
|---|---|---|---|
| `3024d35` 22/04/2026 (Dev) | `Laundry` → `LAUNDRY` ✅ | 188 | 0 |
| `152721f` 15/07/2026 (Test) | `Laundry` → **`LAUNDR`** ❌ | 215 | 0 |
| `da8d70b` 29/07/2026 (Dev) | `Laundry` → `LAUNDRY` ✅ | 218 | 0 |

In the broken (15/07) list: `BINSTORE`✅ / `COMMONROOM`✅ / `PASSAGE`✅ / `FELEV` / **`LAUNDR`❌** — the survivor is the alphabetically first code every time. Laundry was the *only* pair that broke because it is the only one whose dead code sorts first.
  • RESOLVED by Peter Steele (21/07/2026). Deleted the LAUNDR cat/gen code in Dev, Test and Live (first verifying hgmprcom had zero components using LAUNDR), then re-ran the QL Asbestos Base Data workflow in Test and Dev to rebuild the list. (Deleting the unused code is cleaner than the … (Legacy) rename originally proposed — same effect, removes the dead code.)
  • VERIFIED SERVER-SIDE IN ALL THREE ENVIRONMENTS (18/08/2026). Fetched the deployed list from each Management Studio with versaa-rag/fetch_reference_list.py: Dev 218 / Test 215 / Live 217 items, Laundry → LAUNDRY in all three, zero duplicate Names. BINSTR / PSSAGE / COMNRM are absent everywhere — the in-use code holds every slot. There is nothing left to fix server-side in any environment.
  • STILL REPORTED BLANK BY THE USER (Kelly, 07/08/2026) on B47451, B3701 and B3786 in Test, with Location Code correctly showing LAUNDRY on the same screen. Since the task carries the right code and all three servers resolve it, the remaining suspect is a stale reference-data cache on the device. Next step is a forced full device sync and re-check — not another QL change. If it still blanks after a clean resync, escalate as a RefData notification-delivery fault (the rebuild workflows do send SendNotificationStep / RefData to userNames="*").
  • Fix pattern for this class (QL config, not Versaa — no form/package/redeploy): (1) make the description unique — delete the unused duplicate, or suffix it … (Legacy) per the convention Front Elevation (Legacy)/Landing (Legacy)/Corridor (Legacy)… — then (2) re-run QL Asbestos Base Data to regenerate the list.
  • CLOSED — the other duplicate pairs were never at risk. The "neither-written" rule predicted that Bin Store (BINSTORE ~1,050 comps / BINSTR), Common Room (COMMONROOM 81 / COMNRM) and Passage (PASSAGE 408 / PSSAGE) should also be blank. They are not, and never were: in each pair the in-use code sorts first, so it wins the slot. Confirmed twice — in the broken 15/07 list and in all three environments on 18/08. That is why no user ever reported them. ticket_17337_verify_after_peter.sql (V2) was written to settle this and is now moot for the purpose. FELEV/FRTELV is latent only (neither in use).
  • Still open — 8 codes missing from HSG/LOCATION entirely (a different cause: the code doesn't exist, vs. a duplicate) so also blank: KIT (29 components / 28 properties), BATH (27/27), and WETRM, HALLCUP2, LOUNGE, REARGARDEN, LANDCB2, CUPB1 (1 each). KIT/BATH look like legacy variants of KITCHEN/BATHROOM. Either add the codes or remap the components — an asbestos-register decision.
  • Diagnostic SQL: scratch/halo_tickets/ticket_17337_location_desc_investigation.sql, ticket_17337_followup.sql, and ticket_17337_verify_after_peter.sql (run via run_as_sql_admin.ps1 --db ql).

Common Issues / Gotchas

Issue Cause Fix
Asbestos data not loading on form Generic PCA workflow ignoring it Correct — it's expected. Asbestos has its own workflow. Check Asbestos Get Property Data workflow instances
"Already Loaded" status immediately Asbestos Data Loaded = Yes already set in task Idempotency check firing. If you need to reload: clear the DataItem or start a fresh task
SQL 8152 string truncation on items DataItems items column has a 255-char limit; inline modification exceeds it Use sendAllItems=True on the event request instead of modifying items inline
SQL 8152 on form package import Form manifest comment attribute stored in a short column (~100 chars); long comments truncate Keep form manifest comments brief (<100 chars); workflow comments tolerate longer strings
Tenant Comments appearing inside Issues Identified in QL QLcrm_Full Description formula included +$formItem.Tenant_Comments Remove from formula; add Tenant Comments DataItem output to XSLT variable after for-each (see Site Audit v75 fix)
QL contact has no classification (audit with no defects found) QLcrm_Class Level 1 formula final fallback returned NoValue Change final Summary Value to Constant COMPLIANCE so all contacts get classified
Form won't submit: "QLcrm_DefaultAction_Action Outcome: A value is required" Field is isMandatory=True but sits in the "Optional, rarely used" section Set isMandatory=False (Site Audit v76). A mandatory field can hide inside an "optional" label block — the label is cosmetic, the property is what validates
QL contact action arrives "already completed" Mandatory Action Outcome forced the surveyor to pick an outcome (QLcrm_CreateDefaultAction defaults Yes → action always created) Make Action Outcome optional; leave Outcome/Completed blank → action created open
Form columns misaligned on desktop (odd questions right, even below) Three consecutive 50%-wide sections (photo + two question sections) competing for two columns — the SectionBreakElement carries the section width Set the photo section's largeDeviceControlWidth to 100 so it takes its own row (Site Audit v77). Do not renumber the questions to 1–8 — the odd/even order is what creates the pairing
Form looks right on phone but wrong on desktop largeDeviceControlWidth and regularDeviceControlWidth are set independently; a section can be 100 on phone and 50 on large Always check both width properties when diagnosing layout — and confirm which device class the reporter tested on
Fix "doesn't work" after import Env not updated — Dev and Test hold different active versions Version-audit both envs before believing a fix failed (GetAllFormsWithVersions). Ticket 7930: Dev=76, Test=30 → Kelly re-tested the old form. Also check the workflow variable landed, not just the form
Apparent duplicate QL contacts Querying WHERE contact_no > N with no prty_id filter on a shared env picks up other users' contacts Always filter by property. Ticket 7930 "1 audit → 3 contacts" was 2 unrelated EDI contacts from another user
Verifying a QL contact action (open vs completed) QLHGM_ContactActions on t_qlfdat: ContactNumber, ActionCode, AllocatedUser, CompletedYN, CompletedDate, OutcomeCode. Contact + full_desc in hgmcntct
CPL017 action code allocated to wrong user (COGGIJ) Allocation is configured in QL (action-type table), not the Versaa form/workflow QL admin SQL: UPDATE [QL action-type table] SET alloc_id='COMPLIANCE' WHERE actn_code='CPL017' — exact table TBC by QL admin
Components not appearing Wrong cycle number Check $Asbestos_SurveyCycle$ variable (currently 5). Must match QL cycle
Grid Location cell blank for some components (e.g. Laundry) while others render Two cmpgencd HSG/LOCATION codes share one description. The list keeps one row per Name and AsbestosLocationsSQL has no DISTINCT/tie-break (order by desn only), so the lowest code_id wins the slot — if that's the dead code, the in-use one renders blank Make the description unique — delete the unused duplicate code (or suffix it … (Legacy)) in QL Category & General Code Maintenance, then rebuild the list. Find dupes: GROUP BY RTRIM(desn) HAVING COUNT(*)>1 over cmpgencd HSG/LOCATION (Ticket 17337: LAUNDR/LAUNDRY). Only pairs whose dead code sorts first are affected — don't assume every pair is broken. Not a form bug — no redeploy
Location renders correctly on the server list but is still blank on a device The device holds a stale reference-data cache. This form resolves the location client-side off Aareon.QL-x.AsbestosLocations.list, unlike every other asbestos form (which joins cmpgencd server-side) Verify the deployed list first — fetch_reference_list.py --env <env> --name AsbestosLocations. If the server is correct, force a full device sync / re-login. If it survives a clean resync, escalate as a RefData notification-delivery fault
A cat/gen-code fix "didn't take" even though the rebuild workflow was run QL Asbestos Base Data is manual-only; QL Property Survey Base Data writes the same list on a nightly 20:20 schedule and overwrites it. Schedules are per-environment Fix cmpgencd (the durable source), then either wait for the nightly or run the manual workflow for an immediate rebuild. Confirm the nightly actually exists and is running in that environment
Grid Location blank for KIT, BATH, WETRM, LOUNGE, … The code is used on components but does not exist in cmpgencd HSG/LOCATION at all Add the code in QL Category & General Code Maintenance, or remap the components to the correct code (KITCHEN/BATHROOM). Sweep with the NOT EXISTS query in ticket_17337_location_desc_investigation.sql
A QL lookup "works in QL but is blank in Versaa" QL resolves the code by its own lookup; Versaa resolves it through a datalist built by a workflow-variable SQL with its own filters/exclusions Compare the two: read the *SQL workflow variable that builds the list (e.g. AsbestosLocationsSQL) and re-run it verbatim. Duplicate descriptions and exclusion lists are the usual culprits
Tag FRA used for Asbestos Survey This is intentional — shared tag structure No action needed