Skip to content

Void Survey Form

Live dependencies & version history: see the auto-generated catalog page — its Dependencies & Related section lists the sub-forms, sub-tasks, and workflows that use this form, refreshed on every dev pull.

The Void Survey form is used by housing officers to record the condition of a void (empty) property before re-let. It is workflow-launched (not directly selectable from Property Search) — it is created via the Create Jobs workflow using the Demo_TypeOfJobToCreate = "Void Survey" route.

Version History

Version Date Summary
v10 (original) Baseline — full form with Kitchen, Bathroom, Materials blocks; full meter type pre-selection; full room sub-block detail
v11 27/05/2026 Ticket 21617 — 29 changes per Jo Blackburn review of 12/05/2026 spec
v12 28/05/2026 Ticket 21617 — Meter Types screen simplified per Jo Blackburn call 28/05/2026
v13 28/05/2026 Ticket 21617 — Pre-Payment/Quarterly/None push-buttons added inside Gas Meter and Electric Meter sub-screens
v14 28/05/2026 Management Studio in-place edit (version bump only — no transform script; superseded by v15)
v15 28/05/2026 Ticket 21617 — None selection on inner meter screen now routes to [End] instead of falling through to Credit questions
v16 28/05/2026 Ticket 21617 — Electric Supplier (selector + Other text box) removed from Electric Prepay and Electric Credit sub-screens
v17 28/05/2026 Ticket 21617 — Gas Credit sub-screen: heading renamed, Meter Type added, Debt Amount added, Credit Amount added, optional Photo added
v18 28/05/2026 Ticket 21617 — Electric Credit sub-screen: Reading decimal, info label, Debt Amount, Credit Amount, optional Photo added
v19 29/05/2026 Bug fix — Restored room sub-block fields (Heating Type, Decorative Order, Cleanliness, Comments) incorrectly removed in v11
v20 02/06/2026 Ticket 21617 Jo second meeting — Travelling buttons left-align; remove room HeatingType/HeatingTypeOther/DecorativeOrder/Cleanliness; remove Materials (External+Misc); remove BackDoor Replace During VOID; rename front door Replacement Comments→Comments; add Photographs to External Conditions screen
v21 02/06/2026 Meter flow restructure (Gas/Electric Main + Prepay blocks removed; type selection via Meter_GasTypeCredit/Meter_Electric1TypeCredit — Pre-Payment/Quarterly/None); back door type inlined onto Front Door screen; Materials Assessment removed from room blocks; £ added to Debt/Credit captions
v22–v27 02/06/2026 Transform chain (Ticket 21617, Jo meeting 01/06/2026): all 4 SchedulePicker elements locked to Void Rates (2) pricebook (changePriceBook=False); 7 VFP pre-work questions + photo grids inlined into Miscellaneous after Misc_PropertyOkToLet; CRR sub-form ("Is Component Replacement Request Required?" Y/N → ComponentReplacementRequest SubTask) added before Form_IsInspectionComplete. (No v25 package — version skipped.)
v28–v30 03/06/2026 Management Studio in-place edits — Travel screen button alignment & width fixes (3 edits). No transform script; edited directly in MS — not on disk. Dev source of truth.
v32 10/06/2026 Ticket 21617 item 2 — QL classification contact on "property details correct? = No". Wires the dormant QLMV_* stub (root-level, suffix-matched by ImportContactCreationRequest): Class Level 1/2/3 = TENANCYMGT/CHANGES/CHECK, Classification S, Source A, Brief="Property information is incorrect", Full=corrected type/sub-type/bedrooms, gated QLMV_Requested="Yes" when Form_PropertyDetailsCorrect=="No", CreateDefaultAction=No (v1). Paired with workflow Void Pre Inspection QL Updates v2 (adds an ImportContactCreationRequest step after "QL Completion Reference"). + Report email .pdf fix (11/06): Form_DocumentEmailAttachmentName final Summary repointed Form_DocumentNameCalc1 (which appends .pdf) so the report attachment opens directly. Imported to Dev — MS assigned this build form v33 (QL contact + .pdf fix); MS v32 was the QL-contact-only intermediate import. Paired workflow imported as v3 (identical content to v2 — the .pdf fix was form-only and needed no workflow change). Activate form v33 (and workflow v2 or v3) for the changes to go live. On-disk Void+Survey_32.form ↔ MS Dev v33. Pending device test.
v31 09/06/2026 Ticket 21617 — Jo Blackburn feedback call 09/06/2026 (+ "Feedback Void Survey with amendments.docx"). Form-only changes: hide Travelling "Appointment start" label; Travelling button "On route" → "I'm on my way"; remove "central" from heating heading/2 questions/branch button; remove inlined VFP lock-change + key-safe questions; add optional photo groups to Front Door page (Misc_FrontDoorPhotos) and Miscellaneous page (Misc_GeneralPhotos). Built from Void+Survey_30.form (now on disk via 09/06 nightly export). Built — pending Dev import.

