Scaffolds the fusion_repairs module that extends Odoo 19 repair.order with a guided medical-equipment intake workflow. Models - fusion.repair.product.category (8 medical equipment categories seeded) - fusion.repair.intake.template / .question / .answer (7 templates, 32 questions seeded across hospital bed, stairlift, porch lift, wheelchair, walker/rollator, mattress) - fusion.repair.intake.service (AbstractModel) - single entry point used by backend wizard, sales rep portal, and public client portal so all three surfaces produce identical outcomes - repair.order extensions (x_fc_intake_*, x_fc_third_party_equipment, x_fc_photo_ids, x_fc_urgency, x_fc_estimated/actual_cost, AI summary) - fusion.technician.task back-link (x_fc_repair_order_id) - res.partner service preferences (preferred tech, time window, access notes) - res.users repair extensions (skills, cost rate, on-call rotation fields) - res.config.settings for variance thresholds, portal URL, rate limit UI - Backend intake wizard with multi-equipment loop, third-party flag, photos - repair.order form: Intake tab, Photos, Pricing tab, AI tab, smart buttons (technician tasks, intake answers, original SO) - Kanban + list view urgency badges - Fusion Repairs app menu (New Service Call, Repair Orders, Config) Activities & Email - 4 follow-up activity types (CS callback, tech dispatch, visit follow-up, manager review) with urgency-tiered deadlines - 2 mail templates (client confirmation + office notification) with the same dark/light-safe styling as fusion_claims ADP templates Security - New res.groups.privilege + 3 groups (User, Dispatcher, Manager) - Reuses fusion_tasks.group_field_technician (do NOT recreate) - Reuses fusion_authorizer_portal.group_sales_rep_portal - Multi-company global rule + technician scoping rule on repair.order Verified end-to-end on local westin-v19 dev DB via odoo-shell - creates multiple repairs in one session, auto-creates dispatch task for urgent, attaches 4 activity types correctly per urgency tier and third-party flag. Co-authored-by: Cursor <cursoragent@cursor.com>
379 lines
21 KiB
XML
379 lines
21 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!--
|
|
Seed intake templates - one per major medical equipment category.
|
|
Question banks based on the design spec Section "Configurable intake".
|
|
All templates noupdate=1 so customers can customise without losing data on upgrade.
|
|
-->
|
|
<odoo>
|
|
<data noupdate="1">
|
|
|
|
<!-- ============================================================== -->
|
|
<!-- DEFAULT (fallback) - applies to any category without override -->
|
|
<!-- ============================================================== -->
|
|
<record id="intake_template_default" model="fusion.repair.intake.template">
|
|
<field name="name">Default - General Intake</field>
|
|
<field name="code">default</field>
|
|
<field name="sequence">1</field>
|
|
<field name="is_default" eval="True"/>
|
|
<field name="description"><![CDATA[<p>Generic question set used when no equipment-specific template is configured.</p>]]></field>
|
|
</record>
|
|
|
|
<record id="q_default_caller_relationship" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_default"/>
|
|
<field name="sequence">10</field>
|
|
<field name="name">Who is calling? (self / family / caregiver / other)</field>
|
|
<field name="code">caller_relationship</field>
|
|
<field name="question_type">char</field>
|
|
<field name="required" eval="True"/>
|
|
</record>
|
|
<record id="q_default_address_match" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_default"/>
|
|
<field name="sequence">20</field>
|
|
<field name="name">Is the service address the same as the contact address on file?</field>
|
|
<field name="code">address_match</field>
|
|
<field name="question_type">boolean</field>
|
|
<field name="required" eval="True"/>
|
|
</record>
|
|
<record id="q_default_purchased_from_us" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_default"/>
|
|
<field name="sequence">30</field>
|
|
<field name="name">Was this equipment purchased from us?</field>
|
|
<field name="code">purchased_from_us</field>
|
|
<field name="question_type">boolean</field>
|
|
</record>
|
|
<record id="q_default_purchase_date" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_default"/>
|
|
<field name="sequence">40</field>
|
|
<field name="name">Approximate purchase date (if known)</field>
|
|
<field name="code">purchase_date</field>
|
|
<field name="question_type">date</field>
|
|
</record>
|
|
<record id="q_default_issue_summary" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_default"/>
|
|
<field name="sequence">50</field>
|
|
<field name="name">Describe the issue in your own words</field>
|
|
<field name="code">issue_summary</field>
|
|
<field name="question_type">text</field>
|
|
<field name="required" eval="True"/>
|
|
</record>
|
|
<record id="q_default_safety_concern" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_default"/>
|
|
<field name="sequence">60</field>
|
|
<field name="name">Does this issue affect anyone's safety right now?</field>
|
|
<field name="code">safety_concern</field>
|
|
<field name="question_type">boolean</field>
|
|
<field name="required" eval="True"/>
|
|
</record>
|
|
<record id="q_default_access_notes" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_default"/>
|
|
<field name="sequence">70</field>
|
|
<field name="name">Anything the technician should know about access? (stairs, parking, gate code, pet)</field>
|
|
<field name="code">access_notes</field>
|
|
<field name="question_type">text</field>
|
|
<field name="help_text">e.g. "dog in front yard, use side gate"</field>
|
|
</record>
|
|
|
|
<!-- ============================================================== -->
|
|
<!-- HOSPITAL BED -->
|
|
<!-- ============================================================== -->
|
|
<record id="intake_template_hospital_bed" model="fusion.repair.intake.template">
|
|
<field name="name">Hospital Bed - Intake</field>
|
|
<field name="code">hospital_bed</field>
|
|
<field name="sequence">10</field>
|
|
<field name="product_category_ids" eval="[(6, 0, [ref('category_hospital_bed')])]"/>
|
|
</record>
|
|
|
|
<record id="q_bed_powered" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_hospital_bed"/>
|
|
<field name="sequence">10</field>
|
|
<field name="name">Is the bed plugged in and does it power on?</field>
|
|
<field name="code">powered</field>
|
|
<field name="question_type">selection</field>
|
|
<field name="selection_options">Yes - powers on normally
|
|
No - no lights/sound at all
|
|
Powers on but won't move</field>
|
|
<field name="required" eval="True"/>
|
|
</record>
|
|
<record id="q_bed_remote_works" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_hospital_bed"/>
|
|
<field name="sequence">20</field>
|
|
<field name="name">Does the remote control respond when buttons are pressed?</field>
|
|
<field name="code">remote_works</field>
|
|
<field name="question_type">boolean</field>
|
|
</record>
|
|
<record id="q_bed_motor_side" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_hospital_bed"/>
|
|
<field name="sequence">30</field>
|
|
<field name="name">Which motor seems affected? (head, foot, height, all)</field>
|
|
<field name="code">motor_side</field>
|
|
<field name="question_type">char</field>
|
|
<field name="symptom_keywords">motor</field>
|
|
</record>
|
|
<record id="q_bed_rails" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_hospital_bed"/>
|
|
<field name="sequence">40</field>
|
|
<field name="name">Are the side rails functioning normally?</field>
|
|
<field name="code">rails_ok</field>
|
|
<field name="question_type">boolean</field>
|
|
<field name="symptom_keywords">rail,side</field>
|
|
</record>
|
|
<record id="q_bed_mattress" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_hospital_bed"/>
|
|
<field name="sequence">50</field>
|
|
<field name="name">Is the mattress included in this issue?</field>
|
|
<field name="code">mattress_involved</field>
|
|
<field name="question_type">boolean</field>
|
|
</record>
|
|
|
|
<!-- ============================================================== -->
|
|
<!-- STAIRLIFT -->
|
|
<!-- ============================================================== -->
|
|
<record id="intake_template_stairlift" model="fusion.repair.intake.template">
|
|
<field name="name">Stairlift - Intake</field>
|
|
<field name="code">stairlift</field>
|
|
<field name="sequence">20</field>
|
|
<field name="product_category_ids" eval="[(6, 0, [ref('category_stairlift')])]"/>
|
|
</record>
|
|
|
|
<record id="q_stairlift_powered" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_stairlift"/>
|
|
<field name="sequence">10</field>
|
|
<field name="name">Does the stairlift power on? (any lights, beeps)</field>
|
|
<field name="code">powered</field>
|
|
<field name="question_type">boolean</field>
|
|
<field name="required" eval="True"/>
|
|
</record>
|
|
<record id="q_stairlift_error_code" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_stairlift"/>
|
|
<field name="sequence">20</field>
|
|
<field name="name">Is there an error code displayed? (note the number/letter shown)</field>
|
|
<field name="code">error_code</field>
|
|
<field name="question_type">char</field>
|
|
<field name="symptom_keywords">error code</field>
|
|
</record>
|
|
<record id="q_stairlift_stuck_position" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_stairlift"/>
|
|
<field name="sequence">30</field>
|
|
<field name="name">Is anyone currently stuck on the stairlift?</field>
|
|
<field name="code">person_stuck</field>
|
|
<field name="question_type">boolean</field>
|
|
<field name="required" eval="True"/>
|
|
<field name="help_text">If yes, this is a safety issue - escalate immediately.</field>
|
|
</record>
|
|
<record id="q_stairlift_stops_midway" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_stairlift"/>
|
|
<field name="sequence">40</field>
|
|
<field name="name">Does it stop partway up or down the track?</field>
|
|
<field name="code">stops_midway</field>
|
|
<field name="question_type">boolean</field>
|
|
<field name="symptom_keywords">stops midway</field>
|
|
</record>
|
|
<record id="q_stairlift_burning" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_stairlift"/>
|
|
<field name="sequence">50</field>
|
|
<field name="name">Any burning smell, smoke, or unusual noise?</field>
|
|
<field name="code">burning_smell</field>
|
|
<field name="question_type">boolean</field>
|
|
<field name="required" eval="True"/>
|
|
<field name="symptom_keywords">burning smell,smoke</field>
|
|
</record>
|
|
|
|
<!-- ============================================================== -->
|
|
<!-- PORCH LIFT -->
|
|
<!-- ============================================================== -->
|
|
<record id="intake_template_porch_lift" model="fusion.repair.intake.template">
|
|
<field name="name">Porch Lift - Intake</field>
|
|
<field name="code">porch_lift</field>
|
|
<field name="sequence">30</field>
|
|
<field name="product_category_ids" eval="[(6, 0, [ref('category_porch_lift')])]"/>
|
|
</record>
|
|
|
|
<record id="q_porch_powered" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_porch_lift"/>
|
|
<field name="sequence">10</field>
|
|
<field name="name">Does the lift respond when you press the call/send button?</field>
|
|
<field name="code">powered</field>
|
|
<field name="question_type">boolean</field>
|
|
<field name="required" eval="True"/>
|
|
</record>
|
|
<record id="q_porch_gate_switches" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_porch_lift"/>
|
|
<field name="sequence">20</field>
|
|
<field name="name">Are all gate and door safety switches fully closed?</field>
|
|
<field name="code">gate_switches</field>
|
|
<field name="question_type">boolean</field>
|
|
</record>
|
|
<record id="q_porch_stuck" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_porch_lift"/>
|
|
<field name="sequence">30</field>
|
|
<field name="name">Is anyone currently stuck on the lift?</field>
|
|
<field name="code">person_stuck</field>
|
|
<field name="question_type">boolean</field>
|
|
<field name="required" eval="True"/>
|
|
</record>
|
|
<record id="q_porch_outdoor" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_porch_lift"/>
|
|
<field name="sequence">40</field>
|
|
<field name="name">Is the lift outdoors exposed to weather?</field>
|
|
<field name="code">outdoor</field>
|
|
<field name="question_type">boolean</field>
|
|
</record>
|
|
|
|
<!-- ============================================================== -->
|
|
<!-- WHEELCHAIR (MANUAL + POWER - shared template) -->
|
|
<!-- ============================================================== -->
|
|
<record id="intake_template_wheelchair" model="fusion.repair.intake.template">
|
|
<field name="name">Wheelchair - Intake</field>
|
|
<field name="code">wheelchair</field>
|
|
<field name="sequence">40</field>
|
|
<field name="product_category_ids" eval="[(6, 0, [ref('category_wheelchair_manual'), ref('category_wheelchair_power')])]"/>
|
|
</record>
|
|
|
|
<record id="q_wc_brakes" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_wheelchair"/>
|
|
<field name="sequence">10</field>
|
|
<field name="name">Do the brakes engage and hold the wheelchair?</field>
|
|
<field name="code">brakes_ok</field>
|
|
<field name="question_type">boolean</field>
|
|
<field name="required" eval="True"/>
|
|
<field name="symptom_keywords">brake</field>
|
|
</record>
|
|
<record id="q_wc_tires" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_wheelchair"/>
|
|
<field name="sequence">20</field>
|
|
<field name="name">Are both tires inflated and undamaged?</field>
|
|
<field name="code">tires_ok</field>
|
|
<field name="question_type">boolean</field>
|
|
</record>
|
|
<record id="q_wc_frame" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_wheelchair"/>
|
|
<field name="sequence">30</field>
|
|
<field name="name">Is there any visible damage to the frame or footrests?</field>
|
|
<field name="code">frame_damage</field>
|
|
<field name="question_type">boolean</field>
|
|
</record>
|
|
<record id="q_wc_battery" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_wheelchair"/>
|
|
<field name="sequence">40</field>
|
|
<field name="name">For power chairs: does the battery hold a charge?</field>
|
|
<field name="code">battery_holds_charge</field>
|
|
<field name="question_type">boolean</field>
|
|
<field name="symptom_keywords">battery,charge</field>
|
|
</record>
|
|
<record id="q_wc_joystick" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_wheelchair"/>
|
|
<field name="sequence">50</field>
|
|
<field name="name">For power chairs: any error code shown on the joystick display?</field>
|
|
<field name="code">joystick_error</field>
|
|
<field name="question_type">char</field>
|
|
</record>
|
|
|
|
<!-- ============================================================== -->
|
|
<!-- WALKER / ROLLATOR (shared) -->
|
|
<!-- ============================================================== -->
|
|
<record id="intake_template_walker_rollator" model="fusion.repair.intake.template">
|
|
<field name="name">Walker / Rollator - Intake</field>
|
|
<field name="code">walker_rollator</field>
|
|
<field name="sequence">50</field>
|
|
<field name="product_category_ids" eval="[(6, 0, [ref('category_walker'), ref('category_rollator')])]"/>
|
|
</record>
|
|
|
|
<record id="q_walker_wheels" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_walker_rollator"/>
|
|
<field name="sequence">10</field>
|
|
<field name="name">Do all wheels roll freely?</field>
|
|
<field name="code">wheels_roll</field>
|
|
<field name="question_type">boolean</field>
|
|
</record>
|
|
<record id="q_walker_brakes" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_walker_rollator"/>
|
|
<field name="sequence">20</field>
|
|
<field name="name">Do the brakes lock when engaged? (rollator only)</field>
|
|
<field name="code">brakes_lock</field>
|
|
<field name="question_type">boolean</field>
|
|
</record>
|
|
<record id="q_walker_frame" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_walker_rollator"/>
|
|
<field name="sequence">30</field>
|
|
<field name="name">Is the frame stable, with no wobble or loose parts?</field>
|
|
<field name="code">frame_stable</field>
|
|
<field name="question_type">boolean</field>
|
|
</record>
|
|
|
|
<!-- ============================================================== -->
|
|
<!-- MEDICAL MATTRESS -->
|
|
<!-- ============================================================== -->
|
|
<record id="intake_template_mattress" model="fusion.repair.intake.template">
|
|
<field name="name">Medical Mattress - Intake</field>
|
|
<field name="code">mattress</field>
|
|
<field name="sequence">60</field>
|
|
<field name="product_category_ids" eval="[(6, 0, [ref('category_mattress')])]"/>
|
|
</record>
|
|
|
|
<record id="q_mattress_pump_powered" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_mattress"/>
|
|
<field name="sequence">10</field>
|
|
<field name="name">Is the pump plugged in and showing any indicator lights?</field>
|
|
<field name="code">pump_powered</field>
|
|
<field name="question_type">boolean</field>
|
|
<field name="required" eval="True"/>
|
|
</record>
|
|
<record id="q_mattress_leak" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_mattress"/>
|
|
<field name="sequence">20</field>
|
|
<field name="name">Is the mattress leaking or losing air?</field>
|
|
<field name="code">leak</field>
|
|
<field name="question_type">boolean</field>
|
|
<field name="symptom_keywords">leak,deflate</field>
|
|
</record>
|
|
<record id="q_mattress_alarm" model="fusion.repair.intake.question">
|
|
<field name="template_id" ref="intake_template_mattress"/>
|
|
<field name="sequence">30</field>
|
|
<field name="name">Is the pump showing an error code or alarm?</field>
|
|
<field name="code">alarm</field>
|
|
<field name="question_type">char</field>
|
|
</record>
|
|
|
|
<!-- ============================================================== -->
|
|
<!-- Backfill category defaults -->
|
|
<!-- ============================================================== -->
|
|
<function model="fusion.repair.product.category" name="write">
|
|
<value model="fusion.repair.product.category" eval="[ref('category_hospital_bed')]"/>
|
|
<value eval="{'intake_template_id': ref('intake_template_hospital_bed')}"/>
|
|
</function>
|
|
<function model="fusion.repair.product.category" name="write">
|
|
<value model="fusion.repair.product.category" eval="[ref('category_stairlift')]"/>
|
|
<value eval="{'intake_template_id': ref('intake_template_stairlift')}"/>
|
|
</function>
|
|
<function model="fusion.repair.product.category" name="write">
|
|
<value model="fusion.repair.product.category" eval="[ref('category_porch_lift')]"/>
|
|
<value eval="{'intake_template_id': ref('intake_template_porch_lift')}"/>
|
|
</function>
|
|
<function model="fusion.repair.product.category" name="write">
|
|
<value model="fusion.repair.product.category" eval="[ref('category_wheelchair_manual')]"/>
|
|
<value eval="{'intake_template_id': ref('intake_template_wheelchair')}"/>
|
|
</function>
|
|
<function model="fusion.repair.product.category" name="write">
|
|
<value model="fusion.repair.product.category" eval="[ref('category_wheelchair_power')]"/>
|
|
<value eval="{'intake_template_id': ref('intake_template_wheelchair')}"/>
|
|
</function>
|
|
<function model="fusion.repair.product.category" name="write">
|
|
<value model="fusion.repair.product.category" eval="[ref('category_walker')]"/>
|
|
<value eval="{'intake_template_id': ref('intake_template_walker_rollator')}"/>
|
|
</function>
|
|
<function model="fusion.repair.product.category" name="write">
|
|
<value model="fusion.repair.product.category" eval="[ref('category_rollator')]"/>
|
|
<value eval="{'intake_template_id': ref('intake_template_walker_rollator')}"/>
|
|
</function>
|
|
<function model="fusion.repair.product.category" name="write">
|
|
<value model="fusion.repair.product.category" eval="[ref('category_mattress')]"/>
|
|
<value eval="{'intake_template_id': ref('intake_template_default')}"/>
|
|
</function>
|
|
<function model="fusion.repair.product.category" name="write">
|
|
<value model="fusion.repair.product.category" eval="[ref('category_other')]"/>
|
|
<value eval="{'intake_template_id': ref('intake_template_default')}"/>
|
|
</function>
|
|
|
|
</data>
|
|
</odoo>
|