Rename module fusion_authorizer_portal -> fusion_portal everywhere: manifest/assets, controllers, models, views, JS (odoo.define + asset URLs), migration MODULE constants; plus cross-module refs in fusion_schedule, fusion_repairs, fusion_quotations (depends + inherit_id) and the pdf_filler import in fusion_claims. Add rename_module.sql for the one-time in-place DB rename (ir_module_module, ir_model_data, ir_ui_view.key, ir_module_module_dependency) required on installed envs before -u fusion_portal. Document the rename gotcha as rule 16 in CLAUDE.md. Redesign the Accessibility Assessment selector: replace Font Awesome icon tiles with photo-banner cards using 7 optimized images (1000x750 PNG -> 800x600 JPEG, ~8MB -> 488KB), per-type colour accent bar + centered pill button, hover lift/zoom. Images ship as module static files so they deploy/sync with the module. Drop the regenerable graphify-out cache from the module. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1223 lines
72 KiB
XML
1223 lines
72 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
||
<!--
|
||
Copyright 2024-2026 Nexa Systems Inc.
|
||
License OPL-1 (Odoo Proprietary License v1.0)
|
||
Part of the Fusion Claim Assistant product family.
|
||
|
||
Accessibility Assessment Form Templates
|
||
-->
|
||
<odoo>
|
||
<!-- ============================================================= -->
|
||
<!-- STRAIGHT STAIR LIFT FORM -->
|
||
<!-- ============================================================= -->
|
||
<template id="portal_accessibility_stairlift_straight" name="Straight Stair Lift Assessment">
|
||
<t t-call="portal.portal_layout">
|
||
<t t-set="breadcrumbs_searchbar" t-value="True"/>
|
||
<t t-set="no_breadcrumbs" t-value="True"/>
|
||
|
||
<div class="container py-4">
|
||
<!-- Custom Breadcrumb -->
|
||
<nav aria-label="breadcrumb" class="mb-4">
|
||
<ol class="breadcrumb">
|
||
<li class="breadcrumb-item"><a href="/my">Dashboard</a></li>
|
||
<li class="breadcrumb-item"><a href="/my/accessibility">Accessibility</a></li>
|
||
<li class="breadcrumb-item active">Straight Stair Lift</li>
|
||
</ol>
|
||
</nav>
|
||
|
||
<h2 class="mb-4">
|
||
<i class="fa fa-level-up text-primary"></i>
|
||
Straight Stair Lift Assessment
|
||
</h2>
|
||
|
||
<form id="accessibility_form">
|
||
<input type="hidden" name="assessment_type" value="stairlift_straight"/>
|
||
|
||
<!-- Client Info -->
|
||
<t t-call="fusion_portal.accessibility_client_info_section"/>
|
||
|
||
<!-- Stair Measurements -->
|
||
<div class="card mb-4">
|
||
<div class="card-header bg-info text-white">
|
||
<h5 class="mb-0"><i class="fa fa-ruler"></i> Stair Measurements</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-md-4 mb-3">
|
||
<label class="form-label">Number of Steps <span class="text-danger">*</span></label>
|
||
<input type="number" name="stair_steps" id="stair_steps" class="form-control"
|
||
required="required" min="1" placeholder="e.g., 12" onchange="calculateStraightTrackLength()"/>
|
||
</div>
|
||
<div class="col-md-4 mb-3">
|
||
<label class="form-label">Nose to Nose (inches) <span class="text-danger">*</span></label>
|
||
<input type="number" name="stair_nose_to_nose" id="stair_nose_to_nose" class="form-control"
|
||
required="required" min="1" step="0.5" placeholder="e.g., 10" onchange="calculateStraightTrackLength()"/>
|
||
<small class="text-muted">Distance from step nose to next step nose</small>
|
||
</div>
|
||
<div class="col-md-4 mb-3">
|
||
<label class="form-label">Installation Side</label>
|
||
<select name="stair_side" class="form-control">
|
||
<option value="">-- Select --</option>
|
||
<option value="left">Left Side</option>
|
||
<option value="right">Right Side</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="row">
|
||
<div class="col-md-6 mb-3">
|
||
<label class="form-label">Stair Lift Style</label>
|
||
<select name="stair_style" class="form-control">
|
||
<option value="">-- Select --</option>
|
||
<option value="standard">Standard Stair Lift</option>
|
||
<option value="slide_track">Slide Track Stair Lift</option>
|
||
<option value="foldable_hinge">Foldable Hinge Stair Lift</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Calculated Track Length -->
|
||
<div class="alert alert-info">
|
||
<div class="row align-items-center">
|
||
<div class="col-md-8">
|
||
<strong><i class="fa fa-calculator"></i> Calculated Track Length:</strong>
|
||
<div class="mt-2">
|
||
<span class="h4" id="calculated_length">0</span> <span class="text-muted">inches</span>
|
||
<span class="mx-2">|</span>
|
||
<span class="h5" id="calculated_length_feet">0</span> <span class="text-muted">feet</span>
|
||
<span class="mx-2">|</span>
|
||
<span class="h5" id="calculated_length_metres">0</span> <span class="text-muted">metres</span>
|
||
</div>
|
||
<small class="text-muted">Formula: (Steps x Nose-to-Nose) + 13" top landing</small>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<label class="form-label">Manual Override (inches)</label>
|
||
<input type="number" name="stair_manual_length_override" class="form-control"
|
||
step="0.5" placeholder="Leave blank to use calculated"/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Track Requirements -->
|
||
<div class="alert alert-warning mt-3" id="track_requirements_section" style="display: none;">
|
||
<strong><i class="fa fa-cogs"></i> Track Requirements:</strong>
|
||
<div class="mt-2" id="track_requirements_details">
|
||
<!-- Filled by JavaScript -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Additional Features -->
|
||
<div class="card mb-4">
|
||
<div class="card-header bg-success text-white">
|
||
<h5 class="mb-0"><i class="fa fa-cogs"></i> Additional Features</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-md-6">
|
||
<div class="form-check mb-2">
|
||
<input type="checkbox" name="stair_power_swivel_upstairs" value="true" class="form-check-input" id="power_swivel"/>
|
||
<label class="form-check-label" for="power_swivel">Power Swivel (Upstairs)</label>
|
||
</div>
|
||
<div class="form-check mb-2">
|
||
<input type="checkbox" name="stair_power_folding_footrest" value="true" class="form-check-input" id="power_footrest"/>
|
||
<label class="form-check-label" for="power_footrest">Power Folding Footrest</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Photos -->
|
||
<t t-call="fusion_portal.accessibility_photo_section"/>
|
||
|
||
<!-- Notes -->
|
||
<t t-call="fusion_portal.accessibility_notes_section"/>
|
||
|
||
<!-- Submit Buttons -->
|
||
<t t-call="fusion_portal.accessibility_submit_buttons"/>
|
||
</form>
|
||
</div>
|
||
|
||
<!-- Scripts -->
|
||
<t t-call="fusion_portal.accessibility_form_scripts"/>
|
||
|
||
<script type="text/javascript">
|
||
// Constants for track calculations
|
||
var TRACK_LENGTH_INCHES = 92.5; // One standard track length
|
||
var MIN_CUT_PIECE_FEET = 3; // Minimum cut piece size
|
||
var MIN_CUT_PIECE_INCHES = MIN_CUT_PIECE_FEET * 12; // 36 inches
|
||
|
||
function calculateStraightTrackLength() {
|
||
var steps = parseInt(document.getElementById('stair_steps').value) || 0;
|
||
var noseToNose = parseFloat(document.getElementById('stair_nose_to_nose').value) || 0;
|
||
var calculated = (steps * noseToNose) + 13; // +13 for top landing
|
||
|
||
// Display in inches
|
||
document.getElementById('calculated_length').textContent = calculated.toFixed(1);
|
||
|
||
// Convert and display in feet
|
||
var feet = calculated / 12;
|
||
document.getElementById('calculated_length_feet').textContent = feet.toFixed(2);
|
||
|
||
// Convert and display in metres
|
||
var metres = calculated * 0.0254;
|
||
document.getElementById('calculated_length_metres').textContent = metres.toFixed(2);
|
||
|
||
// Calculate track requirements
|
||
calculateTrackRequirements(calculated);
|
||
}
|
||
|
||
function calculateTrackRequirements(totalLengthInches) {
|
||
var section = document.getElementById('track_requirements_section');
|
||
var details = document.getElementById('track_requirements_details');
|
||
|
||
if (totalLengthInches <= 0) {
|
||
section.style.display = 'none';
|
||
return;
|
||
}
|
||
|
||
section.style.display = 'block';
|
||
|
||
var html = '';
|
||
var tracksNeeded = 0;
|
||
var trackConfig = '';
|
||
|
||
if (totalLengthInches <= TRACK_LENGTH_INCHES) {
|
||
// Single track is enough
|
||
tracksNeeded = 1;
|
||
var cutLength = TRACK_LENGTH_INCHES - totalLengthInches;
|
||
trackConfig = '<span class="badge bg-success">Single Track</span> - ' +
|
||
'Use 1 track (' + TRACK_LENGTH_INCHES + '"), cut ' + cutLength.toFixed(1) + '" from one end';
|
||
} else if (totalLengthInches <= (TRACK_LENGTH_INCHES * 2)) {
|
||
// Two tracks needed, joined in middle
|
||
tracksNeeded = 2;
|
||
var totalTrackLength = TRACK_LENGTH_INCHES * 2; // 185 inches
|
||
var excessLength = totalTrackLength - totalLengthInches;
|
||
var cutPerSide = excessLength / 2;
|
||
|
||
trackConfig = '<span class="badge bg-warning text-dark">Two Tracks Joined</span> - ' +
|
||
'Use 2 tracks (total ' + totalTrackLength.toFixed(1) + '"), ' +
|
||
'cut ' + cutPerSide.toFixed(1) + '" from each outer end, join in middle';
|
||
|
||
// Check minimum cut piece warning
|
||
var remainingPerTrack = TRACK_LENGTH_INCHES - cutPerSide;
|
||
if (cutPerSide > 0 && cutPerSide < MIN_CUT_PIECE_INCHES) {
|
||
trackConfig += '<br/><small class="text-danger"><i class="fa fa-warning"></i> ' +
|
||
'Note: Cut piece (' + cutPerSide.toFixed(1) + '") is less than minimum ' + MIN_CUT_PIECE_INCHES + '"</small>';
|
||
}
|
||
} else if (totalLengthInches <= (TRACK_LENGTH_INCHES * 3)) {
|
||
// Three tracks needed - full track in middle, cuts on sides
|
||
tracksNeeded = 3;
|
||
var remainingLength = totalLengthInches - TRACK_LENGTH_INCHES; // After middle track
|
||
var lengthPerSide = remainingLength / 2;
|
||
var cutPerSide = TRACK_LENGTH_INCHES - lengthPerSide;
|
||
|
||
trackConfig = '<span class="badge bg-danger">Three Tracks (2 Joints)</span> - ' +
|
||
'Full track in middle (' + TRACK_LENGTH_INCHES + '"), ' +
|
||
'cut pieces on each side (' + lengthPerSide.toFixed(1) + '" each, cut ' + cutPerSide.toFixed(1) + '" off)';
|
||
|
||
// Check minimum cut piece warning
|
||
if (lengthPerSide < MIN_CUT_PIECE_INCHES) {
|
||
trackConfig += '<br/><small class="text-danger"><i class="fa fa-warning"></i> ' +
|
||
'Warning: Side pieces (' + lengthPerSide.toFixed(1) + '") are less than minimum ' + MIN_CUT_PIECE_INCHES + '"</small>';
|
||
}
|
||
} else {
|
||
// More than 3 tracks - calculate how many needed
|
||
tracksNeeded = Math.ceil(totalLengthInches / TRACK_LENGTH_INCHES);
|
||
var totalTrackLength = tracksNeeded * TRACK_LENGTH_INCHES;
|
||
var excessLength = totalTrackLength - totalLengthInches;
|
||
|
||
trackConfig = '<span class="badge bg-dark">' + tracksNeeded + ' Tracks (' + (tracksNeeded - 1) + ' Joints)</span> - ' +
|
||
'Total track material: ' + totalTrackLength.toFixed(1) + '", ' +
|
||
'excess to cut: ' + excessLength.toFixed(1) + '"';
|
||
}
|
||
|
||
// Build the HTML
|
||
html += '<div class="mb-2">';
|
||
html += '<strong>Tracks Needed:</strong> ' + tracksNeeded + ' track(s) @ ' + TRACK_LENGTH_INCHES + '" each';
|
||
html += '</div>';
|
||
html += '<div class="mb-2">';
|
||
html += '<strong>Configuration:</strong> ' + trackConfig;
|
||
html += '</div>';
|
||
|
||
// Add reference info
|
||
html += '<hr class="my-2"/>';
|
||
html += '<small class="text-muted">';
|
||
html += '<i class="fa fa-info-circle"></i> Track specs: 1 track = ' + TRACK_LENGTH_INCHES + '" | ';
|
||
html += 'Min cut piece = ' + MIN_CUT_PIECE_FEET + ' feet (' + MIN_CUT_PIECE_INCHES + '")';
|
||
html += '</small>';
|
||
|
||
details.innerHTML = html;
|
||
}
|
||
</script>
|
||
</t>
|
||
</template>
|
||
|
||
<!-- ============================================================= -->
|
||
<!-- CURVED STAIR LIFT FORM -->
|
||
<!-- ============================================================= -->
|
||
<template id="portal_accessibility_stairlift_curved" name="Curved Stair Lift Assessment">
|
||
<t t-call="portal.portal_layout">
|
||
<t t-set="breadcrumbs_searchbar" t-value="True"/>
|
||
<t t-set="no_breadcrumbs" t-value="True"/>
|
||
|
||
<div class="container py-4">
|
||
<!-- Custom Breadcrumb -->
|
||
<nav aria-label="breadcrumb" class="mb-4">
|
||
<ol class="breadcrumb">
|
||
<li class="breadcrumb-item"><a href="/my">Dashboard</a></li>
|
||
<li class="breadcrumb-item"><a href="/my/accessibility">Accessibility</a></li>
|
||
<li class="breadcrumb-item active">Curved Stair Lift</li>
|
||
</ol>
|
||
</nav>
|
||
|
||
<h2 class="mb-4">
|
||
<i class="fa fa-refresh text-info"></i>
|
||
Curved Stair Lift Assessment
|
||
</h2>
|
||
|
||
<form id="accessibility_form">
|
||
<input type="hidden" name="assessment_type" value="stairlift_curved"/>
|
||
|
||
<!-- Client Info -->
|
||
<t t-call="fusion_portal.accessibility_client_info_section"/>
|
||
|
||
<!-- Stair Measurements -->
|
||
<div class="card mb-4">
|
||
<div class="card-header bg-info text-white">
|
||
<h5 class="mb-0"><i class="fa fa-ruler"></i> Stair Measurements</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-md-4 mb-3">
|
||
<label class="form-label">Number of Steps <span class="text-danger">*</span></label>
|
||
<input type="number" name="stair_curved_steps" id="stair_curved_steps" class="form-control"
|
||
required="required" min="1" placeholder="e.g., 14" onchange="calculateCurvedTrackLength()"/>
|
||
</div>
|
||
<div class="col-md-4 mb-3">
|
||
<label class="form-label">Number of Curves</label>
|
||
<input type="number" name="stair_curves_count" id="stair_curves_count" class="form-control"
|
||
min="0" value="0" placeholder="e.g., 2" onchange="calculateCurvedTrackLength()"/>
|
||
<small class="text-muted">Each curve adds 16" to track length</small>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Top Landing Section -->
|
||
<div class="card mb-4">
|
||
<div class="card-header" style="background: linear-gradient(135deg, #5ba848 0%, #3a8fb7 60%, #2e7aad 100%); color: white;">
|
||
<h5 class="mb-0"><i class="fa fa-arrow-up"></i> Top Landing</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-md-6 mb-3">
|
||
<label class="form-label">Top Landing Type <span class="text-danger">*</span></label>
|
||
<select name="stair_top_landing_type" id="stair_top_landing_type" class="form-control" onchange="handleTopLandingChange()">
|
||
<option value="none">Standard (No special landing)</option>
|
||
<option value="90_exit">90° Exit (+24")</option>
|
||
<option value="90_parking">90° Parking (+24")</option>
|
||
<option value="180_parking">180° Parking (+48")</option>
|
||
<option value="flush_landing">Flush Landing (+12")</option>
|
||
<option value="vertical_overrun">Vertical Overrun (Custom)</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-6 mb-3" id="top_overrun_custom_container" style="display: none;">
|
||
<label class="form-label">Top Overrun Length (inches) <span class="text-danger">*</span></label>
|
||
<input type="number" name="top_overrun_custom_length" id="top_overrun_custom_length"
|
||
class="form-control" min="1" step="0.5" placeholder="Enter custom length in inches"
|
||
onchange="calculateCurvedTrackLength()"/>
|
||
<small class="text-muted">Enter the exact overrun measurement needed</small>
|
||
</div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="col-md-12 mb-3">
|
||
<label class="form-label">Top Landing Photos</label>
|
||
<input type="file" name="top_landing_photos" id="top_landing_photos" class="form-control"
|
||
accept="image/*" multiple="multiple"/>
|
||
<small class="text-muted">Upload photos of the top landing area</small>
|
||
<div id="top_landing_preview" class="row mt-2"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Bottom Landing Section -->
|
||
<div class="card mb-4">
|
||
<div class="card-header" style="background: linear-gradient(135deg, #3a8fb7 0%, #2e7aad 60%, #1a6b9a 100%); color: white;">
|
||
<h5 class="mb-0"><i class="fa fa-arrow-down"></i> Bottom Landing</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-md-6 mb-3">
|
||
<label class="form-label">Bottom Landing Type <span class="text-danger">*</span></label>
|
||
<select name="stair_bottom_landing_type" id="stair_bottom_landing_type" class="form-control" onchange="handleBottomLandingChange()">
|
||
<option value="none">Standard (No special landing)</option>
|
||
<option value="90_park">90° Park (+24")</option>
|
||
<option value="180_park">180° Park (+48")</option>
|
||
<option value="drop_nose">Drop Nose Landing (+12")</option>
|
||
<option value="short_vertical">Short Vertical Start (+12")</option>
|
||
<option value="horizontal_overrun">Horizontal Overrun (Custom)</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-6 mb-3" id="bottom_overrun_custom_container" style="display: none;">
|
||
<label class="form-label">Bottom Overrun Length (inches) <span class="text-danger">*</span></label>
|
||
<input type="number" name="bottom_overrun_custom_length" id="bottom_overrun_custom_length"
|
||
class="form-control" min="1" step="0.5" placeholder="Enter custom length in inches"
|
||
onchange="calculateCurvedTrackLength()"/>
|
||
<small class="text-muted">Enter the exact overrun measurement needed</small>
|
||
</div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="col-md-12 mb-3">
|
||
<label class="form-label">Bottom Landing Photos</label>
|
||
<input type="file" name="bottom_landing_photos" id="bottom_landing_photos" class="form-control"
|
||
accept="image/*" multiple="multiple"/>
|
||
<small class="text-muted">Upload photos of the bottom landing area</small>
|
||
<div id="bottom_landing_preview" class="row mt-2"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Calculated Track Length -->
|
||
<div class="card mb-4">
|
||
<div class="card-header" style="background: linear-gradient(135deg, #4a9e3f 0%, #5ba848 100%); color: white;">
|
||
<h5 class="mb-0"><i class="fa fa-calculator"></i> Track Calculation</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="alert alert-info mb-3">
|
||
<div class="row align-items-center">
|
||
<div class="col-md-8">
|
||
<strong>Calculated Track Length:</strong>
|
||
<span id="curved_calculated_length" class="h3 ml-2">0</span> <span class="text-muted">inches</span>
|
||
<span class="mx-2">|</span>
|
||
<span id="curved_calculated_feet" class="h5">0</span> <span class="text-muted">feet</span>
|
||
<span class="mx-2">|</span>
|
||
<span id="curved_calculated_metres" class="h5">0</span> <span class="text-muted">metres</span>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<label class="form-label">Manual Override (inches)</label>
|
||
<input type="number" name="stair_curved_manual_override" class="form-control"
|
||
step="0.5" placeholder="Leave blank to use calculated"/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div id="curved_calculation_breakdown" class="small text-muted">
|
||
<!-- Breakdown will be populated by JavaScript -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Video Upload Section -->
|
||
<div class="card mb-4">
|
||
<div class="card-header bg-dark text-white">
|
||
<h5 class="mb-0"><i class="fa fa-video-camera"></i> Video Recording</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-md-12 mb-3">
|
||
<label class="form-label">Upload Assessment Video</label>
|
||
<input type="file" name="assessment_video" id="assessment_video" class="form-control"
|
||
accept="video/*"/>
|
||
<small class="text-muted">
|
||
<i class="fa fa-info-circle"></i>
|
||
Upload a video walkthrough of the staircase. Video will be compressed automatically.
|
||
<br/>Supported formats: MP4, MOV, AVI, WebM (Max 100MB)
|
||
</small>
|
||
<div id="video_preview" class="mt-2" style="display:none;">
|
||
<video id="video_player" controls="controls" style="max-width: 100%; max-height: 300px;"></video>
|
||
</div>
|
||
<div id="video_compress_status" class="mt-2" style="display:none;">
|
||
<div class="progress">
|
||
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar"
|
||
id="compress_progress" style="width: 0%">Compressing...</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Additional Features -->
|
||
<div class="card mb-4">
|
||
<div class="card-header bg-success text-white">
|
||
<h5 class="mb-0"><i class="fa fa-cogs"></i> Additional Features</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-md-6">
|
||
<h6>Power Features</h6>
|
||
<div class="form-check mb-2">
|
||
<input type="checkbox" name="stair_power_swivel_upstairs" value="true" class="form-check-input" id="swivel_up"/>
|
||
<label class="form-check-label" for="swivel_up">Power Swivel (Upstairs)</label>
|
||
</div>
|
||
<div class="form-check mb-2">
|
||
<input type="checkbox" name="stair_power_swivel_downstairs" value="true" class="form-check-input" id="swivel_down"/>
|
||
<label class="form-check-label" for="swivel_down">Power Swivel (Downstairs)</label>
|
||
</div>
|
||
<div class="form-check mb-2">
|
||
<input type="checkbox" name="stair_auto_folding_footrest" value="true" class="form-check-input" id="auto_footrest"/>
|
||
<label class="form-check-label" for="auto_footrest">Automatic Folding Footrest</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<h6>Other Features</h6>
|
||
<div class="form-check mb-2">
|
||
<input type="checkbox" name="stair_auto_folding_hinge" value="true" class="form-check-input" id="auto_hinge"/>
|
||
<label class="form-check-label" for="auto_hinge">Automatic Folding Hinge</label>
|
||
</div>
|
||
<div class="form-check mb-2">
|
||
<input type="checkbox" name="stair_auto_folding_seat" value="true" class="form-check-input" id="auto_seat"/>
|
||
<label class="form-check-label" for="auto_seat">Automatic Folding Seat</label>
|
||
</div>
|
||
<div class="form-check mb-2">
|
||
<input type="checkbox" name="stair_custom_color" value="true" class="form-check-input" id="custom_color"/>
|
||
<label class="form-check-label" for="custom_color">Customizable Colored Seat</label>
|
||
</div>
|
||
<div class="form-check mb-2">
|
||
<input type="checkbox" name="stair_additional_charging" value="true" class="form-check-input" id="add_charging"/>
|
||
<label class="form-check-label" for="add_charging">Additional Charging Station</label>
|
||
</div>
|
||
<div class="form-check mb-2">
|
||
<input type="checkbox" name="stair_charging_with_remote" value="true" class="form-check-input" id="charging_remote"/>
|
||
<label class="form-check-label" for="charging_remote">Charging Station with Remote</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Photos -->
|
||
<t t-call="fusion_portal.accessibility_photo_section"/>
|
||
|
||
<!-- Notes -->
|
||
<t t-call="fusion_portal.accessibility_notes_section"/>
|
||
|
||
<!-- Submit Buttons -->
|
||
<t t-call="fusion_portal.accessibility_submit_buttons"/>
|
||
</form>
|
||
</div>
|
||
|
||
<!-- Scripts -->
|
||
<t t-call="fusion_portal.accessibility_form_scripts"/>
|
||
|
||
<script type="text/javascript">
|
||
// Landing type track lengths (in inches)
|
||
// Note: vertical_overrun and horizontal_overrun use custom values from input fields
|
||
var TOP_LANDING_LENGTHS = {
|
||
'none': 0,
|
||
'90_exit': 24,
|
||
'90_parking': 24,
|
||
'180_parking': 48,
|
||
'flush_landing': 12,
|
||
'vertical_overrun': 0 // Custom - uses input field
|
||
};
|
||
|
||
var BOTTOM_LANDING_LENGTHS = {
|
||
'none': 0,
|
||
'90_park': 24,
|
||
'180_park': 48,
|
||
'drop_nose': 12,
|
||
'short_vertical': 12,
|
||
'horizontal_overrun': 0 // Custom - uses input field
|
||
};
|
||
|
||
// Handler for top landing type change - show/hide custom field
|
||
function handleTopLandingChange() {
|
||
var topLandingType = document.getElementById('stair_top_landing_type').value;
|
||
var customContainer = document.getElementById('top_overrun_custom_container');
|
||
var customInput = document.getElementById('top_overrun_custom_length');
|
||
|
||
if (topLandingType === 'vertical_overrun') {
|
||
customContainer.style.display = 'block';
|
||
customInput.required = true;
|
||
} else {
|
||
customContainer.style.display = 'none';
|
||
customInput.required = false;
|
||
customInput.value = '';
|
||
}
|
||
calculateCurvedTrackLength();
|
||
}
|
||
|
||
// Handler for bottom landing type change - show/hide custom field
|
||
function handleBottomLandingChange() {
|
||
var bottomLandingType = document.getElementById('stair_bottom_landing_type').value;
|
||
var customContainer = document.getElementById('bottom_overrun_custom_container');
|
||
var customInput = document.getElementById('bottom_overrun_custom_length');
|
||
|
||
if (bottomLandingType === 'horizontal_overrun') {
|
||
customContainer.style.display = 'block';
|
||
customInput.required = true;
|
||
} else {
|
||
customContainer.style.display = 'none';
|
||
customInput.required = false;
|
||
customInput.value = '';
|
||
}
|
||
calculateCurvedTrackLength();
|
||
}
|
||
|
||
function calculateCurvedTrackLength() {
|
||
var steps = parseInt(document.getElementById('stair_curved_steps').value) || 0;
|
||
var curves = parseInt(document.getElementById('stair_curves_count').value) || 0;
|
||
var topLandingType = document.getElementById('stair_top_landing_type').value;
|
||
var bottomLandingType = document.getElementById('stair_bottom_landing_type').value;
|
||
|
||
// Calculate each component
|
||
var baseLength = steps * 12; // 12" per step
|
||
var curvesLength = curves * 16; // 16" per curve
|
||
|
||
// Top landing length - check for custom overrun
|
||
var topLandingLength = 0;
|
||
if (topLandingType === 'vertical_overrun') {
|
||
topLandingLength = parseFloat(document.getElementById('top_overrun_custom_length').value) || 0;
|
||
} else {
|
||
topLandingLength = TOP_LANDING_LENGTHS[topLandingType] || 0;
|
||
}
|
||
|
||
// Bottom landing length - check for custom overrun
|
||
var bottomLandingLength = 0;
|
||
if (bottomLandingType === 'horizontal_overrun') {
|
||
bottomLandingLength = parseFloat(document.getElementById('bottom_overrun_custom_length').value) || 0;
|
||
} else {
|
||
bottomLandingLength = BOTTOM_LANDING_LENGTHS[bottomLandingType] || 0;
|
||
}
|
||
|
||
var total = baseLength + curvesLength + topLandingLength + bottomLandingLength;
|
||
|
||
// Display in different units
|
||
document.getElementById('curved_calculated_length').textContent = total.toFixed(0);
|
||
document.getElementById('curved_calculated_feet').textContent = (total / 12).toFixed(2);
|
||
document.getElementById('curved_calculated_metres').textContent = (total * 0.0254).toFixed(2);
|
||
|
||
// Build breakdown HTML
|
||
var breakdownHtml = '<strong>Breakdown:</strong> ';
|
||
var parts = [];
|
||
if (baseLength > 0) parts.push(steps + ' steps × 12" = ' + baseLength + '"');
|
||
if (curvesLength > 0) parts.push(curves + ' curves × 16" = ' + curvesLength + '"');
|
||
if (topLandingLength > 0) {
|
||
var topLabel = document.getElementById('stair_top_landing_type').options[document.getElementById('stair_top_landing_type').selectedIndex].text;
|
||
if (topLandingType === 'vertical_overrun') {
|
||
parts.push('Top Overrun (custom) = ' + topLandingLength + '"');
|
||
} else {
|
||
parts.push('Top: ' + topLabel.split('(')[0].trim() + ' = ' + topLandingLength + '"');
|
||
}
|
||
}
|
||
if (bottomLandingLength > 0) {
|
||
var bottomLabel = document.getElementById('stair_bottom_landing_type').options[document.getElementById('stair_bottom_landing_type').selectedIndex].text;
|
||
if (bottomLandingType === 'horizontal_overrun') {
|
||
parts.push('Bottom Overrun (custom) = ' + bottomLandingLength + '"');
|
||
} else {
|
||
parts.push('Bottom: ' + bottomLabel.split('(')[0].trim() + ' = ' + bottomLandingLength + '"');
|
||
}
|
||
}
|
||
breakdownHtml += parts.join(' + ') + ' = <strong>' + total + '"</strong>';
|
||
document.getElementById('curved_calculation_breakdown').innerHTML = breakdownHtml;
|
||
}
|
||
|
||
// Photo preview handlers
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
// Top landing photos preview
|
||
var topPhotosInput = document.getElementById('top_landing_photos');
|
||
if (topPhotosInput) {
|
||
topPhotosInput.addEventListener('change', function(e) {
|
||
previewImages(e.target.files, 'top_landing_preview');
|
||
});
|
||
}
|
||
|
||
// Bottom landing photos preview
|
||
var bottomPhotosInput = document.getElementById('bottom_landing_photos');
|
||
if (bottomPhotosInput) {
|
||
bottomPhotosInput.addEventListener('change', function(e) {
|
||
previewImages(e.target.files, 'bottom_landing_preview');
|
||
});
|
||
}
|
||
|
||
// Video preview
|
||
var videoInput = document.getElementById('assessment_video');
|
||
if (videoInput) {
|
||
videoInput.addEventListener('change', function(e) {
|
||
var file = e.target.files[0];
|
||
if (file) {
|
||
var videoPreview = document.getElementById('video_preview');
|
||
var videoPlayer = document.getElementById('video_player');
|
||
if (videoPlayer && videoPreview) {
|
||
videoPlayer.src = URL.createObjectURL(file);
|
||
videoPreview.style.display = 'block';
|
||
}
|
||
|
||
// Show file size info
|
||
var sizeMB = (file.size / (1024 * 1024)).toFixed(2);
|
||
console.log('Video size: ' + sizeMB + ' MB');
|
||
}
|
||
});
|
||
}
|
||
});
|
||
|
||
function previewImages(files, previewContainerId) {
|
||
var container = document.getElementById(previewContainerId);
|
||
if (!container) return;
|
||
container.innerHTML = '';
|
||
|
||
Array.from(files).forEach(function(file, index) {
|
||
var reader = new FileReader();
|
||
reader.onload = function(e) {
|
||
var col = document.createElement('div');
|
||
col.className = 'col-3 mb-2';
|
||
col.innerHTML = '<img src="' + e.target.result + '" class="img-thumbnail" style="max-height: 80px; object-fit: cover;"/>';
|
||
container.appendChild(col);
|
||
};
|
||
reader.readAsDataURL(file);
|
||
});
|
||
}
|
||
</script>
|
||
</t>
|
||
</template>
|
||
|
||
<!-- ============================================================= -->
|
||
<!-- VERTICAL PLATFORM LIFT (VPL) FORM -->
|
||
<!-- ============================================================= -->
|
||
<template id="portal_accessibility_vpl" name="VPL Assessment">
|
||
<t t-call="portal.portal_layout">
|
||
<t t-set="breadcrumbs_searchbar" t-value="True"/>
|
||
<t t-set="no_breadcrumbs" t-value="True"/>
|
||
|
||
<div class="container py-4">
|
||
<!-- Custom Breadcrumb -->
|
||
<nav aria-label="breadcrumb" class="mb-4">
|
||
<ol class="breadcrumb">
|
||
<li class="breadcrumb-item"><a href="/my">Dashboard</a></li>
|
||
<li class="breadcrumb-item"><a href="/my/accessibility">Accessibility</a></li>
|
||
<li class="breadcrumb-item active">Vertical Platform Lift</li>
|
||
</ol>
|
||
</nav>
|
||
|
||
<h2 class="mb-4">
|
||
<i class="fa fa-arrows-v text-success"></i>
|
||
Vertical Platform Lift Assessment
|
||
</h2>
|
||
|
||
<form id="accessibility_form">
|
||
<input type="hidden" name="assessment_type" value="vpl"/>
|
||
|
||
<!-- Client Info -->
|
||
<t t-call="fusion_portal.accessibility_client_info_section"/>
|
||
|
||
<!-- Room Dimensions -->
|
||
<div class="card mb-4">
|
||
<div class="card-header bg-success text-white">
|
||
<h5 class="mb-0"><i class="fa fa-expand"></i> Room Dimensions</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-md-4 mb-3">
|
||
<label class="form-label">Room Width (inches)</label>
|
||
<input type="number" name="vpl_room_width" class="form-control"
|
||
min="0" step="0.5" placeholder="Width"/>
|
||
</div>
|
||
<div class="col-md-4 mb-3">
|
||
<label class="form-label">Room Depth (inches)</label>
|
||
<input type="number" name="vpl_room_depth" class="form-control"
|
||
min="0" step="0.5" placeholder="Depth"/>
|
||
</div>
|
||
<div class="col-md-4 mb-3">
|
||
<label class="form-label">Total Rise Height (inches) <span class="text-danger">*</span></label>
|
||
<input type="number" name="vpl_rise_height" class="form-control"
|
||
required="required" min="0" step="0.5" placeholder="Rise height"/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Platform Requirements -->
|
||
<div class="card mb-4">
|
||
<div class="card-header bg-info text-white">
|
||
<h5 class="mb-0"><i class="fa fa-cube"></i> Platform Requirements</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-md-6 mb-3">
|
||
<div class="form-check">
|
||
<input type="checkbox" name="vpl_has_existing_platform" value="true" class="form-check-input" id="existing_platform"/>
|
||
<label class="form-check-label" for="existing_platform">Existing Platform Available</label>
|
||
</div>
|
||
<small class="text-muted">Lift needs anchor bolts; platform must be concrete</small>
|
||
</div>
|
||
<div class="col-md-6 mb-3">
|
||
<label class="form-label">Concrete Depth (inches)</label>
|
||
<input type="number" name="vpl_concrete_depth" class="form-control"
|
||
min="0" step="0.5" placeholder="Minimum 4 inches required"/>
|
||
<small class="text-muted">Minimum 4" required to absorb vibration</small>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Power Requirements -->
|
||
<div class="card mb-4">
|
||
<div class="card-header bg-warning">
|
||
<h5 class="mb-0"><i class="fa fa-bolt"></i> Power Requirements</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-md-6 mb-3">
|
||
<label class="form-label">Model Type</label>
|
||
<select name="vpl_model_type" class="form-control">
|
||
<option value="">-- Select --</option>
|
||
<option value="ac">AC Model (Requires dedicated 15-amp breaker)</option>
|
||
<option value="dc">DC Model (No dedicated breaker required)</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-6 mb-3">
|
||
<div class="form-check mb-2">
|
||
<input type="checkbox" name="vpl_has_nearby_plug" value="true" class="form-check-input" id="nearby_plug"/>
|
||
<label class="form-check-label" for="nearby_plug">Power Plug Nearby (110V / 15-amp)</label>
|
||
</div>
|
||
<div class="form-check mb-2">
|
||
<input type="checkbox" name="vpl_needs_plug_install" value="true" class="form-check-input" id="plug_install"/>
|
||
<label class="form-check-label" for="plug_install">Needs Plug Installation</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Certification -->
|
||
<div class="card mb-4">
|
||
<div class="card-header" style="background: linear-gradient(135deg, #5ba848 0%, #3a8fb7 60%, #2e7aad 100%); color: white;">
|
||
<h5 class="mb-0"><i class="fa fa-certificate"></i> Certification</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-md-6 mb-3">
|
||
<div class="form-check">
|
||
<input type="checkbox" name="vpl_needs_certification" value="true" class="form-check-input" id="needs_cert"/>
|
||
<label class="form-check-label" for="needs_cert">Needs City Certification</label>
|
||
</div>
|
||
<small class="text-muted">Required if installing plug or other electrical work</small>
|
||
</div>
|
||
<div class="col-md-6 mb-3">
|
||
<label class="form-label">Certification Notes</label>
|
||
<textarea name="vpl_certification_notes" class="form-control" rows="2"
|
||
placeholder="Any certification requirements..."></textarea>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Photos -->
|
||
<t t-call="fusion_portal.accessibility_photo_section"/>
|
||
|
||
<!-- Notes -->
|
||
<t t-call="fusion_portal.accessibility_notes_section"/>
|
||
|
||
<!-- Submit Buttons -->
|
||
<t t-call="fusion_portal.accessibility_submit_buttons"/>
|
||
</form>
|
||
</div>
|
||
|
||
<!-- Scripts -->
|
||
<t t-call="fusion_portal.accessibility_form_scripts"/>
|
||
</t>
|
||
</template>
|
||
|
||
<!-- ============================================================= -->
|
||
<!-- CEILING LIFT FORM -->
|
||
<!-- ============================================================= -->
|
||
<template id="portal_accessibility_ceiling" name="Ceiling Lift Assessment">
|
||
<t t-call="portal.portal_layout">
|
||
<t t-set="breadcrumbs_searchbar" t-value="True"/>
|
||
<t t-set="no_breadcrumbs" t-value="True"/>
|
||
|
||
<div class="container py-4">
|
||
<!-- Custom Breadcrumb -->
|
||
<nav aria-label="breadcrumb" class="mb-4">
|
||
<ol class="breadcrumb">
|
||
<li class="breadcrumb-item"><a href="/my">Dashboard</a></li>
|
||
<li class="breadcrumb-item"><a href="/my/accessibility">Accessibility</a></li>
|
||
<li class="breadcrumb-item active">Ceiling Lift</li>
|
||
</ol>
|
||
</nav>
|
||
|
||
<h2 class="mb-4">
|
||
<i class="fa fa-cloud-upload text-warning"></i>
|
||
Ceiling Lift Assessment
|
||
</h2>
|
||
|
||
<form id="accessibility_form">
|
||
<input type="hidden" name="assessment_type" value="ceiling_lift"/>
|
||
|
||
<!-- Client Info -->
|
||
<t t-call="fusion_portal.accessibility_client_info_section"/>
|
||
|
||
<!-- Track Specifications -->
|
||
<div class="card mb-4">
|
||
<div class="card-header bg-warning">
|
||
<h5 class="mb-0"><i class="fa fa-arrows-h"></i> Track Specifications</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-md-6 mb-3">
|
||
<label class="form-label">Total Track Length (feet) <span class="text-danger">*</span></label>
|
||
<input type="number" name="ceiling_track_length" class="form-control"
|
||
required="required" min="0" step="0.5" placeholder="e.g., 15"/>
|
||
</div>
|
||
<div class="col-md-6 mb-3">
|
||
<label class="form-label">Horizontal Movement Type</label>
|
||
<select name="ceiling_movement_type" class="form-control">
|
||
<option value="">-- Select --</option>
|
||
<option value="manual">Manual (left-to-right)</option>
|
||
<option value="powered">Powered (left-to-right)</option>
|
||
</select>
|
||
<small class="text-muted">All ceiling lifts move up/down with power</small>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Features -->
|
||
<div class="card mb-4">
|
||
<div class="card-header bg-success text-white">
|
||
<h5 class="mb-0"><i class="fa fa-cogs"></i> Additional Features</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-md-6">
|
||
<div class="form-check mb-2">
|
||
<input type="checkbox" name="ceiling_charging_throughout" value="true" class="form-check-input" id="charging_throughout"/>
|
||
<label class="form-check-label" for="charging_throughout">Charging Throughout Track</label>
|
||
<small class="text-muted d-block">Instead of single location charging</small>
|
||
</div>
|
||
<div class="form-check mb-2">
|
||
<input type="checkbox" name="ceiling_carry_bar" value="true" class="form-check-input" id="carry_bar"/>
|
||
<label class="form-check-label" for="carry_bar">Carry Bar</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-6 mb-3">
|
||
<label class="form-label">Additional Slings Needed</label>
|
||
<input type="number" name="ceiling_additional_slings" class="form-control"
|
||
min="0" value="0" placeholder="0"/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Photos -->
|
||
<t t-call="fusion_portal.accessibility_photo_section"/>
|
||
|
||
<!-- Notes -->
|
||
<t t-call="fusion_portal.accessibility_notes_section"/>
|
||
|
||
<!-- Submit Buttons -->
|
||
<t t-call="fusion_portal.accessibility_submit_buttons"/>
|
||
</form>
|
||
</div>
|
||
|
||
<!-- Scripts -->
|
||
<t t-call="fusion_portal.accessibility_form_scripts"/>
|
||
</t>
|
||
</template>
|
||
|
||
<!-- ============================================================= -->
|
||
<!-- CUSTOM RAMP FORM -->
|
||
<!-- ============================================================= -->
|
||
<template id="portal_accessibility_ramp" name="Custom Ramp Assessment">
|
||
<t t-call="portal.portal_layout">
|
||
<t t-set="breadcrumbs_searchbar" t-value="True"/>
|
||
<t t-set="no_breadcrumbs" t-value="True"/>
|
||
|
||
<div class="container py-4">
|
||
<!-- Custom Breadcrumb -->
|
||
<nav aria-label="breadcrumb" class="mb-4">
|
||
<ol class="breadcrumb">
|
||
<li class="breadcrumb-item"><a href="/my">Dashboard</a></li>
|
||
<li class="breadcrumb-item"><a href="/my/accessibility">Accessibility</a></li>
|
||
<li class="breadcrumb-item active">Custom Ramp</li>
|
||
</ol>
|
||
</nav>
|
||
|
||
<h2 class="mb-4">
|
||
<i class="fa fa-road text-danger"></i>
|
||
Custom Ramp Assessment
|
||
</h2>
|
||
|
||
<form id="accessibility_form">
|
||
<input type="hidden" name="assessment_type" value="ramp"/>
|
||
|
||
<!-- Client Info -->
|
||
<t t-call="fusion_portal.accessibility_client_info_section"/>
|
||
|
||
<!-- Ramp Measurements -->
|
||
<div class="card mb-4">
|
||
<div class="card-header bg-danger text-white">
|
||
<h5 class="mb-0"><i class="fa fa-ruler"></i> Ramp Measurements</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-md-4 mb-3">
|
||
<label class="form-label">Total Height (inches) <span class="text-danger">*</span></label>
|
||
<input type="number" name="ramp_height" id="ramp_height" class="form-control"
|
||
required="required" min="0" step="0.5" placeholder="Height from ground"
|
||
onchange="calculateRampLength()"/>
|
||
</div>
|
||
<div class="col-md-4 mb-3">
|
||
<label class="form-label">Ground Incline (degrees)</label>
|
||
<input type="number" name="ramp_ground_incline" class="form-control"
|
||
min="0" max="45" step="0.5" placeholder="Optional"/>
|
||
<small class="text-muted">If ground is already inclined</small>
|
||
</div>
|
||
<div class="col-md-4 mb-3">
|
||
<label class="form-label">Handrail Height (inches)</label>
|
||
<input type="number" name="ramp_handrail_height" class="form-control"
|
||
value="32" min="32" step="0.5"/>
|
||
<small class="text-muted">Minimum 32" required</small>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="row">
|
||
<div class="col-md-6 mb-3">
|
||
<div class="form-check">
|
||
<input type="checkbox" name="ramp_at_door" value="true" class="form-check-input"
|
||
id="ramp_at_door" onchange="calculateRampLength()"/>
|
||
<label class="form-check-label" for="ramp_at_door">Ramp at Door</label>
|
||
<small class="text-muted d-block">Requires 5ft landing at door</small>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Calculated Values -->
|
||
<div class="alert alert-info">
|
||
<h6><i class="fa fa-calculator"></i> Ontario Building Code Calculations</h6>
|
||
<div class="row">
|
||
<div class="col-md-4">
|
||
<strong>Ramp Length:</strong>
|
||
<span id="calc_ramp_length" class="h5 ml-2">0</span> inches
|
||
<br/>
|
||
<small class="text-muted">1:12 ratio (12" per 1" height)</small>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<strong>Landings Needed:</strong>
|
||
<span id="calc_landings" class="h5 ml-2">0</span>
|
||
<br/>
|
||
<small class="text-muted">Every 30 feet (5ft each)</small>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<strong>Total Length:</strong>
|
||
<span id="calc_total_length" class="h5 ml-2">0</span> inches
|
||
<br/>
|
||
<small class="text-muted">Including landings</small>
|
||
</div>
|
||
</div>
|
||
<div class="row mt-3">
|
||
<div class="col-md-6">
|
||
<label class="form-label">Manual Override (inches)</label>
|
||
<input type="number" name="ramp_manual_override" class="form-control"
|
||
step="0.5" placeholder="Leave blank to use calculated"/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Photos -->
|
||
<t t-call="fusion_portal.accessibility_photo_section"/>
|
||
|
||
<!-- Notes -->
|
||
<t t-call="fusion_portal.accessibility_notes_section"/>
|
||
|
||
<!-- Submit Buttons -->
|
||
<t t-call="fusion_portal.accessibility_submit_buttons"/>
|
||
</form>
|
||
</div>
|
||
|
||
<!-- Scripts -->
|
||
<t t-call="fusion_portal.accessibility_form_scripts"/>
|
||
|
||
<script type="text/javascript">
|
||
function calculateRampLength() {
|
||
var height = parseFloat(document.getElementById('ramp_height').value) || 0;
|
||
var atDoor = document.getElementById('ramp_at_door').checked;
|
||
|
||
// Ontario Building Code: 12" length per 1" height
|
||
var rampLength = height * 12;
|
||
|
||
// Landings every 30 feet (360 inches)
|
||
var landings = Math.ceil(rampLength / 360);
|
||
|
||
// Each landing is 5 feet (60 inches)
|
||
var landingsLength = landings * 60;
|
||
|
||
// Door landing if at door
|
||
var doorLanding = atDoor ? 60 : 0;
|
||
|
||
var totalLength = rampLength + landingsLength + doorLanding;
|
||
|
||
document.getElementById('calc_ramp_length').textContent = rampLength.toFixed(0);
|
||
document.getElementById('calc_landings').textContent = landings;
|
||
document.getElementById('calc_total_length').textContent = totalLength.toFixed(0);
|
||
}
|
||
</script>
|
||
</t>
|
||
</template>
|
||
|
||
<!-- ============================================================= -->
|
||
<!-- BATHROOM MODIFICATION FORM -->
|
||
<!-- ============================================================= -->
|
||
<template id="portal_accessibility_bathroom" name="Bathroom Modification Assessment">
|
||
<t t-call="portal.portal_layout">
|
||
<t t-set="breadcrumbs_searchbar" t-value="True"/>
|
||
<t t-set="no_breadcrumbs" t-value="True"/>
|
||
|
||
<div class="container py-4">
|
||
<!-- Custom Breadcrumb -->
|
||
<nav aria-label="breadcrumb" class="mb-4">
|
||
<ol class="breadcrumb">
|
||
<li class="breadcrumb-item"><a href="/my">Dashboard</a></li>
|
||
<li class="breadcrumb-item"><a href="/my/accessibility">Accessibility</a></li>
|
||
<li class="breadcrumb-item active">Bathroom Modification</li>
|
||
</ol>
|
||
</nav>
|
||
|
||
<h2 class="mb-4">
|
||
<i class="fa fa-bath text-secondary"></i>
|
||
Bathroom Modification Assessment
|
||
</h2>
|
||
|
||
<form id="accessibility_form">
|
||
<input type="hidden" name="assessment_type" value="bathroom"/>
|
||
|
||
<!-- Client Info -->
|
||
<t t-call="fusion_portal.accessibility_client_info_section"/>
|
||
|
||
<!-- Modification Description -->
|
||
<div class="card mb-4">
|
||
<div class="card-header" style="background: linear-gradient(135deg, #2e7aad 0%, #1a6b9a 60%, #155d87 100%); color: white;">
|
||
<h5 class="mb-0"><i class="fa fa-pencil"></i> Modification Description</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-12 mb-3">
|
||
<label class="form-label">Describe all bathroom modifications needed <span class="text-danger">*</span></label>
|
||
<textarea name="bathroom_description" class="form-control" rows="8"
|
||
required="required"
|
||
placeholder="Describe in detail:
|
||
- What modifications are needed?
|
||
- Current bathroom layout
|
||
- Specific requirements
|
||
- Grab bar locations
|
||
- Shower/tub modifications
|
||
- Flooring changes
|
||
- Any other details..."></textarea>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Photos -->
|
||
<t t-call="fusion_portal.accessibility_photo_section"/>
|
||
|
||
<!-- Notes -->
|
||
<t t-call="fusion_portal.accessibility_notes_section"/>
|
||
|
||
<!-- Submit Buttons -->
|
||
<t t-call="fusion_portal.accessibility_submit_buttons"/>
|
||
</form>
|
||
</div>
|
||
|
||
<!-- Scripts -->
|
||
<t t-call="fusion_portal.accessibility_form_scripts"/>
|
||
</t>
|
||
</template>
|
||
|
||
<!-- ============================================================= -->
|
||
<!-- TUB CUTOUT FORM -->
|
||
<!-- ============================================================= -->
|
||
<template id="portal_accessibility_tub_cutout" name="Tub Cutout Assessment">
|
||
<t t-call="portal.portal_layout">
|
||
<t t-set="breadcrumbs_searchbar" t-value="True"/>
|
||
<t t-set="no_breadcrumbs" t-value="True"/>
|
||
|
||
<div class="container py-4">
|
||
<!-- Custom Breadcrumb -->
|
||
<nav aria-label="breadcrumb" class="mb-4">
|
||
<ol class="breadcrumb">
|
||
<li class="breadcrumb-item"><a href="/my">Dashboard</a></li>
|
||
<li class="breadcrumb-item"><a href="/my/accessibility">Accessibility</a></li>
|
||
<li class="breadcrumb-item active">Tub Cutout</li>
|
||
</ol>
|
||
</nav>
|
||
|
||
<h2 class="mb-4">
|
||
<i class="fa fa-cut" style="color: #6c5ce7;"></i>
|
||
Tub Cutout Assessment
|
||
</h2>
|
||
|
||
<form id="accessibility_form">
|
||
<input type="hidden" name="assessment_type" value="tub_cutout"/>
|
||
|
||
<!-- Client Info -->
|
||
<t t-call="fusion_portal.accessibility_client_info_section"/>
|
||
|
||
<!-- Tub Measurements -->
|
||
<div class="card mb-4">
|
||
<div class="card-header" style="background: #6c5ce7; color: white;">
|
||
<h5 class="mb-0"><i class="fa fa-ruler"></i> Tub Measurements</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-md-6 mb-3">
|
||
<label class="form-label">Internal Height of Tub (inches) <span class="text-danger">*</span></label>
|
||
<input type="number" name="tub_internal_height" class="form-control"
|
||
required="required" min="0" step="0.5" placeholder="Internal height"/>
|
||
<small class="text-muted">Measure from inside bottom to top edge</small>
|
||
</div>
|
||
<div class="col-md-6 mb-3">
|
||
<label class="form-label">External Height of Tub (inches) <span class="text-danger">*</span></label>
|
||
<input type="number" name="tub_external_height" class="form-control"
|
||
required="required" min="0" step="0.5" placeholder="External height"/>
|
||
<small class="text-muted">Measure from floor to top edge</small>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Additional Supplies -->
|
||
<div class="card mb-4">
|
||
<div class="card-header bg-info text-white">
|
||
<h5 class="mb-0"><i class="fa fa-shopping-cart"></i> Additional Supplies</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-12 mb-3">
|
||
<label class="form-label">Additional supplies needed with the modification</label>
|
||
<textarea name="tub_additional_supplies" class="form-control" rows="4"
|
||
placeholder="List any additional supplies needed:
|
||
- Grab bars
|
||
- Non-slip mats
|
||
- Shower seat
|
||
- Other items..."></textarea>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Photos -->
|
||
<t t-call="fusion_portal.accessibility_photo_section"/>
|
||
|
||
<!-- Notes -->
|
||
<t t-call="fusion_portal.accessibility_notes_section"/>
|
||
|
||
<!-- Submit Buttons -->
|
||
<t t-call="fusion_portal.accessibility_submit_buttons"/>
|
||
</form>
|
||
</div>
|
||
|
||
<!-- Scripts -->
|
||
<t t-call="fusion_portal.accessibility_form_scripts"/>
|
||
</t>
|
||
</template>
|
||
|
||
</odoo>
|