| v34 | 18/06/2026 | Ticket 21617 item-2 fix — added QLMV_Use Property Void Client No (Option List, default Yes, cloned from QLMV_UpdateQL) so the property-change QL contact resolves the void client instead of erroring "no client no" on voids (per Pete). Form-only change on Void+Survey_33.form base; no workflow change (workflow v4 already passes propertyId). Built void_survey_v34_180626.ftpackage, imported + activated via ms_import.pyDev form v34 active. Verified in QL (hgmcntct.contact_no=1701884). See Known Issues. ✅ VERIFIED END-TO-END IN TEST 23/06/2026 — form Test v42 / workflow Test v7 (= Dev v34 / v6 content): completing a Void Survey answering "No" raised the contact in t_qlfdat.dbo.hpm1stcr (TENANCYMGT/CHANGES/CHECK, client_no=3000384, processed_yn=1, no error) and the workflow ran Complete. Item 2 done. | | workflow rework | 23–25/06/2026 | Void Pre Inspection QL Updates reworked — ✅ VERIFIED COMPLETE end-to-end in Test (v11), Dev v10/Test v11 active. (1) Full materials bypass — removed Merge Room Materials + Change Materials Provider; the 19/06 fix only removed External/Misc and still crashed (AppendItemGroupsFromSubGroups.GroupCursor NullReference) on surveys with rooms → this is what blocked SOR pull-through (the crash was upstream of Send Inspection Result). Re-pointed Change Schedules Provider → Map GenPB. (2) Contact gatedXPathConditionalTarget on QL Completion Reference: QL_Client No empty → skip Raise Property Change ContactProcess Order in QL, so a clientless void Completes instead of erroring "no client no"; a void with a resolvable client still raises the contact. (3) Clean diagram — gateway <Editor><Layout> added (it rendered tangled without one). Verified on order 381165: 4 SOR lines (£703.36) land on the QL order; Process Order in QL Completes (auto-retries through the QL interface-processing delay); workflow Complete. Scripts: transform_void_qlupdates_v4.py (bypass), transform_void_qlupdates_v8.py (gate), transform_void_qlupdates_v11_layout.py (diagram). | | cards/keys | 09/07/2026 | Ticket 21617 session-6 — Gas Credit "Are there any cards or keys on site?" (Yes/No; Yes reveals a details text box, Meter_GasCardsKeysOnSite/Meter_GasCardsKeysDetail). Both optional, on the PDF. Form Dev v36 / Test v43. Scripts transform_void_survey_cardskeys.py / build_void_survey_cardskeys.py. | | v38 | 13/07/2026 | Ticket 21617 — QL "bedrooms/property type incorrect" contact consolidated onto Peter Steele's new block. Peter saved a Dev v37 with the _Data Items "raise contact" block copied in under prefix QLcrm_ (class levels TENANCYMGT/CHANGES/BEDROOM/PROPERTY/QUERY — Jo's updated 5-level classification; Classification S, Source I, Type I, Use Property Void Client No=Yes). I finished the unfinished parts: QLcrm_Brief Description = "Bedrooms and type of property incorrect"; QLcrm_Full Description = the proven concat "Property Type: "+…con_type_hgmprty2+" Sub-type: "+…con_style_hgmprty2+" Bedrooms: "+…bed_nos_hgmprty2 (Peter's copy left a disabled formula pointing at leftover FRA_descriptn_original); tightened QLcrm_Requested to fire only when Form_PropertyDetailsCorrect=="No" (Peter's copy fired on ≠Yes, i.e. also on blank); set the two tenant client-no flags (Use Property Tenant Client No, Use Tenancy Seq No Tenant Client No) to No — a void has no tenant, and the verified QLMV_ block used void-only. Neutralised the superseded QLMV_ block (hard-set QLMV_Requested→constant "No") so exactly one contact fires — registration is by suffix-match (Form_RaiseContactGroupNameList is empty), so both *_Requested groups are processed and either would fire independently. Imported+activated Dev v38 / Test v45. Scripts transform_void_survey_qlcrm_finish.py / build_void_survey_qlcrm_finish.py. | | v39 | 13/07/2026 | Ticket 21617 — fix found during device test: the QLcrm_ contact blocked submission with "A value is required" on QLcrm_DefaultAction_Action Outcome. Cause: QLcrm_CreateDefaultAction (copied from _Data Items) defaulted "Yes" (QL creates an allocated action), and QLcrm_DefaultAction_Action Outcome is unconditionally mandatory (isMandatory=True, no gating formula) + on the layout. The proven QLMV_ block avoids this: CreateDefaultAction resolves constant "No" (contact only, no allocated action) and has no DefaultAction detail items. Fix = mirror it: QLcrm_CreateDefaultAction → constant "No"; QLcrm_DefaultAction_Action Outcome isMandatoryFalse. Imported+activated Dev v39 / Test v46. Script transform_void_survey_qlcrm_noaction.py. Note for QL/Peter: this makes it a plain contact (lands in the contact work-tray). If Jo wants an auto-allocated action instead, that's a QL default-action config job (assignee + valid outcome), then flip CreateDefaultAction back on. | | v40 | 13/07/2026 | Ticket 21617 — Jo session-7 (call 14/07): contact capture redesigned + form polish before user testing. (1) Contact redesign — Jo: "we need that locked down, we don't want them to change that". The three editable fields (QLPrtyx_con_type/con_style/bed_nos_hgmprty2) are removed from the layout — they carried the same captions as the read-only QLPrtyxO_* "current value" siblings displayed above them (hence two "Property Type" boxes on screen). FormItems kept (the email formula references them) but set non-mandatory so an invisible mandatory can't block submit. New Form_PropertyDetailsComments (multi-line lineCount=4, mandatory, availableForDocumentRendering=True), visible only when Form_PropertyDetailsCorrect=="No" — mandatory is safe because hidden items aren't validated, so it's required only when relevant. QLcrm_Brief Description = "Are the bedrooms and type of property correct?" (the question — Jo: "generally what Pete does is put the question in there"; 46 chars vs the field's maxLength=50, the _Data Items/QL brief_desc standard). QLcrm_Full Description = the comment box (was a concat of the corrected values). Form_PropertyDetailsEmailBody repointed to QLPrtyxO_* + the comment (it referenced the removed fields). Confirmed by Jo: CreateDefaultAction stays No — she configures the housing-officer action in QL against the classification ("the contact actions tab is all set by QL, I sort that out"). (2) Misc_FrontDoorComments is MISNAMED — it is the BACK door Comments box (layout right after Misc_BackDoorType), and its Visible formula 6893aad9… was enabled="false" → never hid, always mandatory. That was Jo's "say no back door and it still wants comments". Now gated on Misc_Does property have a back door == "Yes", mirroring its sibling b7d3e9f1…. Note the general rule: on this form all 117 isMandatory flags are static — relevance gating is done with Visible formulas, and hidden items are not validated. So "mandatory when irrelevant" is a visible bug, not a mandatory one — do NOT blanket-flip isMandatory. (3) Inspector Comments on the complete=Yes pathGenBP_InspectorComments lives in the Operative Comments block, which the Form_IsInspectionComplete==Yes route (NextBlockName at v39 line 47110 → Inspection Result) never visits. Element cloned into Inspection Result (fresh GUID); not rerouted, because Operative Comments also holds debug items (z_ShowDebugData, z_DebugUsers, z_Insights_Switch, z_Env_Dec) that would then be exposed to inspectors. (4) Clearance on the PDF — the five VFP_PreWork*_btn items had availableForDocumentRendering=False; the only False items out of 600 (565 True), which is why they never reached the report and don't even appear in the Template Designer's field picker. Flipped to True (independent of isMandatory; they stay optional). Imported+activated Dev v40 / Test v49. Script transform_void_survey_v40_session7.py. | | v41 | 13/07/2026 | Ticket 21617 — Inspector Comments fix + template bindings. Device test showed the v40 Inspector Comments box still didn't render on the complete=Yes path despite visible=True. Root cause — a reusable gotcha: a gated SectionBreakElement hides EVERY element after it, so element ORDER decides visibility. Inspection Result has a SectionBreak (formula 44351bfb…) gated on z_ShowDebugData=="Yes"; everything after it (z_*, Form_Permissions, QL_QL User ID, Red Flags) is debug-only — and appending the clone to the end of the block put it inside that hidden section. Moved to sit directly after Total SMV (the last visible element), before the debug break → Dev v41 / Test v50 (transform_void_survey_v41_inspcomments.py). Word template bindings — hand-authoring FAILED; the v40 note ("cannot be scripted") was right. I overturned it on ambiguous evidence (the GUID looked document-local: 494/654 shared fields differ per template; condition0 bound 10× here with 10 GUIDs) and authored 7 bindings by cloning rows → Void Survey (clearance + gas keys).docx, then v2 after fixing duplicate w14:paraId/wp14:anchorId (source has zero duplicates; w14:textId="77777777" repeats 201× and should). Both rejected by Save to Server: NullReferenceException at DocumentEx.RangeInGroups ← DocumentValidator.CheckDocument(validIdentifiers, …). Differing GUIDs fit "the Connector mints one server-side per insertion and remembers it" equally well — a GUID it never issued can't resolve → null. The real blocker was the render flag (the 5 clearance fields were availableForDocumentRendering=False, the only False of 600, so they weren't in the field picker at all); that's now True. Correct route: load the template from the server → insert each field via the Connector's field picker → Save to Server. The v2 docx is kept only as a layout reference (versaa-rag/tools/void_survey/add_clearance_gaskeys_to_template.py). Editing existing bindings (remove/move/re-layout) still works and pastes fine — only new ones need the picker. ⏳ Also: hide the QLcrm_ debug panel before Jo's user testing. | | v42 | 13/07/2026 | Ticket 21617 — restored the QL client fallback chain (my v38 error, surfaced once the gate was removed). With the workflow gate gone the contact step finally ran, and errored "Unable to create contact as there is no client no provided" — the classification (TENANCYMGT/CHANGES/BEDROOM/PROPERTY/QUERY) was landing perfectly; only client resolution failed. In v38 I set QLcrm_Use Property Tenant Client No + QLcrm_Use Tenancy Seq No Tenant Client No to No ("a void has no tenant"). Wrong — the three *_Use…Client No switches are a fallback chain (explicit → property void client → property lead-tenant client). Test property D2351 is tenanted (tenancy 20055026, client 415398), so there was no void client and no fallback. Restored both to Yes (transform_void_survey_v42_clientchain.py). ✅ VERIFIED: contact now lands in the client's Household Contact Info (client 415398 via the tenant fallback), Brief = the question, Full = the inspector's comment, Additional Classes 1–5 populated. | | v43–v44 | 16/07/2026 | Ticket 21617 — made the 5 clearance questions render-eligible for the PDF. VFP_PreWork{Clearance,Fumigation,Cleaning,NeddleSweep,GardenClearance}_btn (v43) and their _wg groups + _Photo/_Desn members (v44) had availableForDocumentRendering=False — the only False items of 600, which is why they never reached the report and didn't appear in the Template Designer picker. Flipped to True. | | v45–v46 | 16/07/2026 | Ticket 21617 — fixed the CRR sub-form pull-through (empty components list + blank address). The ComponentReplacementRequest SubTask mapped the property id into the generic SubTask Property ID header field, but the CRR component loader reads GenBP_Key_PropertyId / QLPrtyCm_PropertyId — so "Request Component Data" queried with no property → empty list. Peter's reference is the Repair Works Order form (v97): it maps straight into the loader keys. Mirrored it — map GenBP_Key_PropertyIdGenBP_Key_PropertyId + QLPrtyCm_PropertyId + QL_Property ID (v45), and GenBP_AddressLine1..5/GenBP_AddressPostcodeQLPrty_AddressLine1..5/QLPrty_PostCode (v46, the CRR's own display fields). ✅ VERIFIED: components load + address/postcode display. Property Type left blank (no clean source; RWO doesn't map it either). Copy-paste of the SubTask mapping from the Safeguarding sub-task was the original bug — it targeted the generic header fields. | | v47 | 16/07/2026 | Ticket 21617 — fixed the Meter Readings doc error without touching the template. Void Insp Meter Readings + 1T_Export_Document failed on every completion: "Could not locate Item Meter_ElectricMeterPrePayment used within operand". The Meter+Readings.template still references 5 prepay items removed in the v21 restructure (2 as BinaryCondition operands). Hand-editing the .template is a dead end — they're VSTO-customized docs, and re-zipping breaks the ThisDocument control (ControlNotFoundException in the Connector). So fixed it form-side: re-added the 5 as hidden FormItems (not on layout); Meter_ElectricMeterPrePayment/Meter_GasMeterPrePayment carry value formulas → Meter_Electric1TypeCredit/Meter_GasTypeCredit, so the template's conditions resolve (item exists) and evaluate correctly (same Pre-Payment/Quarterly value). ✅ No more errored instances. A compatibility shim — reversible; the template still carries the legacy prepay structure internally (a Connector-UI rebuild is a future nicety, not needed for clean instances). | | v48 | 17/07/2026 | Ticket 21617 — hid the QLcrm_ contact debug panel from the surveyor layout before Jo's user testing (24 QLcrm_ display fields + Form_RaiseContactGroupNameList + the "Optional, used for voids etc / rarely used / Markers for the form" labels — Peter's debug display, not gated on debug so always visible). Removed the contiguous run from the Void Property Details block; FormItem definitions kept (contact still fires — it reads data items, not layout), real content (property details, comment box, GenBP_PropertyShuttered) preserved. | | workflow v12 | 13/07/2026 | Ticket 21617 — the workflow was silently eating every void contact. Test SQL after a void-survey submit (order 381178) showed nothing in t_qlfdat.dbo.hpm1stcr — the contact never reached QL. Root cause in Void Pre Inspection QL Updates: the June contact-gate branches on string-length(QL_Client No)==0 → skip contact, but a void always has an empty QL_Client No (the void client is resolved inside the contact step via QLcrm_Use Property Void Client No=Yes, which is downstream of the gate and never reached). So every void skipped the contact. The June contact (1560511, 23/06) only fired because that ran on workflow v7, pre-gate. Fix: re-gate on QLcrm_Requested=='Yes' (raise the contact when the surveyor answered property-details = No), else skip to Process Order in QL — mirrors the workflow's own existing "Property Details changed" gate pattern. Imported+activated Dev v11 / Test v12 (transform_void_qlupdates_v12.py). Also fixed a tooling bug: ms_import.py --env dev had been importing to Test (trusted a stale config base_url) → it now resolves --env authoritatively. ⏳ Re-test: complete a NEW void survey in Test answering "No" → one contact in hpm1stcr (processed_yn=1, void client) → then close ticket. |

Note — the old v31 clean-rebuild scripts are abandoned. transform_void_survey_v22.py/build_void_survey_v22.py (SRC v21 → DST v31) were a never-run rebuild that would have regressed the v28–v30 MS button fixes. The actual v31 (this entry) is built by transform_void_survey_v31.py from Void+Survey_30.form and keeps those fixes. Treat the _v22 scripts as dead reference only.

Artefacts

Artefact Path
v10 form XML extracted/forms/Forms/Void+Survey_10.form
v11 form XML extracted/forms/Forms/Void+Survey_11.form
v12 form XML extracted/forms/Forms/Void+Survey_12.form
v12 package all_versaa_forms/void_survey_v12_280526.ftpackage
v16 form XML extracted/forms/Forms/Void+Survey_16.form
v16 package all_versaa_forms/void_survey_v16_280526.ftpackage
v15 form XML extracted/forms/Forms/Void+Survey_15.form
v15 package all_versaa_forms/void_survey_v15_280526.ftpackage
v17 form XML extracted/forms/Forms/Void+Survey_17.form
v17 package all_versaa_forms/void_survey_v17_280526.ftpackage
v18 form XML extracted/forms/Forms/Void+Survey_18.form
v18 package all_versaa_forms/void_survey_v18_280526.ftpackage
v19 form XML extracted/forms/Forms/Void+Survey_19.form
v19 package all_versaa_forms/void_survey_v19_290526.ftpackage
v20 form XML extracted/forms/Forms/Void+Survey_20.form
v20 package all_versaa_forms/void_survey_v20_020626.ftpackage
v21 form XML extracted/forms/Forms/Void+Survey_21.form
v21 package all_versaa_forms/void_survey_v21_020626.ftpackage
v22–v27 form XML extracted/forms/Forms/Void+Survey_{22,23,24,26,27}.form (latest: Void+Survey_27.form)
v22–v27 packages all_versaa_forms/void_survey_v{22,23,24,26,27}_020626.ftpackage (latest: void_survey_v27_020626.ftpackage)
v28–v30 No on-disk artefacts — Management Studio in-place edits only (Dev source of truth)
v30 form XML extracted/forms/Forms/Void+Survey_30.form (on disk via 09/06 nightly export — v31 baseline)
v31 form XML extracted/forms/Forms/Void+Survey_31.form
v31 package all_versaa_forms/void_survey_v31_090626.ftpackage
v31 transform script versaa-rag/transform_void_survey_v31.py (SRC v30 → DST v31)
v31 build script versaa-rag/build_void_survey_v31.py
v11 package all_versaa_forms/void_survey_v11_270526.ftpackage
Control doc word_templates/Form_Creation_Control_Document_Void_Survey.docx
v11 transform script versaa-rag/transform_void_survey.py
v12 transform script versaa-rag/transform_void_survey_v12.py
v20 transform script versaa-rag/transform_void_survey_v20.py
v20 build script versaa-rag/build_void_survey_v20.py
~~v31 transform script~~ (ABANDONED — never run) versaa-rag/transform_void_survey_v22.py (SRC v21 → DST v31)
~~v31 build script~~ (ABANDONED — never run) versaa-rag/build_void_survey_v22.py

v11 Changes (Ticket 21617 — 29 items)

Changes confirmed by Jo Blackburn review of 12/05/2026 spec:

# Block Change
1 Void Property Details Remove GenBP_PropertyAlarmed
2–3 Electric Credit Remove duplicate serial no. (3rd occurrence); remove Meter_ElectricRate1Credit
4–12 Gas Prepay + Credit Remove supplier, supplier-other, connected, service-to-property fields from both; remove Meter_GasCardRequired from Prepay only
13–17 Generic room sub-block Remove heating type, heating type other, decorative order, cleanliness, comments
18 Remove entire Bathroom block
19 Remove entire Kitchen block
20 Remove entire Materials block
21 Formula 20 Remove IsKitchen/IsBathroom routing; IsShower becomes isStart; Shower/Utility/Toilet/Other/Bedroom/DiningRoom/LivingRoom routes retained
22 Schedules NextBlockName: "Materials" → "Photos"
23–24 Front Door Remove Misc_FrontDoorReplace; Misc_FrontDoorComments always visible
25–26 Miscellaneous Remove Misc_WardenPresent, Misc_WardenAlarm
27–28 External Remove External_GarageCondition, External_GarageDecorativeOrder
29 Root Version 10 → 11

v12 Changes (Jo Blackburn call 28/05/2026)

Jo confirmed the Meter Types navigation screen should only have 2 buttons with no pre-selection questions before them:

"Two buttons, yeah, 2 buttons. Electric meter, gas meter. We're taking away water meter."

# Element Change
30 Meter Types screen Remove "Type of Electric Meter?" OptionsListRadioButton (Meter_ElectricMeterPrePayment)
31 Meter Types screen Remove "Type of Gas Meter?" OptionsListRadioButton (Meter_GasMeterPrePayment)
32 Meter Types screen Remove "Water Meter" BranchButtonElement (Meter_Water Meter Status)
33 Electric Meter button Remove conditional visibility formula — button always shown
34 Gas Meter button Remove conditional visibility formula — button always shown
35 Root Version 11 → 12

Result: The Meter Types screen shows exactly "Meter Types" heading + two buttons (Electric Meter, Gas Meter). Clicking either button navigates into the respective sub-branch as before.

Note on sub-branch routing: The Gas Meter branch internally used Meter_GasMeterPrePayment to route between Gas Prepay and Gas Credit sub-blocks. With the pre-selection question removed, the formula falls through to Gas Credit (the default). This is acceptable — in v11 both sub-blocks already have the same reduced field set (serial number + credit reading only). Same logic applies to the Electric branch.

v13 Changes (Pre-Payment/Quarterly buttons inside meter sub-screens)

# Block Change
36 Gas Meter sub-screen Main Added Meter_GasTypePrePayment OptionsListRadioButton with push-buttons: Pre-Payment / Quarterly / None
37 Electric Meter sub-screen Main Added Meter_ElectricTypePrePayment OptionsListRadioButton with push-buttons: Pre-Payment / Quarterly / None
38 Root Version 12 → 13

v15 Changes (None routes to End on meter sub-screens)

Selecting None on the Gas Meter or Electric Meter inner screen previously fell through to Credit questions. Fixed with explicit routing conditions.

# Block Change
39 Gas Meter branch Main — NextBlockName formula Added condition: Meter_GasTypePrePayment == "None"[End]
40 Electric Meter branch Main — NextBlockName formula Added condition: Meter_ElectricTypePrePayment == "None"[End]
41 Root Version 13 → 15 (v14 was Management Studio in-place edit, transform skips it)

v16 Changes (Electric Supplier removed)

# Block Change
42 Electric Prepay sub-screen Removed Meter_ElectricSupplierSel OptionsListRadioButton
43 Electric Prepay sub-screen Removed Meter_ElectricSupplierOther TextBox
44 Electric Credit sub-screen Removed Meter_ElectricSupplierSel (2nd occurrence)
45 Electric Credit sub-screen Removed Meter_ElectricSupplierOther (2nd occurrence)
46 Root Version 15 → 16

Note: Gas Supplier was already removed in v11.

v17 Changes (Gas Credit sub-screen overhaul)

# Element Change
47 Gas Credit — heading Renamed: "Gas Credit Meter Reading" → "Gas Reading"
48 Gas Credit — reading caption Renamed: "Gas Credit Reading:" → "Gas Reading:"
49 Gas Credit — before reading Added Meter_GasTypeCredit OptionComboBoxElement (Standard/Smart meter type)
50 Gas Credit — after reading Added info LabelElement: "The reading is in m3 (cubic metres)"
51 Gas Credit Added Meter_GasDebt DecimalBoxElement: "Debt Amount:"
52 Gas Credit Added Meter_GasCreditAmount DecimalBoxElement: "Credit Amount:"
53 Gas Credit Added Meter_GasPhoto ImageFormElement (optional photo)
54 Root Version 16 → 17

v18 Changes (Electric Credit sub-screen additions)

# Element Change
55 Electric Credit Added Meter_ElectricCreditReading DecimalBoxElement: "Electric Reading:"
56 Electric Credit Added info LabelElement: "The reading is the kwph read (kilo watt per hour)"
57 Electric Credit Added Meter_ElectricDebt DecimalBoxElement: "Debt Amount:"
58 Electric Credit Added Meter_ElectricCreditAmount DecimalBoxElement: "Credit Amount:"
59 Electric Credit Added Meter_ElectricPhoto ImageFormElement (optional photo)
60 Root Version 17 → 18

v19 Changes (Bug fix — restore room sub-block fields)

Root cause: v11 changes 13–17 removed 5 fields from the generic room sub-block. Jo Blackburn never requested this — they were removed in error. These fields affect every room type (Kitchen, Bedroom, Living Room, Dining Room, Other, Shower Wet Room, Store Utility, Toilet) because they share the one generic room sub-block.

Fix: Restored all 5 fields from Void+Survey_10.form (source of truth) back into the shared block.

# Element Change
61 Generic room sub-block Restored GenBP_RoomCentralHeatingType OptionComboBoxElement ("Heating Type:")
62 Generic room sub-block Restored GenBP_RoomCentralHeatingTypeOther TextBoxElement ("Other:" — visible only when Heating Type = Other)
63 Generic room sub-block Restored GenBP_RoomDecorativeOrder OptionsListRadioButton push-buttons (Good/Fair/Poor, coloured)
64 Generic room sub-block Restored GenBP_RoomCleanliness OptionsListRadioButton push-buttons (Good/Fair/Poor, coloured)
65 Generic room sub-block Restored GenBP_RoomComments TextBoxElement (2-line text field)
66 Root Version 18 → 19

v20 Changes (Ticket 21617 — Jo Blackburn second meeting 01/06/2026)

# Area Change
A Travelling block — 3 buttons alignment and captionAlignment changed from CenterLeft ("I'm on my way", "Get Me There", "I've arrived")
C Generic room sub-block — UI Removed GenBP_RoomCentralHeatingType, GenBP_RoomCentralHeatingTypeOther, GenBP_RoomDecorativeOrder, GenBP_RoomCleanliness (keeping Comments); also removed SectionBreaks SB1 and SB2 that divided these fields
C Generic room sub-block — FormItem defs Removed FormItem definitions for all 4 removed room fields
F Misc front door Renamed caption "Replacement Comments" → "Comments"
G Misc back door Removed Misc_BackDoorReplace OptionsListRadioButton ("Replace During VOID?") and its preceding SectionBreak. FormItem definition retained (referenced in Misc_BackDoorReplacementComment visible formula).
I External branch Removed PageBreak + Materials LabelElement + External_Materials StockPickerElement
I Misc branch Removed PageBreak + Materials LabelElement + Misc_Materials StockPickerElement
I FormItem definitions Removed External_Materials, Misc_Materials, GenBP_RoomMaterials FormItem definitions
I Materials Group template Removed the Materials Group template (no longer referenced by any StockPickerElement)
J External Conditions screen Added "Photographs" LabelElement + External_ConditionPhotos GroupElement (new Photo group) before the "Property External Condition Comments" TextBox. New External_ConditionPhotos FormItem definition added (groupName :Photo).
Root Version 19 → 20

v21 Changes (Meter restructure, back door inline, materials removed)

# Area Change
A Meter flow Removed Gas Main, Gas Prepay, Electric Main, Electric Prepay sub-blocks. Meter type (Pre-Payment/Quarterly/None) now selected via Meter_GasTypeCredit / Meter_Electric1TypeCredit inside a single Gas/Electric credit screen each; upstream meter formula (6108586f…) conditions simplified
B Back door Misc_BackDoorType inlined onto the Front Door screen with conditional visibility; separate Back Door block removed
C Room blocks Materials Assessment section removed
D Captions £ symbol added to Debt Amount / Credit Amount captions
Root Version 20 → 21

v22–v27 Changes (Ticket 21617 — Jo Blackburn meeting 01/06/2026)

Delivered as a multi-version transform chain on 02/06/2026 (resolves the former on-hold Screen 29 item).

Pricebook lock (v22–v27): All 4 SchedulePickerElements locked to "Void Rates (2)"changePriceBook = False. Previously they could dynamically switch pricebooks.

VFP questions inlined (v22–v27): 7 questions from Void+First+Person+Checklist_15.form injected into the Miscellaneous block after Misc_PropertyOkToLet: - Lock change (VFP_LockChange), Key safe (VFP_KeySafe) - Pre-work label + 5 Y/N buttons: Clearance, Fumigation, Cleaning, Needle Sweep, Garden Clearance - Each Y/N button has a photo grid visible when answered Yes (5 photo Group defs injected)

CRR sub-form (v22–v27): "Is Component Replacement Request Required?" Y/N (Misc_CRRRequired) added to the Inspection Complete block. When Yes, a SubTaskButtonElement (ComponentReplacementRequest) appears before Form_IsInspectionComplete.

v28–v30 Changes (Management Studio in-place edits — 03/06/2026)

Travel screen button alignment & width fixes applied directly in Management Studio across 3 version bumps (v27→v28→v29→v30). No transform script and no on-disk .form/package — these edits exist only in TcyDev. Dev is the source of truth for this state.

v31 Changes (Ticket 21617 — Jo Blackburn feedback 09/06/2026)

Delivered by versaa-rag/transform_void_survey_v31.py (SRC Void+Survey_30.form → DST Void+Survey_31.form) + build_void_survey_v31.pyvoid_survey_v31_090626.ftpackage. Source: the call Teams_Sessions/Call with Jo Blackburn re ticket 21617 - 3.vtt and scratch/halo_tickets/ticket_21617_attachments/Feedback Void Survey with amendments.docx (9 screenshots).

Import gotcha (10/06): the first v31 package failed import with 8152: String or binary data would be truncated — the manifest comment was 180 chars (form-version comment column is ~100). Rebuilt with an 85-char comment (form XML unchanged) → imports clean. build_void_survey_v31.py now asserts len(comment) < 100. See sessions/gotchas-and-tips.md.

Item Area Change
1a Travelling block Hide the "Appointment start: HH:mm" LabelElement (visible → False; diary-conditional visible formula dropped). Buttons untouched.
1b Travelling block "I'm on my way" button caption toggle: un-clicked state constant On routeI'm on my way (matches Repair Works Order).
4a Central Heating branch Removed "central": "Central Heating Information" → "Heating Information"; "Does the property have central heating?" → "Does the property have heating?"; "Type of central heating" → "Type of heating". FormItem names CentralHeating_Check/CentralHeating_Type unchanged.
4b Main nav screen "Central Heating" branch button caption → "Heating". targetBranchName + <Branch name="Central Heating"> left intact (navigation depends on them).
7 Miscellaneous block Removed the two inlined VFP questions: VFP_LockChange ("Have you completed a lock change?") + VFP_KeySafe ("Please change the key safe number and confirm") — UI elements and FormItem definitions. The SectionBreak before them is kept (separates "Is the property ok to let?" from the pre-work section).
5 Front Door page (Block "Main") Added "Photographs" label + optional photo group Misc_FrontDoorPhotos (:Photo shared group) after the front-door Comments box.
6 Miscellaneous main page Added "Photographs" label + optional photo group Misc_GeneralPhotos after "Is the property ok to let?".

Item 6 note: the form already had a Misc_Photos photo group, but on a separate sub-page (after a PageBreak, near "Total SMV") with a blank label — so it isn't visible on the main Miscellaneous page Jo was reviewing (and was present even in v19, which Jo tested). Misc_GeneralPhotos is a new, labelled group on the main page; Misc_Photos is left as-is.

Not in v31 (separate / parked): - Item 2 — QL classification contact on "bedrooms/property correct? = No" (TENANCYMGT > CHANGES > CHECK). Planned as v32 (replicate the CRR QLcrm_* → Generic Task Completion ImportContactCreationRequest pattern). Codes confirmed on disk (Level-2 is CHANGES, not "CHANGE"). Currently "No" only fires an email (Form_PropertyDetailsEmailBody). - Item 3 — Location code list review — QL-side, Pete Steele / wider business (still On-Hold, Screen 25). - CRR sub-form "not launching" — Jo re-testing; investigate only if confirmed.

Deployment Status

Environment Version Date
Dev (TcyDev) v30 → v31 built, pending import 09/06/2026
Test (PrtyTest) v19 29/05/2026
Live (PrtyLive)

Next deployment: Import void_survey_v31_090626.ftpackage into TcyDev (MS → Import Package; MS assigns the next sequential version). Test on device, then export → PrtyTest for Jo Blackburn sign-off → PrtyLive. Test is far behind (v19) — the v20–v31 changes all land together at the next Test import. After the Dev import, run run_dev_pull.py (§15) to refresh the catalog. Item 2 (QL contact) ships separately as v32; the Word document template review (then ticket close) follows once Jo signs off the form.

On-Hold Items

Meeting with Jo Blackburn held 01/06/2026 — Screen 29 confirmed and delivered in v22–v27.

Item Status
Screen 29 — Clearance/Fumigation/Cleaning/Needle Sweep/Garden Clearance (with photos) + VFP pre-work Done — delivered in v22–v27 (CRR sub-form + photo grids)
Screen 25 — Location codes list ⏳ Awaiting wider business + Pete Steele input (feasibility check first)
Screen 27 — Add missing front door type to Misc_FrontDoorType ⏳ Awaiting Matty Trade (Jo chasing)

How to Test

The Void Survey is workflow-launched, not directly selectable. To create a test task:

  1. Log into Management Studio (TcyDev environment)
  2. Navigate to Forms → Open the Create Jobs form on a property
  3. Set Demo_TypeOfJobToCreate = "Void Survey"
  4. Complete the form — the workflow dispatches a Void Survey task to the selected user

Key Structural Notes

  • Meter Types block is a navigation-only block. BranchButtons navigate into Electric Meter and Gas Meter branches. The NextBlockName formula always returns [End] (branch buttons handle navigation, not NextBlockName).
  • Formula 20 (room block routing) routes to: Bedroom, Dining Room, Living Room, Other, Shower, Utility, Toilet. Kitchen and Bathroom routes were removed in v11.
  • Gas sub-branch routing uses Meter_GasMeterPrePayment to choose Gas Prepay vs Gas Credit sub-block. After v12, this item has no UI input, so routing always falls through to Gas Credit (acceptable — both sub-blocks identical in v11+).

Known Issues

"Process Order in QL" stuck in PendingRetry — order sitting at ord_status = REG (17/07/2026)

Symptom: Void Pre Inspection QL Updates parks in PendingRetry on the Process Order in QL step (CompleteOrderWorkflowStep): "Order NNNNN has unprocessed or errored updates in the order details interface table."

Diagnosis path (all t_qlfdat): 1. Instance status via ms_workflow_info.py "Void Pre Inspection QL Updates" --runtime-onlyPendingRetry, not Errored = transitory, retrying. 2. The completion lands in hpm1stuo (update-order interface; hpm1stud=details, hpm1stnt=notes, hpm1stua=appointments). Check it for the order: SELECT * FROM hpm1stuo WHERE order_no = NNNNN. processed_yn=0 + error_flag=0 + nothing in hpmgperr = unprocessed, not errored. 3. Interface health: SELECT processed_yn, COUNT(*) FROM hpm1stoa GROUP BY processed_yn — if almost all processed (e.g. 905k vs 25), the interface is not stalled. 4. Order status: SELECT order_no, ord_status FROM hpmordhd WHERE order_no = NNNNN. If REG (registered, not issued) → the completion can't apply to an un-issued order, so hpm1stuo stays unprocessed with no error and the workflow retries forever.

Root cause (test, 17/07): orders 381194/381195 on D2351 were registered + approved (approval=True) but never issued (REG), so their COMPLETE rows in hpm1stuo couldn't apply. Completions do work when the order reaches ISS→CMP (381193 = CMP on the same property). Not a form issue and not caused by the v40–v48 changes — it's QL order-lifecycle (the Register-and-Issue step not fully issuing), Peter's domain. Clearing the errored/pending instances removes the retry record but does not issue the order. Queries: scratch/order_interface_check.sql, scratch/void_order_status.sql.

CRR completion email not sending (open, form-agnostic)

The Component Replacement Request completion email (to ComponentReplacementRequest@lincolnshirehp.com) isn't sending — but it reproduces from the Repair Works Order form too, so it's a shared CRR document-template/recipient issue, not the Void Survey. Separate ticket. (The Void Survey report email — to the address the surveyor types on the last page — works.) See component-replacement-request.md.

Void + "Property details correct? = No" → QL contact "no client no provided" (RESOLVED 18/06/2026)

Symptom (was): the Void Pre Inspection QL Updates workflow errored at the Raise Property Change Contact step (ImportContactCreationRequestQLContactUpdateTask): "Unable to create contact as there is no client no provided. … class1='TENANCYMGT'…" (diagnosed on Dev instance ec16c051-… via ms_workflow_errors.py).

Intended (Jo Blackburn, Ticket 21617 item-2): when the operative answers property details correct? = No, raise a QL contact (brief "property information is incorrect", full = type/sub-type/bedrooms) that goes to the operative filling the form to check. The contact is required — do not suppress it.

Root cause: a Void Survey is always a void (no tenant/client). The contact is classified TENANCYMGT/CHANGES/CHECK — a client/tenancy-level type QL won't create without a client no.

Fix (per Pete): set the contact provider's QLMV_Use Property Void Client No = Yes — this makes QL resolve the property's void client number and raise the contact against it. The mechanism needs the propertyId (workflow v4's Raise Property Change Contact step passes it via XPath to GenBP_Key_PropertyId), so no workflow change — just the form data item. - Form change: added QLMV_Use Property Void Client No (Option List, default Yes) — cloned from QLMV_UpdateQL. Void Survey form v34, active in Dev (built void_survey_v34_180626.ftpackage, imported+activated via ms_import.py). - Verified end-to-end in QL: triggered via ms_submit_form.py (with the flag) → contact step Complete/Succeeded → live contact hgmcntct.contact_no = 1701884, prty_id=10804, client_no=3000384 (the property's void client, not 0), TENANCYMGT/CHANGES/CHECK, brief "Property information is incorrect", taken_by=SALEEI. See sql/cheat-sheet.md.

A dead-end worth recording: first attempt blanked clientNo/tenancySequenceNo/propertyId on the workflow step (mirroring Family Survey task complete RL) as workflow v5errored identically, because the client requirement comes from the contact classification, not the step params (and blanking propertyId actually removes the key the void-client lookup needs). Reverted to workflow v4 via POST /api/Workflows/SetActiveVersion.

The "Object reference not set" errors seen on earlier runs are now DIAGNOSED + FIXED — see below.

Void Pre Inspection QL Updates — materials-merge NullReference crash + SOR pull-through (RESOLVED 25/06/2026)

Symptom (was): the workflow errored "Object reference not set to an instance of an object" (FirstTouch.Workflow.Steps.Toolkit.AppendItemGroupsFromSubGroups.GroupCursor) — earlier at Merge External Materials, later at Merge Room Materials. Because the crash was upstream of Send Inspection Result, the SORs never reached the QL order (this is Jo Blackburn's "SORs not pulling through to QL") and the contact never ran.

Root cause: the form has no materials groups (only schedules) — External_Materials/Misc_Materials/GenBP_RoomMaterials/GenBP_AllMaterials are absent. The materials-merge steps read absent groups → null. Merge Room Materials is graceful only when Room_Rooms is empty; with room inspections it crashes. The 19/06 fix removed only External/Misc Materials, so a real (rooms) survey still crashed.

Fix (workflow rework, verified Test v11 — see Version History "workflow rework"): 1. Removed Merge Room Materials + Change Materials Provider (whole materials pipeline is dead for this form); re-pointed Change Schedules Provider → Map GenPB. Crash gone; SORs now push (Send Inspection Result runs) and land on the QL order (verified: order 381165, 4 SOR lines £703.36). 2. Gated the contact on QL_Client No (XPathConditionalTarget on QL Completion Reference) so a void with no resolvable client skips the contact and Completes (runs Process Order in QL) instead of erroring "no client no provided" and blocking the order tail. A void with a client still raises the contact (the v34 _Use Property Void Client No=Yes fix above). 3. Process Order in QL's "unprocessed or errored updates in the order details interface table" is a transient — it auto-retries until QL's interface job processes the SORs, then Completes (see sessions/gotchas-and-tips.md).

Still pending: a real device submission of form v34 to confirm the full form→workflow→QL path in the wild (done in Test for the workflow side); and import the reworked workflow to Dev (done — Dev v10 active).