From e8e554de955dcd00f5009ba45b9f98b7da57e6ef Mon Sep 17 00:00:00 2001 From: gsinghpal Date: Mon, 23 Feb 2026 00:32:20 -0500 Subject: [PATCH] changes --- fusion_accounts/fusion_accounts/__init__.py | 5 - .../fusion_accounts/__manifest__.py | 45 - .../data/ir_config_parameter_data.xml | 36 - .../fusion_accounts/models/__init__.py | 9 - .../fusion_accounts/models/account_move.py | 265 - .../models/ai_bill_extractor.py | 614 - .../models/fusion_accounts_log.py | 140 - .../models/res_config_settings.py | 84 - .../fusion_accounts/models/res_partner.py | 47 - .../security/ir.model.access.csv | 3 - .../fusion_accounts/security/security.xml | 25 - .../static/description/icon.png | Bin 14697 -> 0 bytes .../views/account_move_views.xml | 63 - .../views/fusion_accounts_dashboard.xml | 92 - .../views/fusion_accounts_log_views.xml | 130 - .../views/fusion_accounts_menus.xml | 190 - .../views/res_config_settings_views.xml | 73 - .../views/res_partner_views.xml | 59 - fusion_authorizer_portal/.DS_Store | Bin 0 -> 6148 bytes .../controllers/pdf_editor.py | 3 + .../fusion_authorizer_portal/README.md | 721 - .../fusion_authorizer_portal/__init__.py | 4 - .../fusion_authorizer_portal/__manifest__.py | 100 - .../controllers/__init__.py | 5 - .../controllers/pdf_editor.py | 218 - .../controllers/portal_assessment.py | 1443 -- .../controllers/portal_main.py | 2468 --- .../data/ir_actions_server_data.xml | 42 - .../data/mail_template_data.xml | 172 - .../data/portal_menu_data.xml | 7 - .../data/welcome_articles.xml | 432 - .../models/__init__.py | 10 - .../models/accessibility_assessment.py | 874 - .../models/adp_document.py | 183 - .../models/assessment.py | 1633 -- .../models/authorizer_comment.py | 85 - .../models/pdf_template.py | 328 - .../models/res_partner.py | 764 - .../models/res_users.py | 119 - .../models/sale_order.py | 250 - .../security/ir.model.access.csv | 12 - .../security/portal_security.xml | 140 - .../static/description/icon.png | Bin 54735 -> 0 bytes .../static/src/css/portal_style.css | 864 - .../static/src/css/technician_portal.css | 540 - .../static/src/js/assessment_form.js | 109 - .../src/js/chatter_message_authorizer.js | 37 - .../static/src/js/loaner_portal.js | 478 - .../static/src/js/pdf_field_editor.js | 716 - .../static/src/js/portal_search.js | 161 - .../static/src/js/signature_pad.js | 167 - .../static/src/js/technician_location.js | 97 - .../static/src/js/technician_push.js | 96 - .../static/src/js/technician_sw.js | 77 - .../src/xml/chatter_message_authorizer.xml | 27 - .../utils/__init__.py | 3 - .../utils/pdf_filler.py | 146 - .../views/assessment_views.xml | 258 - .../views/pdf_template_views.xml | 171 - .../views/portal_accessibility_forms.xml | 1222 -- .../views/portal_accessibility_templates.xml | 712 - .../views/portal_assessment_express.xml | 1622 -- .../views/portal_book_assessment.xml | 153 - .../views/portal_pdf_editor.xml | 184 - .../views/portal_technician_templates.xml | 1455 -- .../views/portal_templates.xml | 3698 ---- .../views/res_partner_views.xml | 123 - .../views/sale_order_views.xml | 49 - fusion_authorizer_portal/models/assessment.py | 12 + .../models/pdf_template.py | 6 + .../static/src/js/pdf_field_editor.js | 226 +- fusion_authorizer_portal/utils/pdf_filler.py | 20 +- .../views/portal_assessment_express.xml | 70 +- .../views/portal_pdf_editor.xml | 37 +- fusion_claims/__manifest__.py | 9 +- .../data/ir_config_parameter_data.xml | 6 + fusion_claims/data/ir_cron_data.xml | 23 + fusion_claims/data/mail_template_data.xml | 49 +- fusion_claims/data/pdf_template_data.xml | 19 +- fusion_claims/fusion_claims/LICENSE | 30 - fusion_claims/fusion_claims/README.md | 199 - fusion_claims/fusion_claims/__init__.py | 15 - fusion_claims/fusion_claims/__manifest__.py | 180 - .../fusion_claims/data/ai_agent_data.xml | 93 - .../device_codes/adp_mobility_manual.json | 17057 ---------------- .../data/ir_actions_server_data.xml | 30 - .../data/ir_config_parameter_data.xml | 157 - .../fusion_claims/data/ir_cron_data.xml | 183 - .../data/mail_activity_type_data.xml | 55 - .../fusion_claims/data/mail_template_data.xml | 174 - .../fusion_claims/data/pdf_template_data.xml | 7 - .../fusion_claims/data/product_labor_data.xml | 15 - .../data/stock_location_data.xml | 41 - .../fusion_claims/models/__init__.py | 34 - .../fusion_claims/models/account_move.py | 1217 -- .../fusion_claims/models/account_move_line.py | 247 - .../fusion_claims/models/account_payment.py | 21 - .../models/account_payment_method_line.py | 16 - .../models/adp_application_data.py | 670 - .../models/adp_posting_schedule.py | 262 - .../fusion_claims/models/ai_agent_ext.py | 164 - .../fusion_claims/models/client_chat.py | 350 - .../fusion_claims/models/client_profile.py | 298 - .../fusion_claims/models/dashboard.py | 162 - .../models/email_builder_mixin.py | 242 - .../models/fusion_adp_device_code.py | 390 - .../models/fusion_central_config.py | 126 - .../models/fusion_loaner_checkout.py | 799 - .../models/fusion_loaner_history.py | 105 - .../fusion_claims/models/product_product.py | 185 - .../fusion_claims/models/product_template.py | 109 - .../fusion_claims/models/push_subscription.py | 73 - .../fusion_claims/models/res_company.py | 69 - .../models/res_config_settings.py | 602 - .../fusion_claims/models/res_partner.py | 82 - .../fusion_claims/models/res_users.py | 26 - .../fusion_claims/models/sale_order.py | 7817 ------- .../fusion_claims/models/sale_order_line.py | 362 - .../models/submission_history.py | 237 - .../models/technician_location.py | 116 - .../fusion_claims/models/technician_task.py | 2307 --- .../fusion_claims/models/xml_parser.py | 735 - .../report/invoice_report_landscape.xml | 410 - .../report/invoice_report_portrait.xml | 377 - .../report/report_accessibility_contract.xml | 342 - .../fusion_claims/report/report_actions.xml | 184 - .../report/report_grab_bar_waiver.xml | 184 - .../report/report_invoice_adp.xml | 1 - .../report/report_mod_invoice.xml | 227 - .../report/report_mod_quotation.xml | 250 - .../report/report_proof_of_delivery.xml | 303 - .../report_proof_of_delivery_standard.xml | 289 - .../report/report_proof_of_pickup.xml | 260 - .../report/report_rental_agreement.xml | 340 - .../report/report_saleorder_adp.xml | 1 - .../fusion_claims/report/report_templates.xml | 203 - .../report/sale_report_landscape.xml | 303 - .../report/sale_report_portrait.xml | 281 - .../scripts/import_adp_mobility_manual.py | 196 - .../security/ir.model.access.csv | 75 - .../fusion_claims/security/security.xml | 141 - .../fusion_claims/static/description/icon.png | Bin 46059 -> 0 bytes .../fusion_claims/static/img/nexa_favicon.png | Bin 12784 -> 0 bytes .../fusion_claims/static/img/nexa_logo.png | Bin 24280 -> 0 bytes .../static/src/css/fusion_task_map_view.scss | 386 - .../src/js/attachment_image_compress.js | 192 - .../static/src/js/calendar_store_hours.js | 22 - .../static/src/js/chatter_resize.js | 40 - .../static/src/js/document_preview.js | 296 - .../static/src/js/fusion_task_map_view.js | 678 - .../static/src/js/gallery_preview.js | 120 - .../src/js/google_address_autocomplete.js | 1480 -- .../static/src/js/preview_button_widget.js | 53 - .../static/src/js/status_selection_filter.js | 63 - .../static/src/js/tax_totals_patch.js | 30 - .../discretionary_benefits_form_template.pdf | Bin 1084626 -> 0 bytes .../src/pdf/sa_mobility_form_template.pdf | Bin 482287 -> 0 bytes .../src/pdf/sa_mobility_page2_sample.pdf | Bin 241053 -> 0 bytes .../static/src/scss/fusion_claims.scss | 872 - .../static/src/xml/document_preview.xml | 204 - .../static/src/xml/fusion_task_map_view.xml | 225 - .../views/account_journal_views.xml | 26 - .../views/account_move_views.xml | 394 - .../fusion_claims/views/adp_claims_views.xml | 1163 -- .../fusion_claims/views/client_chat_views.xml | 87 - .../views/client_profile_views.xml | 723 - .../fusion_claims/views/dashboard_views.xml | 165 - .../views/fusion_loaner_views.xml | 261 - .../views/pdf_template_inherit_views.xml | 6 - .../fusion_claims/views/res_company_views.xml | 39 - .../views/res_config_settings_views.xml | 537 - .../fusion_claims/views/res_partner_views.xml | 77 - .../fusion_claims/views/sale_order_views.xml | 2502 --- .../views/submission_history_views.xml | 80 - .../views/technician_location_views.xml | 128 - .../views/technician_task_views.xml | 480 - .../fusion_claims/wizard/__init__.py | 32 - .../wizard/account_payment_register.py | 79 - .../wizard/account_payment_register_views.xml | 27 - .../fusion_claims/wizard/adp_export_wizard.py | 617 - .../wizard/adp_export_wizard_views.xml | 71 - .../wizard/application_received_wizard.py | 130 - .../application_received_wizard_views.xml | 51 - .../wizard/assessment_completed_wizard.py | 82 - .../assessment_completed_wizard_views.xml | 31 - .../wizard/case_close_verification_wizard.py | 211 - .../case_close_verification_wizard_views.xml | 99 - .../wizard/device_approval_wizard.py | 724 - .../wizard/device_approval_wizard_views.xml | 139 - .../wizard/device_import_wizard.py | 191 - .../wizard/device_import_wizard_views.xml | 64 - .../wizard/field_mapping_config_wizard.py | 460 - .../field_mapping_config_wizard_views.xml | 97 - .../wizard/loaner_checkout_wizard.py | 237 - .../wizard/loaner_return_wizard.py | 139 - .../wizard/mod_awaiting_funding_wizard.py | 52 - .../mod_awaiting_funding_wizard_views.xml | 26 - .../wizard/mod_funding_approved_wizard.py | 74 - .../mod_funding_approved_wizard_views.xml | 33 - .../wizard/mod_pca_received_wizard.py | 304 - .../wizard/mod_pca_received_wizard_views.xml | 69 - .../wizard/odsp_discretionary_wizard.py | 395 - .../odsp_discretionary_wizard_views.xml | 67 - .../wizard/odsp_pre_approved_wizard.py | 70 - .../wizard/odsp_pre_approved_wizard_views.xml | 23 - .../wizard/odsp_ready_delivery_wizard.py | 218 - .../odsp_ready_delivery_wizard_views.xml | 47 - .../wizard/odsp_sa_mobility_wizard.py | 560 - .../wizard/odsp_sa_mobility_wizard_views.xml | 142 - .../wizard/odsp_submit_to_odsp_wizard.py | 233 - .../odsp_submit_to_odsp_wizard_views.xml | 56 - .../wizard/ready_for_delivery_wizard.py | 214 - .../ready_for_delivery_wizard_views.xml | 55 - .../wizard/ready_for_submission_wizard.py | 196 - .../ready_for_submission_wizard_views.xml | 96 - .../wizard/ready_to_bill_wizard.py | 185 - .../wizard/ready_to_bill_wizard_views.xml | 61 - .../wizard/sale_advance_payment_inv.py | 125 - .../wizard/sale_advance_payment_inv_views.xml | 1 - .../wizard/schedule_assessment_wizard.py | 214 - .../schedule_assessment_wizard_views.xml | 45 - .../wizard/send_to_mod_wizard.py | 335 - .../wizard/send_to_mod_wizard_views.xml | 100 - .../wizard/status_change_reason_wizard.py | 410 - .../status_change_reason_wizard_views.xml | 143 - .../wizard/submission_verification_wizard.py | 397 - .../submission_verification_wizard_views.xml | 127 - .../wizard/temp_serial_migration_views.xml | 1 - .../fusion_claims/wizard/xml_import_wizard.py | 107 - .../wizard/xml_import_wizard_views.xml | 41 - fusion_claims/models/__init__.py | 4 +- fusion_claims/models/pdf_template_inherit.py | 162 - fusion_claims/models/res_users.py | 6 + fusion_claims/models/sale_order.py | 167 +- .../{fusion_claims => }/models/task_sync.py | 0 fusion_claims/models/technician_task.py | 190 +- fusion_claims/report/report_actions.xml | 2 +- fusion_claims/report/report_mod_invoice.xml | 10 +- fusion_claims/report/report_mod_quotation.xml | 13 +- fusion_claims/report/report_templates.xml | 34 +- fusion_claims/security/ir.model.access.csv | 4 +- .../static/nuke_cache.html | 0 .../static/src/css/fusion_task_map_view.scss | 23 +- .../static/src/js/fusion_task_map_view.js | 19 +- .../static/src/xml/fusion_task_map_view.xml | 15 +- fusion_claims/views/adp_claims_views.xml | 149 +- .../views/pdf_template_inherit_views.xml | 105 +- .../views/task_sync_views.xml | 0 fusion_claims/views/technician_task_views.xml | 59 +- .../wizard/device_approval_wizard.py | 14 +- .../wizard/device_approval_wizard_views.xml | 7 +- .../wizard/odsp_ready_delivery_wizard.py | 122 +- .../odsp_ready_delivery_wizard_views.xml | 6 +- fusion_clock/__init__.py | 13 - fusion_clock/__manifest__.py | 3 - fusion_clock/controllers/clock_api.py | 1 - fusion_clock/fusion_clock/__init__.py | 19 - fusion_clock/fusion_clock/__manifest__.py | 81 - .../fusion_clock/controllers/__init__.py | 4 - .../fusion_clock/controllers/clock_api.py | 366 - .../fusion_clock/controllers/portal_clock.py | 263 - .../data/ir_config_parameter_data.xml | 74 - .../fusion_clock/data/ir_cron_data.xml | 28 - .../fusion_clock/data/mail_template_data.xml | 85 - fusion_clock/fusion_clock/models/__init__.py | 8 - .../fusion_clock/models/clock_location.py | 182 - .../fusion_clock/models/clock_penalty.py | 67 - .../fusion_clock/models/clock_report.py | 425 - .../fusion_clock/models/hr_attendance.py | 330 - .../fusion_clock/models/hr_employee.py | 100 - .../models/res_config_settings.py | 215 - .../report/clock_employee_report.xml | 145 - .../report/clock_report_template.xml | 90 - .../fusion_clock/security/ir.model.access.csv | 12 - .../fusion_clock/security/security.xml | 129 - .../fusion_clock/static/description/icon.png | Bin 45935 -> 0 bytes .../static/src/css/portal_clock.css | 1259 -- .../static/src/js/fclk_location_map.js | 300 - .../static/src/js/fusion_clock_portal.js | 502 - .../static/src/js/fusion_clock_portal_fab.js | 330 - .../static/src/js/fusion_clock_systray.js | 183 - .../static/src/scss/fusion_clock.scss | 378 - .../static/src/xml/location_map.xml | 47 - .../static/src/xml/systray_clock.xml | 88 - .../views/clock_location_views.xml | 118 - .../fusion_clock/views/clock_menus.xml | 91 - .../views/clock_penalty_views.xml | 88 - .../fusion_clock/views/clock_report_views.xml | 135 - .../views/hr_attendance_views.xml | 269 - .../views/portal_clock_templates.xml | 344 - .../views/portal_report_templates.xml | 96 - .../views/portal_timesheet_templates.xml | 146 - .../views/res_config_settings_views.xml | 166 - fusion_clock/models/clock_report.py | 120 - fusion_clock/models/hr_attendance.py | 180 +- fusion_clock/models/hr_employee.py | 64 - fusion_clock/models/res_config_settings.py | 97 +- fusion_clock/static/src/css/portal_clock.css | 22 +- .../static/src/js/fclk_location_map.js | 300 - .../static/src/js/fusion_clock_portal.js | 54 +- fusion_clock/static/src/xml/location_map.xml | 47 - fusion_clock/views/clock_location_views.xml | 16 +- fusion_clock/views/clock_menus.xml | 24 +- fusion_clock/views/hr_attendance_views.xml | 230 +- fusion_clock/views/portal_clock_templates.xml | 43 +- .../views/res_config_settings_views.xml | 163 +- fusion_faxes/__manifest__.py | 5 + fusion_faxes/fusion_faxes/__init__.py | 6 - fusion_faxes/fusion_faxes/__manifest__.py | 63 - .../data/ir_config_parameter_data.xml | 36 - .../fusion_faxes/data/ir_cron_data.xml | 16 - .../fusion_faxes/data/ir_sequence_data.xml | 14 - fusion_faxes/fusion_faxes/models/__init__.py | 11 - .../fusion_faxes/models/account_move.py | 51 - fusion_faxes/fusion_faxes/models/dashboard.py | 88 - .../fusion_faxes/models/fusion_fax.py | 581 - .../models/fusion_fax_document.py | 48 - .../models/res_config_settings.py | 125 - .../fusion_faxes/models/res_partner.py | 37 - .../fusion_faxes/models/sale_order.py | 51 - .../fusion_faxes/security/ir.model.access.csv | 8 - .../fusion_faxes/security/security.xml | 36 - .../fusion_faxes/static/description/icon.png | Bin 43466 -> 0 bytes .../fusion_faxes/views/account_move_views.xml | 31 - .../fusion_faxes/views/dashboard_views.xml | 156 - .../fusion_faxes/views/fusion_fax_views.xml | 259 - .../views/res_config_settings_views.xml | 115 - .../fusion_faxes/views/res_partner_views.xml | 51 - .../fusion_faxes/views/sale_order_views.xml | 31 - fusion_faxes/fusion_faxes/wizard/__init__.py | 6 - .../fusion_faxes/wizard/send_fax_wizard.py | 162 - .../wizard/send_fax_wizard_line.py | 45 - .../wizard/send_fax_wizard_views.xml | 64 - .../static/src/css/partner_mobile.css | 0 fusion_faxes/views/res_partner_views.xml | 10 +- .../fusion_inventory_sync/__init__.py | 2 - .../fusion_inventory_sync/__manifest__.py | 32 - .../data/ir_cron_data.xml | 14 - .../fusion_inventory_sync/models/__init__.py | 6 - .../models/product_sync_mapping.py | 38 - .../models/product_template.py | 33 - .../models/stock_move.py | 116 - .../models/sync_config.py | 257 - .../fusion_inventory_sync/models/sync_log.py | 30 - .../security/ir.model.access.csv | 7 - .../static/description/icon.png | Bin 46059 -> 0 bytes .../views/product_views.xml | 49 - .../views/sync_config_views.xml | 179 - fusion_notes/fusion_notes/__init__.py | 6 - fusion_notes/fusion_notes/__manifest__.py | 47 - .../fusion_notes/controllers/__init__.py | 2 - fusion_notes/fusion_notes/controllers/main.py | 237 - .../data/ir_config_parameter_data.xml | 24 - fusion_notes/fusion_notes/models/__init__.py | 2 - .../models/res_config_settings.py | 72 - .../fusion_notes/static/description/icon.png | Bin 50138 -> 0 bytes .../static/src/js/voice_note_button.js | 416 - .../static/src/js/voice_note_service.js | 265 - .../static/src/scss/fusion_notes.scss | 104 - .../static/src/xml/voice_note_button.xml | 123 - .../views/res_config_settings_views.xml | 99 - .../static/src/scss/fusion_notes.scss | 4 +- .../fusion_payroll/T4-Employer-Empty.pdf | Bin 56959 -> 0 bytes fusion_payroll/fusion_payroll/T4-Empty.pdf | Bin 56951 -> 0 bytes fusion_payroll/fusion_payroll/__init__.py | 5 - fusion_payroll/fusion_payroll/__manifest__.py | 129 - .../fusion_payroll/controllers/__init__.py | 3 - .../controllers/payroll_report.py | 249 - .../data/hr_payroll_structure.xml | 135 - .../data/hr_payslip_input_type_data.xml | 60 - .../data/hr_rule_parameter_data.xml | 222 - .../fusion_payroll/data/hr_salary_rules.xml | 358 - .../data/tax_yearly_rates_data.xml | 134 - .../fusion_payroll/demo/demo_data.xml | 324 - .../Reports/PayrollAggregatedReport (1).xls | Bin 68096 -> 0 bytes .../Reports/Screenshot 2026-01-01 035249.png | Bin 72834 -> 0 bytes .../Reports/Screenshot 2026-01-01 035258.png | Bin 18255 -> 0 bytes .../Reports/Screenshot 2026-01-01 035303.png | Bin 18017 -> 0 bytes .../Reports/Screenshot 2026-01-01 035333.png | Bin 41472 -> 0 bytes .../Reports/Screenshot 2026-01-01 035354.png | Bin 227916 -> 0 bytes .../Reports/Screenshot 2026-01-01 035521.png | Bin 337926 -> 0 bytes .../Reports/Screenshot 2026-01-01 035540.png | Bin 120549 -> 0 bytes .../Reports/Screenshot 2026-01-01 035602.png | Bin 331886 -> 0 bytes .../Reports/Screenshot 2026-01-01 035622.png | Bin 50626 -> 0 bytes .../Reports/Screenshot 2026-01-01 035645.png | Bin 87236 -> 0 bytes .../Reports/Screenshot 2026-01-01 035715.png | Bin 39822 -> 0 bytes .../Reports/Screenshot 2026-01-01 035739.png | Bin 84350 -> 0 bytes .../Reports/Screenshot 2026-01-01 035808.png | Bin 39273 -> 0 bytes .../Reports/Screenshot 2026-01-01 035821.png | Bin 52526 -> 0 bytes .../Reports/Screenshot 2026-01-01 035834.png | Bin 96143 -> 0 bytes .../Reports/Screenshot 2026-01-01 035855.png | Bin 51036 -> 0 bytes .../Screenshot 2025-12-31 234850.png | Bin 124059 -> 0 bytes .../Screenshot 2025-12-31 234901.png | Bin 75640 -> 0 bytes .../Screenshot 2025-12-31 234913.png | Bin 68983 -> 0 bytes .../Screenshot 2025-12-31 234935.png | Bin 31180 -> 0 bytes .../Screenshot 2025-12-31 235044.png | Bin 56760 -> 0 bytes .../Screenshot 2025-12-31 235055.png | Bin 43481 -> 0 bytes .../Screenshot 2025-12-31 235107.png | Bin 78069 -> 0 bytes .../Screenshot 2025-12-31 235117.png | Bin 16089 -> 0 bytes .../Screenshot 2025-12-31 235132.png | Bin 69376 -> 0 bytes .../Screenshot 2025-12-31 235144.png | Bin 44831 -> 0 bytes .../Screenshot 2025-12-31 235207.png | Bin 87291 -> 0 bytes .../Screenshot 2025-12-31 235216.png | Bin 17422 -> 0 bytes .../Screenshot 2025-12-31 235227.png | Bin 22147 -> 0 bytes .../Screenshot 2025-12-31 235514.png | Bin 101807 -> 0 bytes .../Screenshot 2025-12-31 235525.png | Bin 69284 -> 0 bytes .../Screenshot 2025-12-31 235631.png | Bin 204984 -> 0 bytes .../Screenshot 2026-01-01 000003.png | Bin 43243 -> 0 bytes .../Screenshot 2026-01-01 000024.png | Bin 36913 -> 0 bytes .../Screenshot 2026-01-01 000347.png | Bin 54677 -> 0 bytes .../Screenshot 2026-01-01 000355.png | Bin 42591 -> 0 bytes .../Screenshot 2026-01-01 000408.png | Bin 19922 -> 0 bytes .../Screenshot 2026-01-01 000416.png | Bin 22262 -> 0 bytes .../Screenshot 2026-01-01 000425.png | Bin 18724 -> 0 bytes .../Screenshot 2026-01-01 000432.png | Bin 20468 -> 0 bytes .../Screenshot 2026-01-01 000440.png | Bin 20023 -> 0 bytes .../Screenshot 2026-01-01 000446.png | Bin 20505 -> 0 bytes .../Screenshot 2026-01-01 001008.png | Bin 34368 -> 0 bytes .../Screenshot 2026-01-01 001105.png | Bin 249709 -> 0 bytes .../Screenshot 2026-01-01 001113.png | Bin 274444 -> 0 bytes .../Screenshot 2026-01-01 001138.png | Bin 268317 -> 0 bytes .../Screenshot 2026-01-01 001152.png | Bin 55403 -> 0 bytes .../Screenshot 2026-01-01 001212.png | Bin 3841 -> 0 bytes .../Screenshot 2026-01-01 001233.png | Bin 81629 -> 0 bytes .../Screenshot 2026-01-01 001526.png | Bin 126993 -> 0 bytes .../Screenshot 2026-01-01 001623.png | Bin 218033 -> 0 bytes .../Screenshot 2026-01-01 001746.png | Bin 159385 -> 0 bytes .../Screenshot 2026-01-01 001757.png | Bin 4405 -> 0 bytes .../Screenshot 2026-01-01 001842.png | Bin 30517 -> 0 bytes .../Screenshot 2026-01-01 002136.png | Bin 113624 -> 0 bytes .../Screenshot 2026-01-01 002149.png | Bin 370592 -> 0 bytes .../Screenshot 2026-01-01 002156.png | Bin 709353 -> 0 bytes .../Screenshot 2026-01-01 023231.png | Bin 114101 -> 0 bytes .../fusion_payroll/docs/ENHANCEMENT_PLAN.md | 1183 -- .../fusion_payroll/docs/EXTRACTION_LOG.md | 188 - .../docs/PDF_FIELD_POSITIONING.md | 444 - fusion_payroll/fusion_payroll/docs/README.md | 113 - .../fusion_payroll/docs/models/README.md | 11 - .../fusion_payroll/models/__init__.py | 26 - .../models/cheque_layout_settings.py | 506 - .../fusion_payroll/models/hr_contract.py | 25 - .../fusion_payroll/models/hr_employee.py | 468 - .../fusion_payroll/models/hr_payroll_t4.py | 1555 -- .../fusion_payroll/models/hr_payroll_t4a.py | 704 - .../fusion_payroll/models/hr_payslip.py | 380 - .../fusion_payroll/models/hr_roe.py | 528 - .../models/hr_salary_rule_category.py | 89 - .../models/hr_tax_remittance.py | 306 - .../fusion_payroll/models/pay_period.py | 387 - .../models/payroll_accounting_mapping.py | 46 - .../fusion_payroll/models/payroll_cheque.py | 614 - .../models/payroll_config_settings.py | 546 - .../models/payroll_dashboard.py | 379 - .../fusion_payroll/models/payroll_entry.py | 485 - .../fusion_payroll/models/payroll_report.py | 465 - .../models/payroll_report_cost.py | 422 - .../models/payroll_report_employee.py | 178 - .../models/payroll_report_paycheque.py | 232 - .../models/payroll_report_summary.py | 282 - .../models/payroll_report_tax.py | 350 - .../models/payroll_tax_payment_schedule.py | 131 - .../models/payroll_work_location.py | 103 - .../models/pdf_field_position.py | 97 - .../models/tax_yearly_rate_line.py | 21 - .../fusion_payroll/models/tax_yearly_rates.py | 60 - .../fusion_payroll/not for submission.png | Bin 66433 -> 0 bytes .../reports/payroll_cheque_report.xml | 362 - .../reports/payroll_report_pdf.xml | 74 - .../reports/payroll_reports.xml | 848 - .../reports/report_paystub_canada.xml | 345 - .../security/ir.model.access.csv | 53 - .../static/description/icon.png | Bin 79454 -> 0 bytes .../static/description/icon.svg | 1 - .../static/description/not_for_submission.png | Bin 66433 -> 0 bytes .../static/src/css/roe_report.css | 154 - .../static/src/js/payroll_report_action.js | 266 - .../static/src/js/report_hub.js | 48 - .../static/src/scss/payroll_report.scss | 96 - .../src/xml/payroll_report_templates.xml | 162 - .../static/src/xml/report_hub.xml | 185 - fusion_payroll/fusion_payroll/t4-fill-25e.pdf | Bin 232721 -> 0 bytes .../fusion_payroll/t4a-fill-25e.pdf | Bin 210682 -> 0 bytes .../fusion_payroll/t4sum-fill-25e.pdf | Bin 203494 -> 0 bytes .../views/cheque_layout_settings_views.xml | 261 - .../views/cheque_number_wizard_views.xml | 25 - .../views/fusion_payroll_menus.xml | 528 - .../views/hr_employee_views.xml | 321 - .../fusion_payroll/views/hr_payslip_views.xml | 277 - .../fusion_payroll/views/hr_roe_views.xml | 172 - .../fusion_payroll/views/hr_t4_views.xml | 293 - .../fusion_payroll/views/hr_t4a_views.xml | 235 - .../views/hr_tax_centre_views.xml | 253 - .../fusion_payroll/views/pay_period_views.xml | 147 - .../payroll_cheque_print_wizard_views.xml | 63 - .../views/payroll_cheque_views.xml | 301 - .../views/payroll_config_settings_views.xml | 308 - .../views/payroll_dashboard_views.xml | 254 - .../views/payroll_report_views.xml | 119 - .../payroll_tax_payment_schedule_views.xml | 19 - .../views/payroll_work_location_views.xml | 113 - .../views/pdf_field_position_views.xml | 99 - .../views/run_payroll_wizard_views.xml | 483 - .../views/tax_yearly_rates_views.xml | 75 - .../fusion_payroll/wizards/__init__.py | 7 - .../wizards/cheque_number_wizard.py | 132 - .../wizards/hr_employee_sin_wizard.py | 81 - .../wizards/hr_employee_terminate_wizard.py | 175 - .../wizards/payroll_cheque_print_wizard.py | 213 - .../wizards/run_payroll_wizard.py | 865 - fusion_ringcentral/controllers/widget.py | 4 +- fusion_ringcentral/data/ir_cron_data.xml | 12 + .../fusion_ringcentral/__init__.py | 6 - .../fusion_ringcentral/__manifest__.py | 70 - .../controllers/__init__.py | 8 - .../fusion_ringcentral/controllers/oauth.py | 51 - .../controllers/recording.py | 50 - .../fusion_ringcentral/controllers/webhook.py | 96 - .../fusion_ringcentral/controllers/widget.py | 23 - .../fusion_ringcentral/data/ir_cron_data.xml | 142 - .../data/ir_sequence_data.xml | 22 - .../fusion_ringcentral/models/__init__.py | 11 - .../fusion_ringcentral/models/fusion_fax.py | 391 - .../models/rc_call_dashboard.py | 201 - .../models/rc_call_history.py | 488 - .../fusion_ringcentral/models/rc_config.py | 643 - .../fusion_ringcentral/models/rc_voicemail.py | 849 - .../models/res_config_settings.py | 15 - .../fusion_ringcentral/models/res_partner.py | 48 - .../security/ir.model.access.csv | 18 - .../fusion_ringcentral/security/security.xml | 129 - .../static/description/icon.png | Bin 12801 -> 0 bytes .../static/src/js/rc_click_to_dial.js | 37 - .../static/src/js/rc_phone_widget.js | 92 - .../static/src/js/rc_systray.js | 89 - .../static/src/xml/rc_systray.xml | 11 - .../views/fusion_fax_views.xml | 46 - .../views/rc_call_dashboard_views.xml | 282 - .../views/rc_call_history_views.xml | 264 - .../views/rc_config_views.xml | 170 - .../fusion_ringcentral/views/rc_fax_menus.xml | 45 - .../views/rc_voicemail_views.xml | 217 - .../views/res_config_settings_views.xml | 28 - .../views/res_partner_views.xml | 47 - fusion_ringcentral/models/fusion_fax.py | 203 + fusion_ringcentral/models/rc_config.py | 34 + .../security/ir.model.access.csv | 11 + fusion_ringcentral/security/security.xml | 117 +- .../static/src/js/rc_phone_widget.js | 12 +- fusion_ringcentral/views/rc_config_views.xml | 13 +- 549 files changed, 1330 insertions(+), 124935 deletions(-) delete mode 100644 fusion_accounts/fusion_accounts/__init__.py delete mode 100644 fusion_accounts/fusion_accounts/__manifest__.py delete mode 100644 fusion_accounts/fusion_accounts/data/ir_config_parameter_data.xml delete mode 100644 fusion_accounts/fusion_accounts/models/__init__.py delete mode 100644 fusion_accounts/fusion_accounts/models/account_move.py delete mode 100644 fusion_accounts/fusion_accounts/models/ai_bill_extractor.py delete mode 100644 fusion_accounts/fusion_accounts/models/fusion_accounts_log.py delete mode 100644 fusion_accounts/fusion_accounts/models/res_config_settings.py delete mode 100644 fusion_accounts/fusion_accounts/models/res_partner.py delete mode 100644 fusion_accounts/fusion_accounts/security/ir.model.access.csv delete mode 100644 fusion_accounts/fusion_accounts/security/security.xml delete mode 100644 fusion_accounts/fusion_accounts/static/description/icon.png delete mode 100644 fusion_accounts/fusion_accounts/views/account_move_views.xml delete mode 100644 fusion_accounts/fusion_accounts/views/fusion_accounts_dashboard.xml delete mode 100644 fusion_accounts/fusion_accounts/views/fusion_accounts_log_views.xml delete mode 100644 fusion_accounts/fusion_accounts/views/fusion_accounts_menus.xml delete mode 100644 fusion_accounts/fusion_accounts/views/res_config_settings_views.xml delete mode 100644 fusion_accounts/fusion_accounts/views/res_partner_views.xml create mode 100644 fusion_authorizer_portal/.DS_Store delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/README.md delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/__init__.py delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/__manifest__.py delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/controllers/__init__.py delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/controllers/pdf_editor.py delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/controllers/portal_assessment.py delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/controllers/portal_main.py delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/data/ir_actions_server_data.xml delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/data/mail_template_data.xml delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/data/portal_menu_data.xml delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/data/welcome_articles.xml delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/models/__init__.py delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/models/accessibility_assessment.py delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/models/adp_document.py delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/models/assessment.py delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/models/authorizer_comment.py delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/models/pdf_template.py delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/models/res_partner.py delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/models/res_users.py delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/models/sale_order.py delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/security/ir.model.access.csv delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/security/portal_security.xml delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/static/description/icon.png delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/static/src/css/portal_style.css delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/static/src/css/technician_portal.css delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/assessment_form.js delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/chatter_message_authorizer.js delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/loaner_portal.js delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/pdf_field_editor.js delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/portal_search.js delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/signature_pad.js delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/technician_location.js delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/technician_push.js delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/technician_sw.js delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/static/src/xml/chatter_message_authorizer.xml delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/utils/__init__.py delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/utils/pdf_filler.py delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/views/assessment_views.xml delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/views/pdf_template_views.xml delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/views/portal_accessibility_forms.xml delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/views/portal_accessibility_templates.xml delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/views/portal_assessment_express.xml delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/views/portal_book_assessment.xml delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/views/portal_pdf_editor.xml delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/views/portal_technician_templates.xml delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/views/portal_templates.xml delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/views/res_partner_views.xml delete mode 100644 fusion_authorizer_portal/fusion_authorizer_portal/views/sale_order_views.xml delete mode 100644 fusion_claims/fusion_claims/LICENSE delete mode 100644 fusion_claims/fusion_claims/README.md delete mode 100644 fusion_claims/fusion_claims/__init__.py delete mode 100644 fusion_claims/fusion_claims/__manifest__.py delete mode 100644 fusion_claims/fusion_claims/data/ai_agent_data.xml delete mode 100644 fusion_claims/fusion_claims/data/device_codes/adp_mobility_manual.json delete mode 100644 fusion_claims/fusion_claims/data/ir_actions_server_data.xml delete mode 100644 fusion_claims/fusion_claims/data/ir_config_parameter_data.xml delete mode 100644 fusion_claims/fusion_claims/data/ir_cron_data.xml delete mode 100644 fusion_claims/fusion_claims/data/mail_activity_type_data.xml delete mode 100644 fusion_claims/fusion_claims/data/mail_template_data.xml delete mode 100644 fusion_claims/fusion_claims/data/pdf_template_data.xml delete mode 100644 fusion_claims/fusion_claims/data/product_labor_data.xml delete mode 100644 fusion_claims/fusion_claims/data/stock_location_data.xml delete mode 100644 fusion_claims/fusion_claims/models/__init__.py delete mode 100644 fusion_claims/fusion_claims/models/account_move.py delete mode 100644 fusion_claims/fusion_claims/models/account_move_line.py delete mode 100644 fusion_claims/fusion_claims/models/account_payment.py delete mode 100644 fusion_claims/fusion_claims/models/account_payment_method_line.py delete mode 100644 fusion_claims/fusion_claims/models/adp_application_data.py delete mode 100644 fusion_claims/fusion_claims/models/adp_posting_schedule.py delete mode 100644 fusion_claims/fusion_claims/models/ai_agent_ext.py delete mode 100644 fusion_claims/fusion_claims/models/client_chat.py delete mode 100644 fusion_claims/fusion_claims/models/client_profile.py delete mode 100644 fusion_claims/fusion_claims/models/dashboard.py delete mode 100644 fusion_claims/fusion_claims/models/email_builder_mixin.py delete mode 100644 fusion_claims/fusion_claims/models/fusion_adp_device_code.py delete mode 100644 fusion_claims/fusion_claims/models/fusion_central_config.py delete mode 100644 fusion_claims/fusion_claims/models/fusion_loaner_checkout.py delete mode 100644 fusion_claims/fusion_claims/models/fusion_loaner_history.py delete mode 100644 fusion_claims/fusion_claims/models/product_product.py delete mode 100644 fusion_claims/fusion_claims/models/product_template.py delete mode 100644 fusion_claims/fusion_claims/models/push_subscription.py delete mode 100644 fusion_claims/fusion_claims/models/res_company.py delete mode 100644 fusion_claims/fusion_claims/models/res_config_settings.py delete mode 100644 fusion_claims/fusion_claims/models/res_partner.py delete mode 100644 fusion_claims/fusion_claims/models/res_users.py delete mode 100644 fusion_claims/fusion_claims/models/sale_order.py delete mode 100644 fusion_claims/fusion_claims/models/sale_order_line.py delete mode 100644 fusion_claims/fusion_claims/models/submission_history.py delete mode 100644 fusion_claims/fusion_claims/models/technician_location.py delete mode 100644 fusion_claims/fusion_claims/models/technician_task.py delete mode 100644 fusion_claims/fusion_claims/models/xml_parser.py delete mode 100644 fusion_claims/fusion_claims/report/invoice_report_landscape.xml delete mode 100644 fusion_claims/fusion_claims/report/invoice_report_portrait.xml delete mode 100644 fusion_claims/fusion_claims/report/report_accessibility_contract.xml delete mode 100644 fusion_claims/fusion_claims/report/report_actions.xml delete mode 100644 fusion_claims/fusion_claims/report/report_grab_bar_waiver.xml delete mode 100644 fusion_claims/fusion_claims/report/report_invoice_adp.xml delete mode 100644 fusion_claims/fusion_claims/report/report_mod_invoice.xml delete mode 100644 fusion_claims/fusion_claims/report/report_mod_quotation.xml delete mode 100644 fusion_claims/fusion_claims/report/report_proof_of_delivery.xml delete mode 100644 fusion_claims/fusion_claims/report/report_proof_of_delivery_standard.xml delete mode 100644 fusion_claims/fusion_claims/report/report_proof_of_pickup.xml delete mode 100644 fusion_claims/fusion_claims/report/report_rental_agreement.xml delete mode 100644 fusion_claims/fusion_claims/report/report_saleorder_adp.xml delete mode 100644 fusion_claims/fusion_claims/report/report_templates.xml delete mode 100644 fusion_claims/fusion_claims/report/sale_report_landscape.xml delete mode 100644 fusion_claims/fusion_claims/report/sale_report_portrait.xml delete mode 100644 fusion_claims/fusion_claims/scripts/import_adp_mobility_manual.py delete mode 100644 fusion_claims/fusion_claims/security/ir.model.access.csv delete mode 100644 fusion_claims/fusion_claims/security/security.xml delete mode 100644 fusion_claims/fusion_claims/static/description/icon.png delete mode 100644 fusion_claims/fusion_claims/static/img/nexa_favicon.png delete mode 100644 fusion_claims/fusion_claims/static/img/nexa_logo.png delete mode 100644 fusion_claims/fusion_claims/static/src/css/fusion_task_map_view.scss delete mode 100644 fusion_claims/fusion_claims/static/src/js/attachment_image_compress.js delete mode 100644 fusion_claims/fusion_claims/static/src/js/calendar_store_hours.js delete mode 100644 fusion_claims/fusion_claims/static/src/js/chatter_resize.js delete mode 100644 fusion_claims/fusion_claims/static/src/js/document_preview.js delete mode 100644 fusion_claims/fusion_claims/static/src/js/fusion_task_map_view.js delete mode 100644 fusion_claims/fusion_claims/static/src/js/gallery_preview.js delete mode 100644 fusion_claims/fusion_claims/static/src/js/google_address_autocomplete.js delete mode 100644 fusion_claims/fusion_claims/static/src/js/preview_button_widget.js delete mode 100644 fusion_claims/fusion_claims/static/src/js/status_selection_filter.js delete mode 100644 fusion_claims/fusion_claims/static/src/js/tax_totals_patch.js delete mode 100644 fusion_claims/fusion_claims/static/src/pdf/discretionary_benefits_form_template.pdf delete mode 100644 fusion_claims/fusion_claims/static/src/pdf/sa_mobility_form_template.pdf delete mode 100644 fusion_claims/fusion_claims/static/src/pdf/sa_mobility_page2_sample.pdf delete mode 100644 fusion_claims/fusion_claims/static/src/scss/fusion_claims.scss delete mode 100644 fusion_claims/fusion_claims/static/src/xml/document_preview.xml delete mode 100644 fusion_claims/fusion_claims/static/src/xml/fusion_task_map_view.xml delete mode 100644 fusion_claims/fusion_claims/views/account_journal_views.xml delete mode 100644 fusion_claims/fusion_claims/views/account_move_views.xml delete mode 100644 fusion_claims/fusion_claims/views/adp_claims_views.xml delete mode 100644 fusion_claims/fusion_claims/views/client_chat_views.xml delete mode 100644 fusion_claims/fusion_claims/views/client_profile_views.xml delete mode 100644 fusion_claims/fusion_claims/views/dashboard_views.xml delete mode 100644 fusion_claims/fusion_claims/views/fusion_loaner_views.xml delete mode 100644 fusion_claims/fusion_claims/views/pdf_template_inherit_views.xml delete mode 100644 fusion_claims/fusion_claims/views/res_company_views.xml delete mode 100644 fusion_claims/fusion_claims/views/res_config_settings_views.xml delete mode 100644 fusion_claims/fusion_claims/views/res_partner_views.xml delete mode 100644 fusion_claims/fusion_claims/views/sale_order_views.xml delete mode 100644 fusion_claims/fusion_claims/views/submission_history_views.xml delete mode 100644 fusion_claims/fusion_claims/views/technician_location_views.xml delete mode 100644 fusion_claims/fusion_claims/views/technician_task_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/__init__.py delete mode 100644 fusion_claims/fusion_claims/wizard/account_payment_register.py delete mode 100644 fusion_claims/fusion_claims/wizard/account_payment_register_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/adp_export_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/adp_export_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/application_received_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/application_received_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/assessment_completed_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/assessment_completed_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/case_close_verification_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/case_close_verification_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/device_approval_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/device_approval_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/device_import_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/device_import_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/field_mapping_config_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/field_mapping_config_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/loaner_checkout_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/loaner_return_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/mod_awaiting_funding_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/mod_awaiting_funding_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/mod_funding_approved_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/mod_funding_approved_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/mod_pca_received_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/mod_pca_received_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/odsp_discretionary_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/odsp_discretionary_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/odsp_pre_approved_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/odsp_pre_approved_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/odsp_ready_delivery_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/odsp_ready_delivery_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/odsp_sa_mobility_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/odsp_sa_mobility_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/odsp_submit_to_odsp_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/odsp_submit_to_odsp_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/ready_for_delivery_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/ready_for_delivery_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/ready_for_submission_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/ready_for_submission_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/ready_to_bill_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/ready_to_bill_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/sale_advance_payment_inv.py delete mode 100644 fusion_claims/fusion_claims/wizard/sale_advance_payment_inv_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/schedule_assessment_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/schedule_assessment_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/send_to_mod_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/send_to_mod_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/status_change_reason_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/status_change_reason_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/submission_verification_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/submission_verification_wizard_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/temp_serial_migration_views.xml delete mode 100644 fusion_claims/fusion_claims/wizard/xml_import_wizard.py delete mode 100644 fusion_claims/fusion_claims/wizard/xml_import_wizard_views.xml delete mode 100644 fusion_claims/models/pdf_template_inherit.py rename fusion_claims/{fusion_claims => }/models/task_sync.py (100%) rename fusion_claims/{fusion_claims => }/static/nuke_cache.html (100%) rename fusion_claims/{fusion_claims => }/views/task_sync_views.xml (100%) delete mode 100644 fusion_clock/fusion_clock/__init__.py delete mode 100644 fusion_clock/fusion_clock/__manifest__.py delete mode 100644 fusion_clock/fusion_clock/controllers/__init__.py delete mode 100644 fusion_clock/fusion_clock/controllers/clock_api.py delete mode 100644 fusion_clock/fusion_clock/controllers/portal_clock.py delete mode 100644 fusion_clock/fusion_clock/data/ir_config_parameter_data.xml delete mode 100644 fusion_clock/fusion_clock/data/ir_cron_data.xml delete mode 100644 fusion_clock/fusion_clock/data/mail_template_data.xml delete mode 100644 fusion_clock/fusion_clock/models/__init__.py delete mode 100644 fusion_clock/fusion_clock/models/clock_location.py delete mode 100644 fusion_clock/fusion_clock/models/clock_penalty.py delete mode 100644 fusion_clock/fusion_clock/models/clock_report.py delete mode 100644 fusion_clock/fusion_clock/models/hr_attendance.py delete mode 100644 fusion_clock/fusion_clock/models/hr_employee.py delete mode 100644 fusion_clock/fusion_clock/models/res_config_settings.py delete mode 100644 fusion_clock/fusion_clock/report/clock_employee_report.xml delete mode 100644 fusion_clock/fusion_clock/report/clock_report_template.xml delete mode 100644 fusion_clock/fusion_clock/security/ir.model.access.csv delete mode 100644 fusion_clock/fusion_clock/security/security.xml delete mode 100644 fusion_clock/fusion_clock/static/description/icon.png delete mode 100644 fusion_clock/fusion_clock/static/src/css/portal_clock.css delete mode 100644 fusion_clock/fusion_clock/static/src/js/fclk_location_map.js delete mode 100644 fusion_clock/fusion_clock/static/src/js/fusion_clock_portal.js delete mode 100644 fusion_clock/fusion_clock/static/src/js/fusion_clock_portal_fab.js delete mode 100644 fusion_clock/fusion_clock/static/src/js/fusion_clock_systray.js delete mode 100644 fusion_clock/fusion_clock/static/src/scss/fusion_clock.scss delete mode 100644 fusion_clock/fusion_clock/static/src/xml/location_map.xml delete mode 100644 fusion_clock/fusion_clock/static/src/xml/systray_clock.xml delete mode 100644 fusion_clock/fusion_clock/views/clock_location_views.xml delete mode 100644 fusion_clock/fusion_clock/views/clock_menus.xml delete mode 100644 fusion_clock/fusion_clock/views/clock_penalty_views.xml delete mode 100644 fusion_clock/fusion_clock/views/clock_report_views.xml delete mode 100644 fusion_clock/fusion_clock/views/hr_attendance_views.xml delete mode 100644 fusion_clock/fusion_clock/views/portal_clock_templates.xml delete mode 100644 fusion_clock/fusion_clock/views/portal_report_templates.xml delete mode 100644 fusion_clock/fusion_clock/views/portal_timesheet_templates.xml delete mode 100644 fusion_clock/fusion_clock/views/res_config_settings_views.xml delete mode 100644 fusion_clock/static/src/js/fclk_location_map.js delete mode 100644 fusion_clock/static/src/xml/location_map.xml delete mode 100644 fusion_faxes/fusion_faxes/__init__.py delete mode 100644 fusion_faxes/fusion_faxes/__manifest__.py delete mode 100644 fusion_faxes/fusion_faxes/data/ir_config_parameter_data.xml delete mode 100644 fusion_faxes/fusion_faxes/data/ir_cron_data.xml delete mode 100644 fusion_faxes/fusion_faxes/data/ir_sequence_data.xml delete mode 100644 fusion_faxes/fusion_faxes/models/__init__.py delete mode 100644 fusion_faxes/fusion_faxes/models/account_move.py delete mode 100644 fusion_faxes/fusion_faxes/models/dashboard.py delete mode 100644 fusion_faxes/fusion_faxes/models/fusion_fax.py delete mode 100644 fusion_faxes/fusion_faxes/models/fusion_fax_document.py delete mode 100644 fusion_faxes/fusion_faxes/models/res_config_settings.py delete mode 100644 fusion_faxes/fusion_faxes/models/res_partner.py delete mode 100644 fusion_faxes/fusion_faxes/models/sale_order.py delete mode 100644 fusion_faxes/fusion_faxes/security/ir.model.access.csv delete mode 100644 fusion_faxes/fusion_faxes/security/security.xml delete mode 100644 fusion_faxes/fusion_faxes/static/description/icon.png delete mode 100644 fusion_faxes/fusion_faxes/views/account_move_views.xml delete mode 100644 fusion_faxes/fusion_faxes/views/dashboard_views.xml delete mode 100644 fusion_faxes/fusion_faxes/views/fusion_fax_views.xml delete mode 100644 fusion_faxes/fusion_faxes/views/res_config_settings_views.xml delete mode 100644 fusion_faxes/fusion_faxes/views/res_partner_views.xml delete mode 100644 fusion_faxes/fusion_faxes/views/sale_order_views.xml delete mode 100644 fusion_faxes/fusion_faxes/wizard/__init__.py delete mode 100644 fusion_faxes/fusion_faxes/wizard/send_fax_wizard.py delete mode 100644 fusion_faxes/fusion_faxes/wizard/send_fax_wizard_line.py delete mode 100644 fusion_faxes/fusion_faxes/wizard/send_fax_wizard_views.xml rename fusion_faxes/{fusion_faxes => }/static/src/css/partner_mobile.css (100%) delete mode 100644 fusion_inventory_sync/fusion_inventory_sync/__init__.py delete mode 100644 fusion_inventory_sync/fusion_inventory_sync/__manifest__.py delete mode 100644 fusion_inventory_sync/fusion_inventory_sync/data/ir_cron_data.xml delete mode 100644 fusion_inventory_sync/fusion_inventory_sync/models/__init__.py delete mode 100644 fusion_inventory_sync/fusion_inventory_sync/models/product_sync_mapping.py delete mode 100644 fusion_inventory_sync/fusion_inventory_sync/models/product_template.py delete mode 100644 fusion_inventory_sync/fusion_inventory_sync/models/stock_move.py delete mode 100644 fusion_inventory_sync/fusion_inventory_sync/models/sync_config.py delete mode 100644 fusion_inventory_sync/fusion_inventory_sync/models/sync_log.py delete mode 100644 fusion_inventory_sync/fusion_inventory_sync/security/ir.model.access.csv delete mode 100644 fusion_inventory_sync/fusion_inventory_sync/static/description/icon.png delete mode 100644 fusion_inventory_sync/fusion_inventory_sync/views/product_views.xml delete mode 100644 fusion_inventory_sync/fusion_inventory_sync/views/sync_config_views.xml delete mode 100644 fusion_notes/fusion_notes/__init__.py delete mode 100644 fusion_notes/fusion_notes/__manifest__.py delete mode 100644 fusion_notes/fusion_notes/controllers/__init__.py delete mode 100644 fusion_notes/fusion_notes/controllers/main.py delete mode 100644 fusion_notes/fusion_notes/data/ir_config_parameter_data.xml delete mode 100644 fusion_notes/fusion_notes/models/__init__.py delete mode 100644 fusion_notes/fusion_notes/models/res_config_settings.py delete mode 100644 fusion_notes/fusion_notes/static/description/icon.png delete mode 100644 fusion_notes/fusion_notes/static/src/js/voice_note_button.js delete mode 100644 fusion_notes/fusion_notes/static/src/js/voice_note_service.js delete mode 100644 fusion_notes/fusion_notes/static/src/scss/fusion_notes.scss delete mode 100644 fusion_notes/fusion_notes/static/src/xml/voice_note_button.xml delete mode 100644 fusion_notes/fusion_notes/views/res_config_settings_views.xml delete mode 100644 fusion_payroll/fusion_payroll/T4-Employer-Empty.pdf delete mode 100644 fusion_payroll/fusion_payroll/T4-Empty.pdf delete mode 100644 fusion_payroll/fusion_payroll/__init__.py delete mode 100644 fusion_payroll/fusion_payroll/__manifest__.py delete mode 100644 fusion_payroll/fusion_payroll/controllers/__init__.py delete mode 100644 fusion_payroll/fusion_payroll/controllers/payroll_report.py delete mode 100644 fusion_payroll/fusion_payroll/data/hr_payroll_structure.xml delete mode 100644 fusion_payroll/fusion_payroll/data/hr_payslip_input_type_data.xml delete mode 100644 fusion_payroll/fusion_payroll/data/hr_rule_parameter_data.xml delete mode 100644 fusion_payroll/fusion_payroll/data/hr_salary_rules.xml delete mode 100644 fusion_payroll/fusion_payroll/data/tax_yearly_rates_data.xml delete mode 100644 fusion_payroll/fusion_payroll/demo/demo_data.xml delete mode 100644 fusion_payroll/fusion_payroll/development/Reports/PayrollAggregatedReport (1).xls delete mode 100644 fusion_payroll/fusion_payroll/development/Reports/Screenshot 2026-01-01 035249.png delete mode 100644 fusion_payroll/fusion_payroll/development/Reports/Screenshot 2026-01-01 035258.png delete mode 100644 fusion_payroll/fusion_payroll/development/Reports/Screenshot 2026-01-01 035303.png delete mode 100644 fusion_payroll/fusion_payroll/development/Reports/Screenshot 2026-01-01 035333.png delete mode 100644 fusion_payroll/fusion_payroll/development/Reports/Screenshot 2026-01-01 035354.png delete mode 100644 fusion_payroll/fusion_payroll/development/Reports/Screenshot 2026-01-01 035521.png delete mode 100644 fusion_payroll/fusion_payroll/development/Reports/Screenshot 2026-01-01 035540.png delete mode 100644 fusion_payroll/fusion_payroll/development/Reports/Screenshot 2026-01-01 035602.png delete mode 100644 fusion_payroll/fusion_payroll/development/Reports/Screenshot 2026-01-01 035622.png delete mode 100644 fusion_payroll/fusion_payroll/development/Reports/Screenshot 2026-01-01 035645.png delete mode 100644 fusion_payroll/fusion_payroll/development/Reports/Screenshot 2026-01-01 035715.png delete mode 100644 fusion_payroll/fusion_payroll/development/Reports/Screenshot 2026-01-01 035739.png delete mode 100644 fusion_payroll/fusion_payroll/development/Reports/Screenshot 2026-01-01 035808.png delete mode 100644 fusion_payroll/fusion_payroll/development/Reports/Screenshot 2026-01-01 035821.png delete mode 100644 fusion_payroll/fusion_payroll/development/Reports/Screenshot 2026-01-01 035834.png delete mode 100644 fusion_payroll/fusion_payroll/development/Reports/Screenshot 2026-01-01 035855.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2025-12-31 234850.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2025-12-31 234901.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2025-12-31 234913.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2025-12-31 234935.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2025-12-31 235044.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2025-12-31 235055.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2025-12-31 235107.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2025-12-31 235117.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2025-12-31 235132.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2025-12-31 235144.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2025-12-31 235207.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2025-12-31 235216.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2025-12-31 235227.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2025-12-31 235514.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2025-12-31 235525.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2025-12-31 235631.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 000003.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 000024.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 000347.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 000355.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 000408.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 000416.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 000425.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 000432.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 000440.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 000446.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 001008.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 001105.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 001113.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 001138.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 001152.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 001212.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 001233.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 001526.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 001623.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 001746.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 001757.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 001842.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 002136.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 002149.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 002156.png delete mode 100644 fusion_payroll/fusion_payroll/development/Screenshot 2026-01-01 023231.png delete mode 100644 fusion_payroll/fusion_payroll/docs/ENHANCEMENT_PLAN.md delete mode 100644 fusion_payroll/fusion_payroll/docs/EXTRACTION_LOG.md delete mode 100644 fusion_payroll/fusion_payroll/docs/PDF_FIELD_POSITIONING.md delete mode 100644 fusion_payroll/fusion_payroll/docs/README.md delete mode 100644 fusion_payroll/fusion_payroll/docs/models/README.md delete mode 100644 fusion_payroll/fusion_payroll/models/__init__.py delete mode 100644 fusion_payroll/fusion_payroll/models/cheque_layout_settings.py delete mode 100644 fusion_payroll/fusion_payroll/models/hr_contract.py delete mode 100644 fusion_payroll/fusion_payroll/models/hr_employee.py delete mode 100644 fusion_payroll/fusion_payroll/models/hr_payroll_t4.py delete mode 100644 fusion_payroll/fusion_payroll/models/hr_payroll_t4a.py delete mode 100644 fusion_payroll/fusion_payroll/models/hr_payslip.py delete mode 100644 fusion_payroll/fusion_payroll/models/hr_roe.py delete mode 100644 fusion_payroll/fusion_payroll/models/hr_salary_rule_category.py delete mode 100644 fusion_payroll/fusion_payroll/models/hr_tax_remittance.py delete mode 100644 fusion_payroll/fusion_payroll/models/pay_period.py delete mode 100644 fusion_payroll/fusion_payroll/models/payroll_accounting_mapping.py delete mode 100644 fusion_payroll/fusion_payroll/models/payroll_cheque.py delete mode 100644 fusion_payroll/fusion_payroll/models/payroll_config_settings.py delete mode 100644 fusion_payroll/fusion_payroll/models/payroll_dashboard.py delete mode 100644 fusion_payroll/fusion_payroll/models/payroll_entry.py delete mode 100644 fusion_payroll/fusion_payroll/models/payroll_report.py delete mode 100644 fusion_payroll/fusion_payroll/models/payroll_report_cost.py delete mode 100644 fusion_payroll/fusion_payroll/models/payroll_report_employee.py delete mode 100644 fusion_payroll/fusion_payroll/models/payroll_report_paycheque.py delete mode 100644 fusion_payroll/fusion_payroll/models/payroll_report_summary.py delete mode 100644 fusion_payroll/fusion_payroll/models/payroll_report_tax.py delete mode 100644 fusion_payroll/fusion_payroll/models/payroll_tax_payment_schedule.py delete mode 100644 fusion_payroll/fusion_payroll/models/payroll_work_location.py delete mode 100644 fusion_payroll/fusion_payroll/models/pdf_field_position.py delete mode 100644 fusion_payroll/fusion_payroll/models/tax_yearly_rate_line.py delete mode 100644 fusion_payroll/fusion_payroll/models/tax_yearly_rates.py delete mode 100644 fusion_payroll/fusion_payroll/not for submission.png delete mode 100644 fusion_payroll/fusion_payroll/reports/payroll_cheque_report.xml delete mode 100644 fusion_payroll/fusion_payroll/reports/payroll_report_pdf.xml delete mode 100644 fusion_payroll/fusion_payroll/reports/payroll_reports.xml delete mode 100644 fusion_payroll/fusion_payroll/reports/report_paystub_canada.xml delete mode 100644 fusion_payroll/fusion_payroll/security/ir.model.access.csv delete mode 100644 fusion_payroll/fusion_payroll/static/description/icon.png delete mode 100644 fusion_payroll/fusion_payroll/static/description/icon.svg delete mode 100644 fusion_payroll/fusion_payroll/static/description/not_for_submission.png delete mode 100644 fusion_payroll/fusion_payroll/static/src/css/roe_report.css delete mode 100644 fusion_payroll/fusion_payroll/static/src/js/payroll_report_action.js delete mode 100644 fusion_payroll/fusion_payroll/static/src/js/report_hub.js delete mode 100644 fusion_payroll/fusion_payroll/static/src/scss/payroll_report.scss delete mode 100644 fusion_payroll/fusion_payroll/static/src/xml/payroll_report_templates.xml delete mode 100644 fusion_payroll/fusion_payroll/static/src/xml/report_hub.xml delete mode 100644 fusion_payroll/fusion_payroll/t4-fill-25e.pdf delete mode 100644 fusion_payroll/fusion_payroll/t4a-fill-25e.pdf delete mode 100644 fusion_payroll/fusion_payroll/t4sum-fill-25e.pdf delete mode 100644 fusion_payroll/fusion_payroll/views/cheque_layout_settings_views.xml delete mode 100644 fusion_payroll/fusion_payroll/views/cheque_number_wizard_views.xml delete mode 100644 fusion_payroll/fusion_payroll/views/fusion_payroll_menus.xml delete mode 100644 fusion_payroll/fusion_payroll/views/hr_employee_views.xml delete mode 100644 fusion_payroll/fusion_payroll/views/hr_payslip_views.xml delete mode 100644 fusion_payroll/fusion_payroll/views/hr_roe_views.xml delete mode 100644 fusion_payroll/fusion_payroll/views/hr_t4_views.xml delete mode 100644 fusion_payroll/fusion_payroll/views/hr_t4a_views.xml delete mode 100644 fusion_payroll/fusion_payroll/views/hr_tax_centre_views.xml delete mode 100644 fusion_payroll/fusion_payroll/views/pay_period_views.xml delete mode 100644 fusion_payroll/fusion_payroll/views/payroll_cheque_print_wizard_views.xml delete mode 100644 fusion_payroll/fusion_payroll/views/payroll_cheque_views.xml delete mode 100644 fusion_payroll/fusion_payroll/views/payroll_config_settings_views.xml delete mode 100644 fusion_payroll/fusion_payroll/views/payroll_dashboard_views.xml delete mode 100644 fusion_payroll/fusion_payroll/views/payroll_report_views.xml delete mode 100644 fusion_payroll/fusion_payroll/views/payroll_tax_payment_schedule_views.xml delete mode 100644 fusion_payroll/fusion_payroll/views/payroll_work_location_views.xml delete mode 100644 fusion_payroll/fusion_payroll/views/pdf_field_position_views.xml delete mode 100644 fusion_payroll/fusion_payroll/views/run_payroll_wizard_views.xml delete mode 100644 fusion_payroll/fusion_payroll/views/tax_yearly_rates_views.xml delete mode 100644 fusion_payroll/fusion_payroll/wizards/__init__.py delete mode 100644 fusion_payroll/fusion_payroll/wizards/cheque_number_wizard.py delete mode 100644 fusion_payroll/fusion_payroll/wizards/hr_employee_sin_wizard.py delete mode 100644 fusion_payroll/fusion_payroll/wizards/hr_employee_terminate_wizard.py delete mode 100644 fusion_payroll/fusion_payroll/wizards/payroll_cheque_print_wizard.py delete mode 100644 fusion_payroll/fusion_payroll/wizards/run_payroll_wizard.py delete mode 100644 fusion_ringcentral/fusion_ringcentral/__init__.py delete mode 100644 fusion_ringcentral/fusion_ringcentral/__manifest__.py delete mode 100644 fusion_ringcentral/fusion_ringcentral/controllers/__init__.py delete mode 100644 fusion_ringcentral/fusion_ringcentral/controllers/oauth.py delete mode 100644 fusion_ringcentral/fusion_ringcentral/controllers/recording.py delete mode 100644 fusion_ringcentral/fusion_ringcentral/controllers/webhook.py delete mode 100644 fusion_ringcentral/fusion_ringcentral/controllers/widget.py delete mode 100644 fusion_ringcentral/fusion_ringcentral/data/ir_cron_data.xml delete mode 100644 fusion_ringcentral/fusion_ringcentral/data/ir_sequence_data.xml delete mode 100644 fusion_ringcentral/fusion_ringcentral/models/__init__.py delete mode 100644 fusion_ringcentral/fusion_ringcentral/models/fusion_fax.py delete mode 100644 fusion_ringcentral/fusion_ringcentral/models/rc_call_dashboard.py delete mode 100644 fusion_ringcentral/fusion_ringcentral/models/rc_call_history.py delete mode 100644 fusion_ringcentral/fusion_ringcentral/models/rc_config.py delete mode 100644 fusion_ringcentral/fusion_ringcentral/models/rc_voicemail.py delete mode 100644 fusion_ringcentral/fusion_ringcentral/models/res_config_settings.py delete mode 100644 fusion_ringcentral/fusion_ringcentral/models/res_partner.py delete mode 100644 fusion_ringcentral/fusion_ringcentral/security/ir.model.access.csv delete mode 100644 fusion_ringcentral/fusion_ringcentral/security/security.xml delete mode 100644 fusion_ringcentral/fusion_ringcentral/static/description/icon.png delete mode 100644 fusion_ringcentral/fusion_ringcentral/static/src/js/rc_click_to_dial.js delete mode 100644 fusion_ringcentral/fusion_ringcentral/static/src/js/rc_phone_widget.js delete mode 100644 fusion_ringcentral/fusion_ringcentral/static/src/js/rc_systray.js delete mode 100644 fusion_ringcentral/fusion_ringcentral/static/src/xml/rc_systray.xml delete mode 100644 fusion_ringcentral/fusion_ringcentral/views/fusion_fax_views.xml delete mode 100644 fusion_ringcentral/fusion_ringcentral/views/rc_call_dashboard_views.xml delete mode 100644 fusion_ringcentral/fusion_ringcentral/views/rc_call_history_views.xml delete mode 100644 fusion_ringcentral/fusion_ringcentral/views/rc_config_views.xml delete mode 100644 fusion_ringcentral/fusion_ringcentral/views/rc_fax_menus.xml delete mode 100644 fusion_ringcentral/fusion_ringcentral/views/rc_voicemail_views.xml delete mode 100644 fusion_ringcentral/fusion_ringcentral/views/res_config_settings_views.xml delete mode 100644 fusion_ringcentral/fusion_ringcentral/views/res_partner_views.xml diff --git a/fusion_accounts/fusion_accounts/__init__.py b/fusion_accounts/fusion_accounts/__init__.py deleted file mode 100644 index 140643d..0000000 --- a/fusion_accounts/fusion_accounts/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) - -from . import models diff --git a/fusion_accounts/fusion_accounts/__manifest__.py b/fusion_accounts/fusion_accounts/__manifest__.py deleted file mode 100644 index 25a26b1..0000000 --- a/fusion_accounts/fusion_accounts/__manifest__.py +++ /dev/null @@ -1,45 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) -{ - 'name': 'Fusion Accounts', - 'version': '19.0.1.0.0', - 'category': 'Accounting', - 'summary': 'Smart vendor bill creation from email with AI extraction and vendor matching', - 'description': """ -Fusion Accounts - Smart Vendor Bill Management -=============================================== - -Automatically creates vendor bills from incoming emails with: -- Multi-level vendor matching (email, domain, name) -- Vendor blocking for PO-tracked vendors -- AI-powered data extraction from email body and PDF attachments -- Full activity logging and dashboard - """, - 'author': 'Nexa Systems Inc.', - 'website': 'https://nexasystems.ca', - 'license': 'OPL-1', - 'depends': [ - 'base', - 'account', - 'mail', - 'purchase', - ], - 'external_dependencies': { - 'python': ['fitz'], - }, - 'data': [ - 'security/security.xml', - 'security/ir.model.access.csv', - 'data/ir_config_parameter_data.xml', - 'views/fusion_accounts_log_views.xml', - 'views/fusion_accounts_dashboard.xml', - 'views/res_partner_views.xml', - 'views/res_config_settings_views.xml', - 'views/account_move_views.xml', - 'views/fusion_accounts_menus.xml', - ], - 'installable': True, - 'application': True, - 'auto_install': False, -} diff --git a/fusion_accounts/fusion_accounts/data/ir_config_parameter_data.xml b/fusion_accounts/fusion_accounts/data/ir_config_parameter_data.xml deleted file mode 100644 index e94285d..0000000 --- a/fusion_accounts/fusion_accounts/data/ir_config_parameter_data.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - fusion_accounts.ai_enabled - True - - - fusion_accounts.ai_model - gpt-4o-mini - - - fusion_accounts.ai_max_pages - 2 - - - fusion_accounts.enable_domain_match - True - - - fusion_accounts.enable_name_match - True - - - fusion_accounts.log_retention_days - 90 - - - - diff --git a/fusion_accounts/fusion_accounts/models/__init__.py b/fusion_accounts/fusion_accounts/models/__init__.py deleted file mode 100644 index 3012477..0000000 --- a/fusion_accounts/fusion_accounts/models/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) - -from . import res_partner -from . import fusion_accounts_log -from . import ai_bill_extractor -from . import account_move -from . import res_config_settings diff --git a/fusion_accounts/fusion_accounts/models/account_move.py b/fusion_accounts/fusion_accounts/models/account_move.py deleted file mode 100644 index 71b9799..0000000 --- a/fusion_accounts/fusion_accounts/models/account_move.py +++ /dev/null @@ -1,265 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) - -import logging -from email.utils import parseaddr - -from odoo import models, fields, api - -_logger = logging.getLogger(__name__) - - -class AccountMove(models.Model): - _inherit = 'account.move' - - x_fa_created_from_email = fields.Boolean( - string='Created from Email', - default=False, - readonly=True, - copy=False, - help='This bill was automatically created from an incoming email.', - ) - x_fa_match_level = fields.Selection( - selection=[ - ('exact_email', 'Exact Email'), - ('domain', 'Domain Match'), - ('name', 'Name Match'), - ('no_match', 'No Match'), - ], - string='Vendor Match Level', - readonly=True, - copy=False, - help='How the vendor was matched from the sender email.', - ) - x_fa_ai_extracted = fields.Boolean( - string='AI Extracted', - default=False, - readonly=True, - copy=False, - help='Bill data was extracted using AI.', - ) - x_fa_original_sender = fields.Char( - string='Original Email Sender', - readonly=True, - copy=False, - help='The original sender email address that triggered bill creation.', - ) - - # ========================================================================= - # VENDOR MATCHING - # ========================================================================= - @api.model - def _fa_match_vendor_from_email(self, email_from): - """Multi-level vendor matching from sender email. - - Tries three levels: - 1. Exact email match - 2. Domain match (email domain or website) - 3. Name match (sender display name) - - Returns: (partner_record, match_level) or (False, 'no_match') - """ - if not email_from: - return False, 'no_match' - - # Parse "Display Name " format - display_name, email_address = parseaddr(email_from) - if not email_address: - return False, 'no_match' - - email_address = email_address.strip().lower() - Partner = self.env['res.partner'].sudo() - - # Check settings for which match levels are enabled - ICP = self.env['ir.config_parameter'].sudo() - enable_domain = ICP.get_param('fusion_accounts.enable_domain_match', 'True') == 'True' - enable_name = ICP.get_param('fusion_accounts.enable_name_match', 'True') == 'True' - - # ----- Level 1: Exact email match ----- - partner = Partner.search([ - ('email', '=ilike', email_address), - ('supplier_rank', '>', 0), - ], limit=1) - if not partner: - # Also check without supplier_rank filter (contact might not be flagged as vendor) - partner = Partner.search([ - ('email', '=ilike', email_address), - ], limit=1) - - if partner: - _logger.info("Vendor match Level 1 (exact email): %s -> %s", - email_address, partner.name) - return partner, 'exact_email' - - # ----- Level 2: Domain match ----- - if enable_domain and '@' in email_address: - domain = email_address.split('@')[1] - # Skip common email providers - common_domains = { - 'gmail.com', 'yahoo.com', 'hotmail.com', 'outlook.com', - 'live.com', 'aol.com', 'icloud.com', 'mail.com', - 'protonmail.com', 'zoho.com', - } - if domain not in common_domains: - # Search by email domain - partners = Partner.search([ - '|', - ('email', '=ilike', f'%@{domain}'), - ('website', 'ilike', domain), - ]) - if partners: - # Prefer is_company=True (the parent company) - company_partner = partners.filtered(lambda p: p.is_company) - partner = company_partner[0] if company_partner else partners[0] - _logger.info("Vendor match Level 2 (domain): %s -> %s (from %d candidates)", - domain, partner.name, len(partners)) - return partner, 'domain' - - # ----- Level 3: Name match ----- - if enable_name and display_name: - clean_name = display_name.strip().strip('"').strip("'") - if len(clean_name) >= 3: # Only match names with 3+ characters - partners = Partner.search([ - '|', - ('name', 'ilike', clean_name), - ('commercial_company_name', 'ilike', clean_name), - ]) - if len(partners) == 1: - _logger.info("Vendor match Level 3 (name): '%s' -> %s", - clean_name, partners.name) - return partners, 'name' - elif len(partners) > 1: - _logger.info("Vendor match Level 3 skipped: '%s' matched %d partners (ambiguous)", - clean_name, len(partners)) - - _logger.info("No vendor match found for: %s (%s)", display_name, email_address) - return False, 'no_match' - - # ========================================================================= - # MESSAGE_NEW OVERRIDE - # ========================================================================= - @api.model - def message_new(self, msg_dict, custom_values=None): - """Override to add vendor matching and blocking for incoming bills. - - When an email arrives via the accounts alias: - 1. Match sender to a vendor - 2. If vendor is blocked -> log to Discuss, don't create bill - 3. If not blocked -> create draft bill, run AI extraction - """ - email_from = msg_dict.get('email_from', '') or msg_dict.get('from', '') - subject = msg_dict.get('subject', '') - - _logger.info("Fusion Accounts: Processing incoming email from '%s' subject '%s'", - email_from, subject) - - # Match vendor - partner, match_level = self._fa_match_vendor_from_email(email_from) - - # Check if vendor is blocked - if partner and partner.x_fa_block_email_bill: - _logger.info("Vendor '%s' is blocked for email bill creation. Skipping bill.", - partner.name) - - # Log the blocked action - self.env['fusion.accounts.log'].sudo().create({ - 'email_from': email_from, - 'email_subject': subject, - 'email_date': msg_dict.get('date'), - 'vendor_id': partner.id, - 'match_level': match_level, - 'action_taken': 'blocked', - 'notes': f'Vendor "{partner.name}" has email bill creation blocked.', - }) - - # Post note to vendor's chatter - try: - partner.message_post( - body=f'

Blocked bill email: {subject}

' - f'

From: {email_from}

', - message_type='comment', - subtype_xmlid='mail.mt_note', - ) - except Exception as e: - _logger.warning("Failed to post blocked email to partner chatter: %s", e) - - # Don't create a bill -- just let fetchmail mark the email as handled - # by raising a controlled exception that fetchmail catches gracefully - _logger.info("Skipping bill creation for blocked vendor %s", partner.name) - raise ValueError( - f"Fusion Accounts: Bill creation blocked for vendor '{partner.name}'. " - f"Email from {email_from} logged to activity log." - ) - - # Not blocked -- create the bill - custom_values = custom_values or {} - custom_values['move_type'] = 'in_invoice' - if partner: - custom_values['partner_id'] = partner.id - - # Create the bill via standard Odoo mechanism - try: - move = super().message_new(msg_dict, custom_values=custom_values) - # Write FA fields after creation (Odoo may strip unknown fields from custom_values) - move.sudo().write({ - 'x_fa_created_from_email': True, - 'x_fa_match_level': match_level, - 'x_fa_original_sender': email_from, - }) - except Exception as e: - _logger.error("Failed to create bill from email: %s", e) - self.env['fusion.accounts.log'].sudo().create({ - 'email_from': email_from, - 'email_subject': subject, - 'email_date': msg_dict.get('date'), - 'vendor_id': partner.id if partner else False, - 'match_level': match_level, - 'action_taken': 'failed', - 'notes': str(e), - }) - raise - - # Run AI extraction using attachments from msg_dict - # (ir.attachment records don't exist yet at this point - they're created by message_post later) - ai_extracted = False - ai_result = '' - try: - ICP = self.env['ir.config_parameter'].sudo() - ai_enabled = ICP.get_param('fusion_accounts.ai_enabled', 'True') == 'True' - - if ai_enabled: - extractor = self.env['fusion.accounts.ai.extractor'] - email_body = msg_dict.get('body', '') - - raw_attachments = msg_dict.get('attachments', []) - extracted_data = extractor.extract_bill_data_from_raw( - email_body, raw_attachments - ) - if extracted_data: - extractor.apply_extracted_data(move, extracted_data) - ai_extracted = True - ai_result = str(extracted_data) - move.sudo().write({'x_fa_ai_extracted': True}) - - except Exception as e: - _logger.warning("AI extraction failed for bill %s: %s", move.id, e) - ai_result = f'Error: {e}' - - # Log the successful creation - self.env['fusion.accounts.log'].sudo().create({ - 'email_from': email_from, - 'email_subject': subject, - 'email_date': msg_dict.get('date'), - 'vendor_id': partner.id if partner else False, - 'match_level': match_level, - 'action_taken': 'bill_created', - 'bill_id': move.id, - 'ai_extracted': ai_extracted, - 'ai_result': ai_result, - }) - - _logger.info("Fusion Accounts: Created bill %s from email (vendor=%s, match=%s, ai=%s)", - move.name, partner.name if partner else 'None', match_level, ai_extracted) - - return move diff --git a/fusion_accounts/fusion_accounts/models/ai_bill_extractor.py b/fusion_accounts/fusion_accounts/models/ai_bill_extractor.py deleted file mode 100644 index ee547c0..0000000 --- a/fusion_accounts/fusion_accounts/models/ai_bill_extractor.py +++ /dev/null @@ -1,614 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) - -import base64 -import json -import logging -import re - -from odoo import models - -_logger = logging.getLogger(__name__) - -EXTRACTION_PROMPT = """You are an accounts payable assistant. Extract billing information from the attached invoice/bill document and email. - -IMPORTANT RULES: -- The PDF attachment is the PRIMARY source of truth. Always prefer data from the PDF over the email body. -- "vendor_name" = the company that ISSUED the invoice/bill (the seller/supplier name on the document), NOT the email sender. -- "invoice_number" = the Invoice Number, Bill Number, Reference Number, or Sales Order Number printed on the document. -- "invoice_date" = the date the invoice was issued (not the email date). -- "due_date" = the payment due date on the invoice. -- For line items, extract each product/service line with description, quantity, unit price, and line total. - -Return ONLY valid JSON with this exact structure (use null for missing values): -{ - "vendor_name": "string - the company name that issued the bill", - "invoice_number": "string - invoice/bill/reference number", - "invoice_date": "YYYY-MM-DD", - "due_date": "YYYY-MM-DD", - "currency": "CAD or USD", - "subtotal": 0.00, - "tax_amount": 0.00, - "total_amount": 0.00, - "po_reference": "string or null - any PO reference on the document", - "lines": [ - { - "description": "string", - "quantity": 1.0, - "unit_price": 0.00, - "amount": 0.00 - } - ] -} - -If you cannot determine a value, use null. For lines, include as many as you can find. -Do NOT include any text outside the JSON object.""" - - -class AIBillExtractor(models.AbstractModel): - _name = 'fusion.accounts.ai.extractor' - _description = 'AI Bill Data Extractor' - - def _get_api_key(self): - """Get the OpenAI API key from settings.""" - return self.env['ir.config_parameter'].sudo().get_param( - 'fusion_accounts.openai_api_key', '' - ) - - def _get_ai_model(self): - """Get the configured AI model.""" - return self.env['ir.config_parameter'].sudo().get_param( - 'fusion_accounts.ai_model', 'gpt-4o-mini' - ) - - def _get_max_pages(self): - """Get the max PDF pages to process.""" - try: - return int(self.env['ir.config_parameter'].sudo().get_param( - 'fusion_accounts.ai_max_pages', '2' - )) - except (ValueError, TypeError): - return 2 - - def _is_ai_enabled(self): - """Check if AI extraction is enabled.""" - return self.env['ir.config_parameter'].sudo().get_param( - 'fusion_accounts.ai_enabled', 'True' - ) == 'True' - - def extract_bill_data_from_raw(self, email_body, raw_attachments=None): - """Extract bill data using raw attachments from msg_dict. - - Raw attachments come as a list that can contain: - - tuples: (filename, content_bytes, info_dict) - - ir.attachment records (if already created) - - Args: - email_body: HTML email body - raw_attachments: list from msg_dict['attachments'] - - Returns: - dict with extracted data, or empty dict on failure - """ - if not self._is_ai_enabled(): - _logger.info("AI extraction is disabled") - return {} - - api_key = self._get_api_key() - if not api_key: - _logger.warning("No OpenAI API key configured") - return {} - - try: - import requests as req_lib - except ImportError: - _logger.error("requests library not available") - return {} - - clean_body = self._strip_html(email_body or '') - content_parts = [] - has_pdf_content = False - - # Process raw attachments from msg_dict - if raw_attachments: - for att in raw_attachments[:3]: - fname = '' - content = None - - if hasattr(att, 'datas'): - # ir.attachment record - fname = att.name or '' - content = base64.b64decode(att.datas) if att.datas else None - mimetype = att.mimetype or '' - elif hasattr(att, 'fname') and hasattr(att, 'content'): - # Odoo Attachment namedtuple (fname, content, info) - fname = att.fname or '' - content = att.content if isinstance(att.content, bytes) else None - mimetype = getattr(att, 'info', {}).get('content_type', '') if hasattr(att, 'info') and att.info else '' - elif isinstance(att, (tuple, list)) and len(att) >= 2: - # (filename, content_bytes, ...) tuple - fname = att[0] or '' - content = att[1] if isinstance(att[1], bytes) else None - mimetype = '' - else: - continue - - # Determine mimetype from filename if not set - if not mimetype: - if fname.lower().endswith('.pdf'): - mimetype = 'application/pdf' - elif fname.lower().endswith(('.png', '.jpg', '.jpeg')): - mimetype = 'image/' + fname.rsplit('.', 1)[-1].lower() - - if not content: - continue - - _logger.info("Processing attachment: %s (%d bytes)", fname, len(content)) - - if fname.lower().endswith('.pdf') or mimetype == 'application/pdf': - # Convert PDF to images - pdf_images = self._pdf_bytes_to_images(content) - if pdf_images: - has_pdf_content = True - for img_data in pdf_images: - content_parts.append({ - "type": "image_url", - "image_url": { - "url": f"data:image/png;base64,{img_data}", - "detail": "high", - } - }) - else: - # Fallback: text extraction - pdf_text = self._pdf_bytes_to_text(content) - if pdf_text: - has_pdf_content = True - content_parts.append({ - "type": "text", - "text": f"INVOICE/BILL DOCUMENT:\n{pdf_text[:8000]}" - }) - elif mimetype.startswith('image/'): - has_pdf_content = True - img_b64 = base64.b64encode(content).decode() - content_parts.append({ - "type": "image_url", - "image_url": { - "url": f"data:{mimetype};base64,{img_b64}", - "detail": "high", - } - }) - - # Email body as secondary context - if clean_body and not has_pdf_content: - content_parts.append({ - "type": "text", - "text": f"EMAIL BODY (no invoice attachment):\n{clean_body[:5000]}" - }) - elif clean_body and has_pdf_content: - content_parts.append({ - "type": "text", - "text": f"ADDITIONAL CONTEXT FROM EMAIL:\n{clean_body[:2000]}" - }) - - if not content_parts: - _logger.info("No content to extract from") - return {} - - # Call OpenAI API - model = self._get_ai_model() - messages = [ - {"role": "system", "content": EXTRACTION_PROMPT}, - {"role": "user", "content": content_parts}, - ] - - try: - response = req_lib.post( - 'https://api.openai.com/v1/chat/completions', - headers={ - 'Authorization': f'Bearer {api_key}', - 'Content-Type': 'application/json', - }, - json={ - 'model': model, - 'messages': messages, - 'max_tokens': 2000, - 'temperature': 0.1, - }, - timeout=60, - ) - response.raise_for_status() - result = response.json() - content = result['choices'][0]['message']['content'] - - content = content.strip() - if content.startswith('```'): - lines = content.split('\n') - content = '\n'.join(lines[1:-1] if lines[-1].strip() == '```' else lines[1:]) - content = content.strip() - - if not content: - _logger.warning("AI returned empty response") - return {} - - extracted = json.loads(content) - _logger.info("AI extraction successful: %s", json.dumps(extracted, indent=2)[:500]) - return extracted - - except Exception as e: - _logger.error("AI extraction failed: %s", e) - return {} - - def _pdf_bytes_to_images(self, pdf_bytes): - """Convert raw PDF bytes to base64 PNG images.""" - max_pages = self._get_max_pages() - images = [] - try: - import fitz - doc = fitz.open(stream=pdf_bytes, filetype="pdf") - for page_num in range(min(len(doc), max_pages)): - page = doc[page_num] - pix = page.get_pixmap(matrix=fitz.Matrix(2, 2)) - img_data = base64.b64encode(pix.tobytes("png")).decode() - images.append(img_data) - _logger.info("Converted PDF page %d to image (%d bytes)", page_num + 1, len(img_data)) - doc.close() - except ImportError: - _logger.warning("PyMuPDF not available") - except Exception as e: - _logger.warning("PDF to image failed: %s", e) - return images - - def _pdf_bytes_to_text(self, pdf_bytes): - """Extract text from raw PDF bytes.""" - max_pages = self._get_max_pages() - try: - import fitz - doc = fitz.open(stream=pdf_bytes, filetype="pdf") - parts = [] - for page_num in range(min(len(doc), max_pages)): - parts.append(doc[page_num].get_text()) - doc.close() - return '\n'.join(parts) - except Exception: - return '' - - def extract_bill_data(self, email_body, attachments=None): - """Extract bill data from email body and attachments using OpenAI. - - Args: - email_body: Plain text or HTML email body - attachments: List of ir.attachment records - - Returns: - dict with extracted data, or empty dict on failure - """ - if not self._is_ai_enabled(): - _logger.info("AI extraction is disabled") - return {} - - api_key = self._get_api_key() - if not api_key: - _logger.warning("No OpenAI API key configured for Fusion Accounts") - return {} - - try: - import requests - except ImportError: - _logger.error("requests library not available") - return {} - - # Clean HTML from email body - clean_body = self._strip_html(email_body or '') - - # Build messages for OpenAI - messages = [ - {"role": "system", "content": EXTRACTION_PROMPT}, - ] - - # Build content -- PDF attachments FIRST (primary source), email body second - content_parts = [] - has_pdf_content = False - - # Add PDF/image attachments first (these are the invoice documents) - if attachments: - for attachment in attachments[:3]: # Max 3 attachments - if attachment.mimetype == 'application/pdf': - # Try image conversion first (best for AI vision) - pdf_images = self._pdf_to_images(attachment) - if pdf_images: - has_pdf_content = True - for img_data in pdf_images: - content_parts.append({ - "type": "image_url", - "image_url": { - "url": f"data:image/png;base64,{img_data}", - "detail": "high", - } - }) - else: - # Fallback: extract text from PDF - pdf_text = self._pdf_to_text(attachment) - if pdf_text: - has_pdf_content = True - content_parts.append({ - "type": "text", - "text": f"INVOICE/BILL DOCUMENT:\n{pdf_text[:8000]}" - }) - elif attachment.mimetype in ('image/png', 'image/jpeg', 'image/jpg'): - has_pdf_content = True - img_b64 = base64.b64encode(base64.b64decode(attachment.datas)).decode() - content_parts.append({ - "type": "image_url", - "image_url": { - "url": f"data:{attachment.mimetype};base64,{img_b64}", - "detail": "high", - } - }) - - # Add email body as secondary context (only if no PDF content found) - if clean_body and not has_pdf_content: - content_parts.append({ - "type": "text", - "text": f"EMAIL BODY (no invoice attachment found):\n{clean_body[:5000]}" - }) - elif clean_body and has_pdf_content: - content_parts.append({ - "type": "text", - "text": f"ADDITIONAL CONTEXT FROM EMAIL:\n{clean_body[:2000]}" - }) - - if not content_parts: - _logger.info("No content to extract from") - return {} - - messages.append({"role": "user", "content": content_parts}) - - # Call OpenAI API - model = self._get_ai_model() - try: - response = requests.post( - 'https://api.openai.com/v1/chat/completions', - headers={ - 'Authorization': f'Bearer {api_key}', - 'Content-Type': 'application/json', - }, - json={ - 'model': model, - 'messages': messages, - 'max_tokens': 2000, - 'temperature': 0.1, - }, - timeout=60, - ) - response.raise_for_status() - result = response.json() - content = result['choices'][0]['message']['content'] - - # Parse JSON from response -- handle markdown code fences - content = content.strip() - if content.startswith('```'): - # Remove ```json ... ``` wrapper - lines = content.split('\n') - content = '\n'.join(lines[1:-1] if lines[-1].strip() == '```' else lines[1:]) - content = content.strip() - - if not content: - _logger.warning("AI returned empty response") - return {} - - extracted = json.loads(content) - _logger.info("AI extraction successful: %s", json.dumps(extracted, indent=2)[:500]) - return extracted - - except requests.exceptions.RequestException as e: - _logger.error("OpenAI API request failed: %s", e) - return {} - except (json.JSONDecodeError, KeyError, IndexError) as e: - _logger.warning("Failed to parse AI response: %s (content: %s)", e, content[:200] if content else 'empty') - return {} - - def apply_extracted_data(self, move, extracted_data): - """Apply AI-extracted data to a draft vendor bill. - - The PDF/invoice is the source of truth for: - - Vendor name (matched to Odoo contact) - - Invoice/bill number (ref) - - Invoice date, due date - - Line items - - Args: - move: account.move record (draft vendor bill) - extracted_data: dict from extract_bill_data() - """ - if not extracted_data: - return - - vals = {} - - # --- Vendor matching from AI-extracted vendor name --- - # This overrides the email sender match because the PDF - # shows the actual billing company (e.g., "Canada Computers Inc.") - ai_vendor_name = extracted_data.get('vendor_name') - if ai_vendor_name: - partner = self._match_vendor_by_name(ai_vendor_name) - if partner: - vals['partner_id'] = partner.id - _logger.info("AI vendor match: '%s' -> %s (id=%d)", - ai_vendor_name, partner.name, partner.id) - - # Invoice reference (vendor's invoice/bill/SO number) - if extracted_data.get('invoice_number'): - vals['ref'] = extracted_data['invoice_number'] - - # Invoice date - if extracted_data.get('invoice_date'): - try: - from datetime import datetime - vals['invoice_date'] = datetime.strptime( - extracted_data['invoice_date'], '%Y-%m-%d' - ).date() - except (ValueError, TypeError): - pass - - # Due date - if extracted_data.get('due_date'): - try: - from datetime import datetime - vals['invoice_date_due'] = datetime.strptime( - extracted_data['due_date'], '%Y-%m-%d' - ).date() - except (ValueError, TypeError): - pass - - if vals: - try: - move.write(vals) - _logger.info("Applied AI data to bill %s: %s", move.id, vals) - except Exception as e: - _logger.error("Failed to apply AI data to bill %s: %s", move.id, e) - - # Add invoice lines if extracted - lines = extracted_data.get('lines', []) - if lines and not move.invoice_line_ids: - line_vals_list = [] - for line in lines[:20]: # Max 20 lines - line_vals = { - 'move_id': move.id, - 'name': line.get('description', 'Extracted line'), - 'quantity': line.get('quantity', 1.0), - 'price_unit': line.get('unit_price', 0.0), - } - line_vals_list.append(line_vals) - - if line_vals_list: - try: - move.write({ - 'invoice_line_ids': [(0, 0, lv) for lv in line_vals_list] - }) - _logger.info("Added %d AI-extracted lines to bill %s", - len(line_vals_list), move.id) - except Exception as e: - _logger.error("Failed to add lines to bill %s: %s", move.id, e) - - def _match_vendor_by_name(self, vendor_name): - """Match AI-extracted vendor name to an Odoo partner. - - Tries multiple strategies: - 1. Exact name match - 2. Commercial company name match - 3. Partial/contains match (only if single result) - - Returns: res.partner record or False - """ - if not vendor_name or len(vendor_name) < 3: - return False - - Partner = self.env['res.partner'].sudo() - vendor_name = vendor_name.strip() - - # Level 1: Exact name match - partner = Partner.search([ - ('name', '=ilike', vendor_name), - ('supplier_rank', '>', 0), - ], limit=1) - if partner: - return partner - - # Level 2: Exact name match without supplier_rank filter - partner = Partner.search([ - ('name', '=ilike', vendor_name), - ], limit=1) - if partner: - return partner - - # Level 3: Commercial company name match - partner = Partner.search([ - ('commercial_company_name', '=ilike', vendor_name), - ], limit=1) - if partner: - return partner - - # Level 4: Contains match (only accept single result to avoid false positives) - partners = Partner.search([ - '|', - ('name', 'ilike', vendor_name), - ('commercial_company_name', 'ilike', vendor_name), - ]) - if len(partners) == 1: - return partners - - # Level 5: Try without common suffixes (Inc, Ltd, Corp, etc.) - clean_name = vendor_name - for suffix in [' Inc', ' Inc.', ' Ltd', ' Ltd.', ' Corp', ' Corp.', - ' Co', ' Co.', ' LLC', ' Company', ' Limited']: - if clean_name.lower().endswith(suffix.lower()): - clean_name = clean_name[:len(clean_name) - len(suffix)].strip() - break - - if clean_name != vendor_name and len(clean_name) >= 3: - partners = Partner.search([ - '|', - ('name', 'ilike', clean_name), - ('commercial_company_name', 'ilike', clean_name), - ]) - if len(partners) == 1: - return partners - - _logger.info("No vendor match for AI-extracted name: '%s'", vendor_name) - return False - - def _strip_html(self, html): - """Strip HTML tags from text.""" - clean = re.sub(r']*>.*?', '', html, flags=re.DOTALL) - clean = re.sub(r']*>.*?', '', clean, flags=re.DOTALL) - clean = re.sub(r'<[^>]+>', ' ', clean) - clean = re.sub(r'\s+', ' ', clean).strip() - return clean - - def _pdf_to_images(self, attachment): - """Convert PDF attachment pages to base64 PNG images using PyMuPDF.""" - max_pages = self._get_max_pages() - images = [] - - try: - import fitz # PyMuPDF - pdf_data = base64.b64decode(attachment.datas) - doc = fitz.open(stream=pdf_data, filetype="pdf") - for page_num in range(min(len(doc), max_pages)): - page = doc[page_num] - pix = page.get_pixmap(matrix=fitz.Matrix(2, 2)) # 2x zoom for readability - img_data = base64.b64encode(pix.tobytes("png")).decode() - images.append(img_data) - _logger.info("Converted PDF page %d to image (%d bytes)", page_num + 1, len(img_data)) - doc.close() - except ImportError: - _logger.warning("PyMuPDF not available, will try text extraction fallback") - except Exception as e: - _logger.warning("PDF to image conversion failed: %s", e) - - return images - - def _pdf_to_text(self, attachment): - """Extract text content from PDF as fallback when image conversion fails.""" - max_pages = self._get_max_pages() - - try: - import fitz # PyMuPDF - pdf_data = base64.b64decode(attachment.datas) - doc = fitz.open(stream=pdf_data, filetype="pdf") - text_parts = [] - for page_num in range(min(len(doc), max_pages)): - page = doc[page_num] - text_parts.append(page.get_text()) - doc.close() - full_text = '\n'.join(text_parts) - if full_text.strip(): - _logger.info("Extracted %d chars of text from PDF", len(full_text)) - return full_text - except ImportError: - pass - except Exception as e: - _logger.warning("PDF text extraction failed: %s", e) - - return '' diff --git a/fusion_accounts/fusion_accounts/models/fusion_accounts_log.py b/fusion_accounts/fusion_accounts/models/fusion_accounts_log.py deleted file mode 100644 index 8b5aa33..0000000 --- a/fusion_accounts/fusion_accounts/models/fusion_accounts_log.py +++ /dev/null @@ -1,140 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) - -from odoo import models, fields, api, _ - - -class FusionAccountsLog(models.Model): - _name = 'fusion.accounts.log' - _description = 'Fusion Accounts - Email Processing Log' - _order = 'create_date desc' - _rec_name = 'email_subject' - - email_from = fields.Char( - string='From', - readonly=True, - help='Sender email address', - ) - vendor_blocked = fields.Boolean( - related='vendor_id.x_fa_block_email_bill', - string='Vendor Blocked', - readonly=True, - ) - email_subject = fields.Char( - string='Subject', - readonly=True, - ) - email_date = fields.Datetime( - string='Email Date', - readonly=True, - ) - vendor_id = fields.Many2one( - 'res.partner', - string='Matched Vendor', - readonly=True, - help='Vendor matched from sender email', - ) - match_level = fields.Selection( - selection=[ - ('exact_email', 'Exact Email'), - ('domain', 'Domain Match'), - ('name', 'Name Match'), - ('no_match', 'No Match'), - ], - string='Match Level', - readonly=True, - help='How the vendor was identified', - ) - action_taken = fields.Selection( - selection=[ - ('bill_created', 'Bill Created'), - ('blocked', 'Blocked (Vendor)'), - ('failed', 'Failed'), - ('no_vendor', 'No Vendor Match'), - ], - string='Action', - readonly=True, - ) - bill_id = fields.Many2one( - 'account.move', - string='Created Bill', - readonly=True, - help='The vendor bill created from this email', - ) - ai_extracted = fields.Boolean( - string='AI Extracted', - readonly=True, - default=False, - help='Whether AI data extraction was performed', - ) - ai_result = fields.Text( - string='AI Extraction Result', - readonly=True, - help='JSON output from AI extraction', - ) - notes = fields.Text( - string='Notes', - readonly=True, - help='Error messages or additional details', - ) - - def action_block_vendor(self): - """Block the vendor from this log entry from email bill creation.""" - for log in self: - if log.vendor_id and not log.vendor_id.x_fa_block_email_bill: - log.vendor_id.write({'x_fa_block_email_bill': True}) - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': _('Vendor Blocked'), - 'message': _('Vendor blocked from email bill creation.'), - 'type': 'success', - 'sticky': False, - } - } - - def action_enable_vendor(self): - """Enable the vendor from this log entry for email bill creation.""" - for log in self: - if log.vendor_id and log.vendor_id.x_fa_block_email_bill: - log.vendor_id.write({'x_fa_block_email_bill': False}) - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': _('Vendor Enabled'), - 'message': _('Vendor enabled for email bill creation.'), - 'type': 'success', - 'sticky': False, - } - } - - # Stat fields for dashboard - @api.model - def get_dashboard_data(self): - """Return statistics for the dashboard.""" - today = fields.Date.today() - return { - 'bills_pending': self.env['account.move'].search_count([ - ('move_type', '=', 'in_invoice'), - ('state', '=', 'draft'), - ('x_fa_created_from_email', '=', True), - ]), - 'bills_today': self.search_count([ - ('action_taken', '=', 'bill_created'), - ('create_date', '>=', fields.Datetime.to_string(today)), - ]), - 'blocked_today': self.search_count([ - ('action_taken', '=', 'blocked'), - ('create_date', '>=', fields.Datetime.to_string(today)), - ]), - 'failed_today': self.search_count([ - ('action_taken', '=', 'failed'), - ('create_date', '>=', fields.Datetime.to_string(today)), - ]), - 'total_blocked_vendors': self.env['res.partner'].search_count([ - ('x_fa_block_email_bill', '=', True), - ]), - } diff --git a/fusion_accounts/fusion_accounts/models/res_config_settings.py b/fusion_accounts/fusion_accounts/models/res_config_settings.py deleted file mode 100644 index 73b8ded..0000000 --- a/fusion_accounts/fusion_accounts/models/res_config_settings.py +++ /dev/null @@ -1,84 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) - -import logging - -from odoo import models, fields - -_logger = logging.getLogger(__name__) - - -class ResConfigSettings(models.TransientModel): - _inherit = 'res.config.settings' - - # ========================================================================= - # AI SETTINGS - # ========================================================================= - x_fa_ai_enabled = fields.Boolean( - string='Enable AI Extraction', - config_parameter='fusion_accounts.ai_enabled', - help='Enable AI-powered data extraction from email body and attachments.', - ) - x_fa_openai_api_key = fields.Char( - string='OpenAI API Key', - config_parameter='fusion_accounts.openai_api_key', - help='Your OpenAI API key for bill data extraction.', - ) - x_fa_ai_model = fields.Selection( - selection=[ - ('gpt-4o-mini', 'GPT-4o Mini (Fast, Low Cost)'), - ('gpt-4o', 'GPT-4o (Best Quality)'), - ], - string='AI Model', - config_parameter='fusion_accounts.ai_model', - help='OpenAI model to use for extraction.', - ) - x_fa_ai_max_pages = fields.Integer( - string='Max PDF Pages', - config_parameter='fusion_accounts.ai_max_pages', - help='Maximum number of PDF pages to send to AI for extraction.', - ) - - # ========================================================================= - # MATCHING SETTINGS - # ========================================================================= - x_fa_enable_domain_match = fields.Boolean( - string='Enable Domain Matching', - config_parameter='fusion_accounts.enable_domain_match', - help='Match vendors by email domain (Level 2 matching).', - ) - x_fa_enable_name_match = fields.Boolean( - string='Enable Name Matching', - config_parameter='fusion_accounts.enable_name_match', - help='Match vendors by sender display name (Level 3 matching).', - ) - x_fa_auto_block_po_vendors = fields.Boolean( - string='Auto-Block PO Vendors', - config_parameter='fusion_accounts.auto_block_po_vendors', - help='Automatically block email bill creation for vendors with active Purchase Orders.', - ) - - # ========================================================================= - # GENERAL SETTINGS - # ========================================================================= - x_fa_log_retention_days = fields.Integer( - string='Log Retention (Days)', - config_parameter='fusion_accounts.log_retention_days', - help='Number of days to keep activity logs. Set 0 to keep forever.', - ) - - def set_values(self): - ICP = self.env['ir.config_parameter'].sudo() - # Protect API key and customized settings from accidental blanking - _protected = { - 'fusion_accounts.openai_api_key': ICP.get_param('fusion_accounts.openai_api_key', ''), - 'fusion_accounts.ai_model': ICP.get_param('fusion_accounts.ai_model', ''), - 'fusion_accounts.ai_max_pages': ICP.get_param('fusion_accounts.ai_max_pages', ''), - } - super().set_values() - for key, old_val in _protected.items(): - new_val = ICP.get_param(key, '') - if not new_val and old_val: - ICP.set_param(key, old_val) - _logger.warning("Settings protection: restored %s", key) diff --git a/fusion_accounts/fusion_accounts/models/res_partner.py b/fusion_accounts/fusion_accounts/models/res_partner.py deleted file mode 100644 index 54c76c6..0000000 --- a/fusion_accounts/fusion_accounts/models/res_partner.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) - -from odoo import models, fields, _ - - -class ResPartner(models.Model): - _inherit = 'res.partner' - - x_fa_block_email_bill = fields.Boolean( - string='Block Email Bill Creation', - default=False, - help='When enabled, incoming emails from this vendor will NOT ' - 'automatically create vendor bills. Use this for vendors ' - 'whose bills should be created through Purchase Orders instead.', - ) - - def action_fa_block_vendors(self): - """Block selected vendors from email bill creation.""" - self.write({'x_fa_block_email_bill': True}) - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': _('Vendors Blocked'), - 'message': _('%d vendor(s) blocked from email bill creation.') % len(self), - 'type': 'success', - 'sticky': False, - 'next': {'type': 'ir.actions.act_window_close'}, - } - } - - def action_fa_enable_vendors(self): - """Enable selected vendors for email bill creation.""" - self.write({'x_fa_block_email_bill': False}) - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': _('Vendors Enabled'), - 'message': _('%d vendor(s) enabled for email bill creation.') % len(self), - 'type': 'success', - 'sticky': False, - 'next': {'type': 'ir.actions.act_window_close'}, - } - } diff --git a/fusion_accounts/fusion_accounts/security/ir.model.access.csv b/fusion_accounts/fusion_accounts/security/ir.model.access.csv deleted file mode 100644 index 4e20527..0000000 --- a/fusion_accounts/fusion_accounts/security/ir.model.access.csv +++ /dev/null @@ -1,3 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_fusion_accounts_log_user,fusion.accounts.log user,model_fusion_accounts_log,group_fusion_accounts_user,1,0,0,0 -access_fusion_accounts_log_manager,fusion.accounts.log manager,model_fusion_accounts_log,group_fusion_accounts_manager,1,1,1,1 diff --git a/fusion_accounts/fusion_accounts/security/security.xml b/fusion_accounts/fusion_accounts/security/security.xml deleted file mode 100644 index 5808529..0000000 --- a/fusion_accounts/fusion_accounts/security/security.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - Fusion Accounts - 50 - - - - - User - 10 - - - - - - - Administrator - 20 - - - - - diff --git a/fusion_accounts/fusion_accounts/static/description/icon.png b/fusion_accounts/fusion_accounts/static/description/icon.png deleted file mode 100644 index 71436f5eafe473c667aee001338aacd97112fa97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14697 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 Mr7T$`ZW8)`0NiC?K>z>% diff --git a/fusion_accounts/fusion_accounts/views/account_move_views.xml b/fusion_accounts/fusion_accounts/views/account_move_views.xml deleted file mode 100644 index 33bb3a1..0000000 --- a/fusion_accounts/fusion_accounts/views/account_move_views.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - account.move.form.fusion.accounts - account.move - - 80 - - - - -
- - Created from Email - - - - AI Extracted - -
-
- - - - - - - - - - - - - - - - -
-
- - - - - - account.move.search.fusion.accounts - account.move - - 80 - - - - - - - - -
diff --git a/fusion_accounts/fusion_accounts/views/fusion_accounts_dashboard.xml b/fusion_accounts/fusion_accounts/views/fusion_accounts_dashboard.xml deleted file mode 100644 index 9b220c4..0000000 --- a/fusion_accounts/fusion_accounts/views/fusion_accounts_dashboard.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - Dashboard - fusion.accounts.log - kanban,list,form - {'search_default_filter_date': 1, 'search_default_group_action': 1} - - -

- Fusion Accounts Dashboard -

-

- Email processing activity will appear here. - Configure your email aliases and AI settings under Configuration. -

-
-
- - - - - - fusion.accounts.log.kanban - fusion.accounts.log - - - - - - - - - - - - - -
- - - -
- - -
-
- - - AI - -
-
- - -
-
- - -
-
- -
- -
- - -
-
-
-
-
-
-
-
diff --git a/fusion_accounts/fusion_accounts/views/fusion_accounts_log_views.xml b/fusion_accounts/fusion_accounts/views/fusion_accounts_log_views.xml deleted file mode 100644 index 94409a1..0000000 --- a/fusion_accounts/fusion_accounts/views/fusion_accounts_log_views.xml +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - - fusion.accounts.log.list - fusion.accounts.log - - -
-
- - - - - - - - - -
-
-
- - - - - - fusion.accounts.log.form - fusion.accounts.log - -
-
-
- -
-

-
- - - - - - - - - - - - - - - - - - - - - -
-
-
-
- - - - - - fusion.accounts.log.search - fusion.accounts.log - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/fusion_accounts/fusion_accounts/views/fusion_accounts_menus.xml b/fusion_accounts/fusion_accounts/views/fusion_accounts_menus.xml deleted file mode 100644 index e3c39c1..0000000 --- a/fusion_accounts/fusion_accounts/views/fusion_accounts_menus.xml +++ /dev/null @@ -1,190 +0,0 @@ - - - - - - - - - Bills from Email - account.move - list,form - [('move_type', '=', 'in_invoice'), ('x_fa_created_from_email', '=', True)] - {'default_move_type': 'in_invoice'} - -

- No bills from email yet -

-

- Bills will appear here when incoming emails create vendor bills automatically. -

-
-
- - - - All Vendor Bills - account.move - list,form - [('move_type', '=', 'in_invoice')] - {'default_move_type': 'in_invoice'} - - - - - Blocked Vendors - res.partner - list,form - - [('x_fa_block_email_bill', '=', True)] - {'default_x_fa_block_email_bill': True} - -

- No blocked vendors -

-

- Vendors blocked from automatic email bill creation will appear here. - Block vendors whose bills should be created through Purchase Orders instead. -

-
-
- - - - Vendors with Active POs - res.partner - list,form - - [('purchase_line_ids', '!=', False), ('supplier_rank', '>', 0)] - -

- No vendors with purchase orders -

-

- Vendors with Purchase Orders appear here. - Consider blocking these vendors from automatic email bill creation. -

-
-
- - - - All Vendors - res.partner - list,form - - [('supplier_rank', '>', 0)] - - - - - Activity Log - fusion.accounts.log - list,form - -

- No activity logged yet -

-

- Email processing activity will be logged here automatically. -

-
-
- - - - Fusion Accounts Settings - res.config.settings - form - current - {'module': 'fusion_accounts'} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/fusion_accounts/fusion_accounts/views/res_config_settings_views.xml b/fusion_accounts/fusion_accounts/views/res_config_settings_views.xml deleted file mode 100644 index 58327de..0000000 --- a/fusion_accounts/fusion_accounts/views/res_config_settings_views.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - res.config.settings.fusion.accounts - res.config.settings - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- -
-
-
-
-
diff --git a/fusion_accounts/fusion_accounts/views/res_partner_views.xml b/fusion_accounts/fusion_accounts/views/res_partner_views.xml deleted file mode 100644 index f04a644..0000000 --- a/fusion_accounts/fusion_accounts/views/res_partner_views.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - res.partner.form.fusion.accounts - res.partner - - 50 - - - - - - - - - - - - - - - - - - - res.partner.list.fusion.accounts - res.partner - 99 - - -
-
- - - - - -
-
-
- - - - -
diff --git a/fusion_authorizer_portal/.DS_Store b/fusion_authorizer_portal/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..1a29dce94a34b91aa6fc52a8cf20dd23a9ea43c3 GIT binary patch literal 6148 zcmeHLF;4<96n<4CL>3l}#u)D>$PX|%2*$XPFgYpQ5hdX~0-|xd7zbBf{3ANKxVich z`~eP5ZYF-Otw#$7iHlLwN7}FSz1M#C-StW#B2gWNWug)h6;K#+i>NY;{ahw&PWP+; zg&d<#F?I22Q-31bbvOl_0>4cGUb{sKux^j(1gmzmeh1ydawCYNo}zp^m>wC$wOXqi zw-8a-eZ6k3Up-Z3MTg&r?j4yd9x*KCD5NIXHf@GmtESK7bn%{YN^_%l#3IXY&s*nt z^Atg!5O23Gjj40LGwwI%-&?x*(!?6W#%&86=U*w zTTA&&jAe3~6=(C>WL|mj!d*e>P+)Vae~kN0KD~{Uk2QwLWm=5QLq4nvbP5J-Ivcx7 z;_d+~46n&yzmjsWB1TV1c7!#*cxD~`ieb-YD-;#F+9}`^a0;Xf@cY3-Ve~a73gxQ< zl{^9fbLf_ac8ME6Pou9fQ3wxAs8paz75a!FR66=S9p`II6smL*`tTw2%tD_~gq$7Y zdorAauh7*_0jGeiz`Xie;{AVn`uX2Za^IW+PJw@=fXLMvwJI)2@2wLT$9t`Za)83d pafw2if=X}4vcX$1|F0koK93tfUt^*WJuvq}K+51Mr@)UY@Cnh<&ZhtX literal 0 HcmV?d00001 diff --git a/fusion_authorizer_portal/controllers/pdf_editor.py b/fusion_authorizer_portal/controllers/pdf_editor.py index b3f14ef..9b3f098 100644 --- a/fusion_authorizer_portal/controllers/pdf_editor.py +++ b/fusion_authorizer_portal/controllers/pdf_editor.py @@ -35,6 +35,7 @@ class FusionPdfEditorController(http.Controller): fields = template.field_ids.read([ 'name', 'label', 'page', 'pos_x', 'pos_y', 'width', 'height', 'field_type', 'font_size', 'font_name', 'field_key', 'default_value', 'is_active', + 'text_align', ]) return request.render('fusion_authorizer_portal.portal_pdf_field_editor', { @@ -56,6 +57,7 @@ class FusionPdfEditorController(http.Controller): return template.field_ids.read([ 'name', 'label', 'page', 'pos_x', 'pos_y', 'width', 'height', 'field_type', 'font_size', 'font_name', 'field_key', 'default_value', 'is_active', + 'text_align', ]) # ================================================================ @@ -73,6 +75,7 @@ class FusionPdfEditorController(http.Controller): allowed = { 'name', 'label', 'page', 'pos_x', 'pos_y', 'width', 'height', 'field_type', 'font_size', 'font_name', 'field_key', 'default_value', 'is_active', + 'text_align', } safe_values = {k: v for k, v in values.items() if k in allowed} if safe_values: diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/README.md b/fusion_authorizer_portal/fusion_authorizer_portal/README.md deleted file mode 100644 index 36a60a2..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/README.md +++ /dev/null @@ -1,721 +0,0 @@ -# Fusion Authorizer & Sales Portal - -**Version:** 19.0.1.0.0 -**License:** LGPL-3 -**Category:** Sales/Portal -**Author:** Fusion Claims - -## Table of Contents - -1. [Overview](#overview) -2. [Features](#features) -3. [Installation](#installation) -4. [Configuration](#configuration) -5. [Models](#models) -6. [Controllers & Routes](#controllers--routes) -7. [Security](#security) -8. [Frontend Assets](#frontend-assets) -9. [Email Templates](#email-templates) -10. [User Guide](#user-guide) -11. [API Reference](#api-reference) -12. [Troubleshooting](#troubleshooting) -13. [Changelog](#changelog) - ---- - -## Overview - -The **Fusion Authorizer & Sales Portal** module extends Odoo's portal functionality to provide external access for two key user types: - -- **Authorizers (Occupational Therapists/OTs):** Healthcare professionals who authorize ADP (Assistive Devices Program) claims -- **Sales Representatives:** Field sales staff who conduct client assessments and manage orders - -This module integrates with the `fusion_claims` module to provide a seamless workflow for ADP claims management, from initial client assessment through to order completion. - -### Target Platform -- **Odoo Enterprise v19** -- Requires: `base`, `sale`, `portal`, `website`, `mail`, `fusion_claims` - ---- - -## Features - -### Authorizer Portal -- View all assigned ADP cases with full details (excluding internal costs) -- Real-time search by client name, reference numbers, or claim number -- Upload ADP application documents with revision tracking -- Add comments/notes to cases -- Download submitted ADP applications -- Receive email notifications for new assignments and status changes - -### Sales Rep Portal -- View sales cases linked to the logged-in user -- Start and manage client assessments -- Record detailed wheelchair specifications and measurements -- Capture digital signatures for ADP pages 11 & 12 -- Track assessment progress through workflow states - -### Assessment System -- Comprehensive client information collection -- Wheelchair specifications (seat width, depth, height, cushion type, etc.) -- Accessibility and mobility needs documentation -- Touch-friendly digital signature capture -- Automatic draft Sale Order creation upon completion -- Document distribution to authorizers, sales reps, and internal records -- Automated email notifications - ---- - -## Installation - -### Prerequisites -1. Odoo Enterprise v19 installed and running -2. The `fusion_claims` module installed and configured -3. Portal module enabled -4. Website module enabled -5. Mail module configured with outgoing email server - -### Installation Steps - -1. **Copy the module** to your Odoo addons directory: - ```bash - cp -r fusion_authorizer_portal /path/to/odoo/custom-addons/ - ``` - -2. **Update the apps list** in Odoo: - - Go to Apps menu - - Click "Update Apps List" - - Search for "Fusion Authorizer" - -3. **Install the module**: - - Click Install on "Fusion Authorizer & Sales Portal" - - Wait for installation to complete - -4. **Restart Odoo** (recommended): - ```bash - docker restart odoo-app # For Docker installations - # OR - sudo systemctl restart odoo # For systemd installations - ``` - ---- - -## Configuration - -### Granting Portal Access to Users - -1. Navigate to **Contacts** in Odoo backend -2. Open the contact record for the authorizer or sales rep -3. Go to the **Portal Access** tab -4. Check the appropriate role: - - `Is Authorizer` - For Occupational Therapists - - `Is Sales Rep (Portal)` - For Sales Representatives -5. Click the **Grant Portal Access** button -6. An invitation email will be sent to the contact's email address - -### Setting Up Authorizers on Sales Orders - -1. Open a Sales Order -2. In the order details, set the **Authorizer** field (`x_fc_authorizer_id`) -3. The authorizer will receive an email notification about the assignment -4. The case will appear in their portal dashboard - ---- - -## Models - -### New Models - -#### `fusion.assessment` -**Wheelchair Assessment Record** - -Captures comprehensive client assessment data including: - -| Field Group | Fields | -|-------------|--------| -| **Client Info** | `client_name`, `client_first_name`, `client_last_name`, `client_street`, `client_city`, `client_state`, `client_postal_code`, `client_country_id`, `client_phone`, `client_mobile`, `client_email`, `client_dob`, `client_health_card`, `client_reference_1`, `client_reference_2` | -| **Participants** | `sales_rep_id` (res.users), `authorizer_id` (res.partner) | -| **Assessment Details** | `assessment_date`, `assessment_location`, `assessment_location_notes` | -| **Measurements** | `seat_width`, `seat_depth`, `seat_to_floor_height`, `back_height`, `armrest_height`, `footrest_length`, `overall_width`, `overall_length`, `overall_height`, `seat_angle`, `back_angle`, `client_weight`, `client_height` | -| **Product Types** | `cushion_type`, `cushion_notes`, `backrest_type`, `backrest_notes`, `frame_type`, `frame_notes`, `wheel_type`, `wheel_notes` | -| **Needs** | `mobility_notes`, `accessibility_notes`, `special_requirements`, `diagnosis` | -| **Signatures** | `signature_page_11`, `signature_page_11_name`, `signature_page_11_date`, `signature_page_12`, `signature_page_12_name`, `signature_page_12_date` | -| **Status** | `state` (draft, pending_signature, completed, cancelled) | -| **References** | `reference` (auto-generated ASM-XXXXX), `sale_order_id`, `partner_id` | - -**Key Methods:** -- `action_complete()` - Completes assessment, creates draft Sale Order, sends notifications -- `_ensure_partner()` - Creates or links res.partner for the client -- `_create_draft_sale_order()` - Generates Sale Order with specifications -- `_generate_signed_documents()` - Creates document records for signatures -- `_send_completion_notifications()` - Sends emails to authorizer and client - ---- - -#### `fusion.adp.document` -**ADP Document Management with Revision Tracking** - -| Field | Type | Description | -|-------|------|-------------| -| `sale_order_id` | Many2one | Link to Sale Order | -| `assessment_id` | Many2one | Link to Assessment | -| `document_type` | Selection | full_application, page_11, page_12, pages_11_12, final_submission, other | -| `file` | Binary | Document file content | -| `filename` | Char | Original filename | -| `file_size` | Integer | File size in bytes | -| `mimetype` | Char | MIME type | -| `revision` | Integer | Revision number (auto-incremented) | -| `revision_note` | Text | Notes about this revision | -| `is_current` | Boolean | Whether this is the current version | -| `uploaded_by` | Many2one | User who uploaded | -| `upload_date` | Datetime | Upload timestamp | -| `source` | Selection | portal, internal, assessment | - -**Key Methods:** -- `action_download()` - Download the document -- `get_documents_for_order()` - Get all documents for a sale order -- `get_revision_history()` - Get all revisions of a document type - ---- - -#### `fusion.authorizer.comment` -**Portal Comments System** - -| Field | Type | Description | -|-------|------|-------------| -| `sale_order_id` | Many2one | Link to Sale Order | -| `assessment_id` | Many2one | Link to Assessment | -| `author_id` | Many2one | res.partner who authored | -| `author_user_id` | Many2one | res.users who authored | -| `comment` | Text | Comment content | -| `comment_type` | Selection | general, question, update, approval | -| `is_internal` | Boolean | Internal-only comment | - ---- - -### Extended Models - -#### `res.partner` (Extended) - -| New Field | Type | Description | -|-----------|------|-------------| -| `is_authorizer` | Boolean | Partner is an Authorizer/OT | -| `is_sales_rep_portal` | Boolean | Partner is a Sales Rep with portal access | -| `authorizer_portal_user_id` | Many2one | Linked portal user account | -| `assigned_case_count` | Integer | Computed count of assigned cases | -| `assessment_count` | Integer | Computed count of assessments | - -**New Methods:** -- `action_grant_portal_access()` - Creates portal user and sends invitation -- `action_view_assigned_cases()` - Opens list of assigned Sale Orders -- `action_view_assessments()` - Opens list of assessments - ---- - -#### `sale.order` (Extended) - -| New Field | Type | Description | -|-----------|------|-------------| -| `portal_comment_ids` | One2many | Comments from portal users | -| `portal_comment_count` | Integer | Computed comment count | -| `portal_document_ids` | One2many | Documents uploaded via portal | -| `portal_document_count` | Integer | Computed document count | -| `assessment_id` | Many2one | Source assessment that created this order | -| `portal_authorizer_id` | Many2one | Authorizer reference (computed from x_fc_authorizer_id) | - -**New Methods:** -- `_send_authorizer_assignment_notification()` - Email on authorizer assignment -- `_send_status_change_notification()` - Email on status change -- `get_portal_display_data()` - Safe data for portal display (excludes costs) -- `get_authorizer_portal_cases()` - Search cases for authorizer portal -- `get_sales_rep_portal_cases()` - Search cases for sales rep portal - ---- - -## Controllers & Routes - -### Authorizer Portal Routes - -| Route | Method | Auth | Description | -|-------|--------|------|-------------| -| `/my/authorizer` | GET | user | Authorizer dashboard | -| `/my/authorizer/cases` | GET | user | List of assigned cases | -| `/my/authorizer/cases/search` | POST | user | AJAX search (jsonrpc) | -| `/my/authorizer/case/` | GET | user | Case detail view | -| `/my/authorizer/case//comment` | POST | user | Add comment to case | -| `/my/authorizer/case//upload` | POST | user | Upload document | -| `/my/authorizer/document//download` | GET | user | Download document | - -### Sales Rep Portal Routes - -| Route | Method | Auth | Description | -|-------|--------|------|-------------| -| `/my/sales` | GET | user | Sales rep dashboard | -| `/my/sales/cases` | GET | user | List of sales cases | -| `/my/sales/cases/search` | POST | user | AJAX search (jsonrpc) | -| `/my/sales/case/` | GET | user | Case detail view | - -### Assessment Routes - -| Route | Method | Auth | Description | -|-------|--------|------|-------------| -| `/my/assessments` | GET | user | List of assessments | -| `/my/assessment/new` | GET | user | New assessment form | -| `/my/assessment/` | GET | user | View/edit assessment | -| `/my/assessment/save` | POST | user | Save assessment data | -| `/my/assessment//signatures` | GET | user | Signature capture page | -| `/my/assessment//save_signature` | POST | user | Save signature (jsonrpc) | -| `/my/assessment//complete` | POST | user | Complete assessment | - ---- - -## Security - -### Security Groups - -| Group | XML ID | Description | -|-------|--------|-------------| -| Authorizer Portal | `group_authorizer_portal` | Access to authorizer portal features | -| Sales Rep Portal | `group_sales_rep_portal` | Access to sales rep portal features | - -### Record Rules - -| Model | Rule | Description | -|-------|------|-------------| -| `fusion.authorizer.comment` | Portal Read | Users can read non-internal comments on their cases | -| `fusion.authorizer.comment` | Portal Create | Users can create comments on their cases | -| `fusion.adp.document` | Portal Read | Users can read documents on their cases | -| `fusion.adp.document` | Portal Create | Users can upload documents to their cases | -| `fusion.assessment` | Portal Access | Users can access assessments they're linked to | -| `sale.order` | Portal Authorizer | Authorizers can view their assigned orders | - -### Access Rights (ir.model.access.csv) - -| Model | Group | Read | Write | Create | Unlink | -|-------|-------|------|-------|--------|--------| -| `fusion.authorizer.comment` | base.group_user | 1 | 1 | 1 | 1 | -| `fusion.authorizer.comment` | base.group_portal | 1 | 0 | 1 | 0 | -| `fusion.adp.document` | base.group_user | 1 | 1 | 1 | 1 | -| `fusion.adp.document` | base.group_portal | 1 | 0 | 1 | 0 | -| `fusion.assessment` | base.group_user | 1 | 1 | 1 | 1 | -| `fusion.assessment` | base.group_portal | 1 | 1 | 1 | 0 | - ---- - -## Frontend Assets - -### CSS (`static/src/css/portal_style.css`) - -Custom portal styling with a dark blue and green color scheme: - -- **Primary Color:** Dark blue (#1e3a5f) -- **Secondary Color:** Medium blue (#2c5282) -- **Accent Color:** Green (#38a169) -- **Background:** Light gray (#f7fafc) - -Styled components: -- Portal cards with shadow effects -- Status badges with color coding -- Custom buttons with hover effects -- Responsive tables -- Form inputs with focus states - -### JavaScript - -#### `portal_search.js` -Real-time search functionality: -- Debounced input handling (300ms delay) -- AJAX calls to search endpoints -- Dynamic table updates -- Search result highlighting - -#### `assessment_form.js` -Assessment form enhancements: -- Unsaved changes warning -- Auto-fill client name from first/last name -- Number input validation -- Form state tracking - -#### `signature_pad.js` -Digital signature capture: -- HTML5 Canvas-based drawing -- Touch and mouse event support -- Clear signature functionality -- Export to base64 PNG -- AJAX save to server - ---- - -## Email Templates - -### Case Assignment (`mail_template_case_assigned`) -**Trigger:** Authorizer assigned to a Sale Order -**Recipient:** Authorizer email -**Content:** Case details, client information, link to portal - -### Status Change (`mail_template_status_changed`) -**Trigger:** Sale Order state changes -**Recipient:** Assigned authorizer -**Content:** Previous and new status, case details - -### Assessment Complete - Authorizer (`mail_template_assessment_complete_authorizer`) -**Trigger:** Assessment completed -**Recipient:** Assigned authorizer -**Content:** Assessment details, measurements, signed documents - -### Assessment Complete - Client (`mail_template_assessment_complete_client`) -**Trigger:** Assessment completed -**Recipient:** Client email -**Content:** Confirmation, next steps, measurements summary - -### Document Uploaded (`mail_template_document_uploaded`) -**Trigger:** Document uploaded via portal -**Recipient:** Internal team -**Content:** Document details, revision info, download link - ---- - -## User Guide - -### For Administrators - -#### Granting Portal Access - -1. Go to **Contacts** > Select the contact -2. Navigate to the **Portal Access** tab -3. Enable the appropriate role: - - Check `Is Authorizer` for OTs/Therapists - - Check `Is Sales Rep (Portal)` for Sales Reps -4. Click **Grant Portal Access** -5. The user receives an email with login instructions - -#### Assigning Cases to Authorizers - -1. Open a **Sale Order** -2. Set the **Authorizer** field to the appropriate contact -3. Save the order -4. The authorizer receives a notification email -5. The case appears in their portal dashboard - ---- - -### For Authorizers - -#### Accessing the Portal - -1. Visit `https://your-domain.com/my` -2. Log in with your portal credentials -3. Click **Authorizer Portal** in the menu - -#### Viewing Cases - -1. From the dashboard, view recent cases and statistics -2. Click **View All Cases** or **My Cases** for the full list -3. Use the search bar to find specific cases by: - - Client name - - Client reference 1 or 2 - - Claim number - -#### Adding Comments - -1. Open a case detail view -2. Scroll to the Comments section -3. Enter your comment -4. Select comment type (General, Question, Update, Approval) -5. Click **Add Comment** - -#### Uploading Documents - -1. Open a case detail view -2. Go to the Documents section -3. Click **Upload Document** -4. Select document type (Full Application, Page 11, Page 12, etc.) -5. Choose the file and add revision notes -6. Click **Upload** - ---- - -### For Sales Representatives - -#### Starting a New Assessment - -1. Log in to the portal -2. Click **New Assessment** -3. Fill in client information: - - Name, address, contact details - - Client references -4. Record wheelchair specifications: - - Measurements (seat width, depth, height) - - Product types (cushion, backrest, frame, wheels) -5. Document accessibility and mobility needs -6. Click **Save & Continue** - -#### Capturing Signatures - -1. After saving assessment data, click **Proceed to Signatures** -2. **Page 11 (Authorizer):** - - Have the OT sign on the canvas - - Enter their printed name - - Click **Save Signature** -3. **Page 12 (Client):** - - Have the client sign on the canvas - - Enter their printed name - - Click **Save Signature** - -#### Completing the Assessment - -1. Once both signatures are captured, click **Complete Assessment** -2. The system will: - - Create a new customer record (if needed) - - Generate a draft Sale Order - - Attach signed documents - - Send notification emails -3. The assessment moves to "Completed" status - ---- - -## API Reference - -### Assessment Model Methods - -```python -# Complete an assessment and create Sale Order -assessment.action_complete() - -# Get formatted specifications for order notes -specs = assessment._format_specifications_for_order() - -# Ensure partner exists or create new -partner = assessment._ensure_partner() -``` - -### Sale Order Portal Methods - -```python -# Get safe data for portal display (no costs) -data = order.get_portal_display_data() - -# Search cases for authorizer -cases = SaleOrder.get_authorizer_portal_cases( - partner_id=123, - search_query='Smith', - limit=50, - offset=0 -) - -# Search cases for sales rep -cases = SaleOrder.get_sales_rep_portal_cases( - user_id=456, - search_query='wheelchair', - limit=50, - offset=0 -) -``` - -### Partner Methods - -```python -# Grant portal access programmatically -partner.action_grant_portal_access() - -# Check if partner is an authorizer -if partner.is_authorizer: - cases = partner.assigned_case_count -``` - -### Document Methods - -```python -# Get all documents for an order -docs = ADPDocument.get_documents_for_order(sale_order_id) - -# Get revision history -history = document.get_revision_history() -``` - ---- - -## Troubleshooting - -### Common Errors - -#### Error: `Invalid field 'in_portal' in 'portal.wizard.user'` - -**Cause:** Odoo 19 changed the portal wizard API, removing the `in_portal` field. - -**Solution:** The `action_grant_portal_access` method has been updated to: -1. First attempt using the standard portal wizard -2. If that fails, fall back to direct user creation with portal group assignment - -```python -# The fallback code creates the user directly: -portal_group = self.env.ref('base.group_portal') -portal_user = self.env['res.users'].sudo().create({ - 'name': self.name, - 'login': self.email, - 'email': self.email, - 'partner_id': self.id, - 'groups_id': [(6, 0, [portal_group.id])], -}) -``` - ---- - -#### Error: `Invalid view type: 'tree'` - -**Cause:** Odoo 19 renamed `` views to ``. - -**Solution:** Replace all `` tags with `` in XML view definitions: -```xml - -... - - -... -``` - ---- - -#### Error: `Invalid field 'category_id' in 'res.groups'` - -**Cause:** Odoo 19 no longer supports `category_id` in `res.groups` XML definitions. - -**Solution:** Remove the `` element from security group definitions: -```xml - - -``` - ---- - -#### Error: `DeprecationWarning: @route(type='json') is deprecated` - -**Cause:** Odoo 19 uses `type='jsonrpc'` instead of `type='json'`. - -**Solution:** Update route decorators: -```python -# Old -@http.route('/my/endpoint', type='json', auth='user') - -# New -@http.route('/my/endpoint', type='jsonrpc', auth='user') -``` - ---- - -### Portal Access Issues - -#### User can't see cases in portal - -1. Verify the partner has `is_authorizer` or `is_sales_rep_portal` checked -2. Verify the `authorizer_portal_user_id` is set -3. For authorizers, verify the Sale Order has `x_fc_authorizer_id` set to their partner ID -4. For sales reps, verify the Sale Order has `user_id` set to their user ID - -#### Email notifications not sending - -1. Check that the outgoing mail server is configured in Odoo -2. Verify the email templates exist and are active -3. Check the mail queue (Settings > Technical > Email > Emails) -4. Review the Odoo logs for mail errors - ---- - -### Debug Logging - -Enable debug logging for this module: - -```python -import logging -_logger = logging.getLogger('fusion_authorizer_portal') -_logger.setLevel(logging.DEBUG) -``` - -Or in Odoo configuration: -```ini -[options] -log_handler = fusion_authorizer_portal:DEBUG -``` - ---- - -## Changelog - -### Version 19.0.1.0.0 (Initial Release) - -**New Features:** -- Authorizer Portal with case management -- Sales Rep Portal with assessment forms -- Wheelchair Assessment model with 50+ fields -- Digital signature capture (Pages 11 & 12) -- Document management with revision tracking -- Real-time search functionality -- Email notifications for key events -- Portal access management from partner form - -**Technical:** -- Compatible with Odoo Enterprise v19 -- Integrates with fusion_claims module -- Mobile-responsive portal design -- Touch-friendly signature pad -- AJAX-powered search - -**Bug Fixes:** -- Fixed `in_portal` field error in Odoo 19 portal wizard -- Fixed `tree` to `list` view type for Odoo 19 -- Fixed `category_id` error in security groups -- Fixed `type='json'` deprecation warning - ---- - -## File Structure - -``` -fusion_authorizer_portal/ -├── __init__.py -├── __manifest__.py -├── README.md -├── controllers/ -│ ├── __init__.py -│ ├── portal_main.py # Authorizer & Sales Rep portal routes -│ └── portal_assessment.py # Assessment routes -├── data/ -│ ├── mail_template_data.xml # Email templates & sequences -│ └── portal_menu_data.xml # Portal menu items -├── models/ -│ ├── __init__.py -│ ├── adp_document.py # Document management model -│ ├── assessment.py # Assessment model -│ ├── authorizer_comment.py # Comments model -│ ├── res_partner.py # Partner extensions -│ └── sale_order.py # Sale Order extensions -├── security/ -│ ├── ir.model.access.csv # Access rights -│ └── portal_security.xml # Groups & record rules -├── static/ -│ └── src/ -│ ├── css/ -│ │ └── portal_style.css # Portal styling -│ └── js/ -│ ├── assessment_form.js # Form enhancements -│ ├── portal_search.js # Real-time search -│ └── signature_pad.js # Signature capture -└── views/ - ├── assessment_views.xml # Assessment backend views - ├── portal_templates.xml # Portal QWeb templates - ├── res_partner_views.xml # Partner form extensions - └── sale_order_views.xml # Sale Order extensions -``` - ---- - -## Support - -For support or feature requests, contact: - -- **Email:** support@fusionclaims.com -- **Website:** https://fusionclaims.com - ---- - -*Last Updated: January 2026* diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/__init__.py b/fusion_authorizer_portal/fusion_authorizer_portal/__init__.py deleted file mode 100644 index c3d410e..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# -*- coding: utf-8 -*- - -from . import models -from . import controllers diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/__manifest__.py b/fusion_authorizer_portal/fusion_authorizer_portal/__manifest__.py deleted file mode 100644 index 283339b..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/__manifest__.py +++ /dev/null @@ -1,100 +0,0 @@ -# -*- coding: utf-8 -*- -{ - 'name': 'Fusion Authorizer & Sales Portal', - 'version': '19.0.2.0.9', - 'category': 'Sales/Portal', - 'summary': 'Portal for Authorizers (OTs) and Sales Reps with Assessment Forms', - 'description': """ -Fusion Authorizer & Sales Rep Portal -===================================== - -This module provides external portal access for: - -**Authorizers (Occupational Therapists)** -- View assigned ADP cases -- Upload documents (ADP applications, signed pages) -- Add comments to cases -- Complete assessments with clients -- Capture digital signatures for ADP pages 11 & 12 - -**Sales Representatives** -- View their sales cases -- Start new client assessments -- Record wheelchair specifications and measurements -- Capture client signatures -- Track assessment progress - -**Assessment System** -- Client information collection -- Wheelchair specifications (seat width, depth, height, etc.) -- Accessibility and mobility needs documentation -- Digital signature capture for ADP pages 11 & 12 -- Automatic draft Sale Order creation -- Document distribution to all parties -- Automated email notifications - -**Features** -- Real-time client search -- Document version tracking -- Mobile-friendly signature capture -- Email notifications for status changes -- Secure portal access with role-based permissions - """, - 'author': 'Fusion Claims', - 'website': 'https://fusionclaims.com', - 'license': 'LGPL-3', - 'depends': [ - 'base', - 'sale', - 'portal', - 'website', - 'mail', - 'calendar', - 'knowledge', - 'fusion_claims', - ], - 'data': [ - # Security - 'security/portal_security.xml', - 'security/ir.model.access.csv', - # Data - 'data/mail_template_data.xml', - 'data/portal_menu_data.xml', - 'data/ir_actions_server_data.xml', - 'data/welcome_articles.xml', - # Views - 'views/res_partner_views.xml', - 'views/sale_order_views.xml', - 'views/assessment_views.xml', - 'views/pdf_template_views.xml', - # Portal Templates - 'views/portal_templates.xml', - 'views/portal_assessment_express.xml', - 'views/portal_pdf_editor.xml', - 'views/portal_accessibility_templates.xml', - 'views/portal_accessibility_forms.xml', - 'views/portal_technician_templates.xml', - 'views/portal_book_assessment.xml', - ], - 'assets': { - 'web.assets_backend': [ - 'fusion_authorizer_portal/static/src/xml/chatter_message_authorizer.xml', - 'fusion_authorizer_portal/static/src/js/chatter_message_authorizer.js', - ], - 'web.assets_frontend': [ - 'fusion_authorizer_portal/static/src/css/portal_style.css', - 'fusion_authorizer_portal/static/src/css/technician_portal.css', - 'fusion_authorizer_portal/static/src/js/portal_search.js', - 'fusion_authorizer_portal/static/src/js/assessment_form.js', - 'fusion_authorizer_portal/static/src/js/signature_pad.js', - 'fusion_authorizer_portal/static/src/js/loaner_portal.js', - 'fusion_authorizer_portal/static/src/js/pdf_field_editor.js', - 'fusion_authorizer_portal/static/src/js/technician_push.js', - 'fusion_authorizer_portal/static/src/js/technician_location.js', - ], - }, - 'images': ['static/description/icon.png'], - 'installable': True, - 'application': False, - 'auto_install': False, -} diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/controllers/__init__.py b/fusion_authorizer_portal/fusion_authorizer_portal/controllers/__init__.py deleted file mode 100644 index 81b165c..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/controllers/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# -*- coding: utf-8 -*- - -from . import portal_main -from . import portal_assessment -from . import pdf_editor \ No newline at end of file diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/controllers/pdf_editor.py b/fusion_authorizer_portal/fusion_authorizer_portal/controllers/pdf_editor.py deleted file mode 100644 index 9b3f098..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/controllers/pdf_editor.py +++ /dev/null @@ -1,218 +0,0 @@ -# -*- coding: utf-8 -*- -# Fusion PDF Field Editor Controller -# Provides routes for the visual drag-and-drop field position editor - -import base64 -import json -import logging - -from odoo import http -from odoo.http import request - -_logger = logging.getLogger(__name__) - - -class FusionPdfEditorController(http.Controller): - """Controller for the PDF field position visual editor.""" - - # ================================================================ - # Editor Page - # ================================================================ - - @http.route('/fusion/pdf-editor/', type='http', auth='user', website=True) - def pdf_field_editor(self, template_id, **kw): - """Render the visual field editor for a PDF template.""" - template = request.env['fusion.pdf.template'].browse(template_id) - if not template.exists(): - return request.redirect('/web') - - # Get preview image for page 1 - preview_url = '' - preview = template.preview_ids.filtered(lambda p: p.page == 1) - if preview and preview[0].image: - preview_url = f'/web/image/fusion.pdf.template.preview/{preview[0].id}/image' - - fields = template.field_ids.read([ - 'name', 'label', 'page', 'pos_x', 'pos_y', 'width', 'height', - 'field_type', 'font_size', 'font_name', 'field_key', 'default_value', 'is_active', - 'text_align', - ]) - - return request.render('fusion_authorizer_portal.portal_pdf_field_editor', { - 'template': template, - 'fields': fields, - 'preview_url': preview_url, - }) - - # ================================================================ - # JSONRPC: Get fields for template - # ================================================================ - - @http.route('/fusion/pdf-editor/fields', type='json', auth='user') - def get_fields(self, template_id, **kw): - """Return all fields for a template.""" - template = request.env['fusion.pdf.template'].browse(template_id) - if not template.exists(): - return [] - return template.field_ids.read([ - 'name', 'label', 'page', 'pos_x', 'pos_y', 'width', 'height', - 'field_type', 'font_size', 'font_name', 'field_key', 'default_value', 'is_active', - 'text_align', - ]) - - # ================================================================ - # JSONRPC: Update field position/properties - # ================================================================ - - @http.route('/fusion/pdf-editor/update-field', type='json', auth='user') - def update_field(self, field_id, values, **kw): - """Update a field's position or properties.""" - field = request.env['fusion.pdf.template.field'].browse(field_id) - if not field.exists(): - return {'error': 'Field not found'} - - # Filter to allowed fields only - allowed = { - 'name', 'label', 'page', 'pos_x', 'pos_y', 'width', 'height', - 'field_type', 'font_size', 'font_name', 'field_key', 'default_value', 'is_active', - 'text_align', - } - safe_values = {k: v for k, v in values.items() if k in allowed} - if safe_values: - field.write(safe_values) - return {'success': True} - - # ================================================================ - # JSONRPC: Create new field - # ================================================================ - - @http.route('/fusion/pdf-editor/create-field', type='json', auth='user') - def create_field(self, **kw): - """Create a new field on a template.""" - template_id = kw.get('template_id') - if not template_id: - return {'error': 'Missing template_id'} - - vals = { - 'template_id': int(template_id), - 'name': kw.get('name', 'new_field'), - 'label': kw.get('label', 'New Field'), - 'field_type': kw.get('field_type', 'text'), - 'field_key': kw.get('field_key', kw.get('name', '')), - 'page': int(kw.get('page', 1)), - 'pos_x': float(kw.get('pos_x', 0.3)), - 'pos_y': float(kw.get('pos_y', 0.3)), - 'width': float(kw.get('width', 0.150)), - 'height': float(kw.get('height', 0.015)), - 'font_size': float(kw.get('font_size', 10)), - } - - field = request.env['fusion.pdf.template.field'].create(vals) - return {'id': field.id, 'success': True} - - # ================================================================ - # JSONRPC: Delete field - # ================================================================ - - @http.route('/fusion/pdf-editor/delete-field', type='json', auth='user') - def delete_field(self, field_id, **kw): - """Delete a field from a template.""" - field = request.env['fusion.pdf.template.field'].browse(field_id) - if field.exists(): - field.unlink() - return {'success': True} - - # ================================================================ - # JSONRPC: Get page preview image URL - # ================================================================ - - @http.route('/fusion/pdf-editor/page-image', type='json', auth='user') - def get_page_image(self, template_id, page, **kw): - """Return the preview image URL for a specific page.""" - template = request.env['fusion.pdf.template'].browse(template_id) - if not template.exists(): - return {'image_url': ''} - - preview = template.preview_ids.filtered(lambda p: p.page == page) - if preview and preview[0].image: - return {'image_url': f'/web/image/fusion.pdf.template.preview/{preview[0].id}/image'} - return {'image_url': ''} - - # ================================================================ - # Upload page preview image (from editor) - # ================================================================ - - @http.route('/fusion/pdf-editor/upload-preview', type='http', auth='user', - methods=['POST'], csrf=True, website=True) - def upload_preview_image(self, **kw): - """Upload a preview image for a template page directly from the editor.""" - template_id = int(kw.get('template_id', 0)) - page = int(kw.get('page', 1)) - template = request.env['fusion.pdf.template'].browse(template_id) - if not template.exists(): - return json.dumps({'error': 'Template not found'}) - - image_file = request.httprequest.files.get('preview_image') - if not image_file: - return json.dumps({'error': 'No image uploaded'}) - - image_data = base64.b64encode(image_file.read()) - - # Find or create preview for this page - preview = template.preview_ids.filtered(lambda p: p.page == page) - if preview: - preview[0].write({'image': image_data, 'image_filename': image_file.filename}) - else: - request.env['fusion.pdf.template.preview'].create({ - 'template_id': template_id, - 'page': page, - 'image': image_data, - 'image_filename': image_file.filename, - }) - - _logger.info("Uploaded preview image for template %s page %d", template.name, page) - return request.redirect(f'/fusion/pdf-editor/{template_id}') - - # ================================================================ - # Preview: Generate sample filled PDF - # ================================================================ - - @http.route('/fusion/pdf-editor/preview/', type='http', auth='user') - def preview_pdf(self, template_id, **kw): - """Generate a preview filled PDF with sample data.""" - template = request.env['fusion.pdf.template'].browse(template_id) - if not template.exists() or not template.pdf_file: - return request.redirect('/web') - - # Build sample data for preview - sample_context = { - 'client_last_name': 'Smith', - 'client_first_name': 'John', - 'client_middle_name': 'A', - 'client_health_card': '1234-567-890', - 'client_health_card_version': 'AB', - 'client_street': '123 Main Street', - 'client_unit': 'Unit 4B', - 'client_city': 'Toronto', - 'client_state': 'Ontario', - 'client_postal_code': 'M5V 2T6', - 'client_phone': '(416) 555-0123', - 'client_email': 'john.smith@example.com', - 'client_weight': '185', - 'consent_applicant': True, - 'consent_agent': False, - 'consent_date': '2026-02-08', - 'agent_last_name': '', - 'agent_first_name': '', - } - - try: - pdf_bytes = template.generate_filled_pdf(sample_context) - headers = [ - ('Content-Type', 'application/pdf'), - ('Content-Disposition', f'inline; filename="preview_{template.name}.pdf"'), - ] - return request.make_response(pdf_bytes, headers=headers) - except Exception as e: - _logger.error("PDF preview generation failed: %s", e) - return request.redirect(f'/fusion/pdf-editor/{template_id}?error=preview_failed') diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/controllers/portal_assessment.py b/fusion_authorizer_portal/fusion_authorizer_portal/controllers/portal_assessment.py deleted file mode 100644 index b69c431..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/controllers/portal_assessment.py +++ /dev/null @@ -1,1443 +0,0 @@ -# -*- coding: utf-8 -*- - -from odoo import http, fields, _ -from odoo.http import request -from odoo.addons.portal.controllers.portal import CustomerPortal, pager as portal_pager -from odoo.exceptions import AccessError, MissingError, ValidationError -import json -import base64 -import logging -from datetime import datetime -from markupsafe import Markup - -_logger = logging.getLogger(__name__) - - -class AssessmentPortal(CustomerPortal): - """Portal controller for Assessments""" - - @http.route(['/my/assessments', '/my/assessments/page/'], type='http', auth='user', website=True) - def portal_assessments(self, page=1, search='', state='', sortby='date', **kw): - """List of assessments""" - partner = request.env.user.partner_id - user = request.env.user - - if not partner.is_authorizer and not partner.is_sales_rep_portal: - return request.redirect('/my') - - Assessment = request.env['fusion.assessment'].sudo() - - # Build domain based on role - domain = [] - if partner.is_authorizer and partner.is_sales_rep_portal: - domain = ['|', ('authorizer_id', '=', partner.id), ('sales_rep_id', '=', user.id)] - elif partner.is_authorizer: - domain = [('authorizer_id', '=', partner.id)] - elif partner.is_sales_rep_portal: - domain = [('sales_rep_id', '=', user.id)] - - # Add state filter - if state: - domain.append(('state', '=', state)) - - # Add search filter - if search: - domain = domain + [ - '|', '|', - ('client_name', 'ilike', search), - ('reference', 'ilike', search), - ('client_email', 'ilike', search), - ] - - # Sorting - sortings = { - 'date': {'label': _('Date'), 'order': 'assessment_date desc'}, - 'name': {'label': _('Client'), 'order': 'client_name'}, - 'reference': {'label': _('Reference'), 'order': 'reference'}, - 'state': {'label': _('Status'), 'order': 'state'}, - } - order = sortings.get(sortby, sortings['date'])['order'] - - # Pager - assessment_count = Assessment.search_count(domain) - pager = portal_pager( - url='/my/assessments', - url_args={'search': search, 'state': state, 'sortby': sortby}, - total=assessment_count, - page=page, - step=20, - ) - - # Get assessments - assessments = Assessment.search(domain, order=order, limit=20, offset=pager['offset']) - - # State options for filter - state_options = [ - ('', _('All')), - ('draft', _('In Progress')), - ('pending_signature', _('Pending Signatures')), - ('completed', _('Completed')), - ('cancelled', _('Cancelled')), - ] - - values = { - 'assessments': assessments, - 'pager': pager, - 'search': search, - 'state': state, - 'state_options': state_options, - 'sortby': sortby, - 'sortings': sortings, - 'page_name': 'assessments', - } - - return request.render('fusion_authorizer_portal.portal_assessments', values) - - @http.route('/my/assessment/new', type='http', auth='user', website=True) - def portal_assessment_new(self, **kw): - """Start a new assessment""" - partner = request.env.user.partner_id - user = request.env.user - - if not partner.is_authorizer and not partner.is_sales_rep_portal: - return request.redirect('/my') - - # Get list of authorizers for dropdown (if sales rep starting assessment) - authorizers = request.env['res.partner'].sudo().search([ - ('is_authorizer', '=', True), - ]) - - values = { - 'partner': partner, - 'user': user, - 'authorizers': authorizers, - 'countries': request.env['res.country'].sudo().search([]), - 'default_country': request.env.ref('base.ca', raise_if_not_found=False), - 'page_name': 'assessment_new', - } - - return request.render('fusion_authorizer_portal.portal_assessment_form', values) - - @http.route('/my/assessment/', type='http', auth='user', website=True) - def portal_assessment_view(self, assessment_id, **kw): - """View/edit an assessment""" - partner = request.env.user.partner_id - user = request.env.user - - if not partner.is_authorizer and not partner.is_sales_rep_portal: - return request.redirect('/my') - - try: - assessment = request.env['fusion.assessment'].sudo().browse(assessment_id) - if not assessment.exists(): - raise MissingError(_('Assessment not found.')) - - # Check access - has_access = ( - (partner.is_authorizer and assessment.authorizer_id.id == partner.id) or - (partner.is_sales_rep_portal and assessment.sales_rep_id.id == user.id) - ) - if not has_access: - raise AccessError(_('You do not have access to this assessment.')) - - except (AccessError, MissingError): - return request.redirect('/my/assessments') - - # Get list of authorizers for dropdown - authorizers = request.env['res.partner'].sudo().search([ - ('is_authorizer', '=', True), - ]) - - # Get assessment photos - photos = request.env['ir.attachment'].sudo().search([ - ('res_model', '=', 'fusion.assessment'), - ('res_id', '=', assessment.id), - ('mimetype', 'like', 'image/%'), - ]) - - values = { - 'assessment': assessment, - 'partner': partner, - 'user': user, - 'authorizers': authorizers, - 'countries': request.env['res.country'].sudo().search([]), - 'page_name': 'assessment_edit', - 'is_readonly': assessment.state in ['completed', 'cancelled'], - 'photos': photos, - } - - return request.render('fusion_authorizer_portal.portal_assessment_form', values) - - @http.route('/my/assessment/save', type='http', auth='user', website=True, methods=['POST'], csrf=True) - def portal_assessment_save(self, assessment_id=None, **kw): - """Save assessment data (create or update)""" - partner = request.env.user.partner_id - user = request.env.user - - if not partner.is_authorizer and not partner.is_sales_rep_portal: - return request.redirect('/my') - - Assessment = request.env['fusion.assessment'].sudo() - - # Prepare values - vals = { - 'client_name': kw.get('client_name', ''), - 'client_first_name': kw.get('client_first_name', ''), - 'client_last_name': kw.get('client_last_name', ''), - 'client_street': kw.get('client_street', ''), - 'client_unit': kw.get('client_unit', ''), - 'client_city': kw.get('client_city', ''), - 'client_state': kw.get('client_state', 'Ontario'), - 'client_postal_code': kw.get('client_postal_code', ''), - 'client_phone': kw.get('client_phone', ''), - 'client_mobile': kw.get('client_mobile', ''), - 'client_email': kw.get('client_email', ''), - 'client_reference_1': kw.get('client_reference_1', ''), - 'client_reference_2': kw.get('client_reference_2', ''), - 'assessment_location': kw.get('assessment_location', 'home'), - 'assessment_location_notes': kw.get('assessment_location_notes', ''), - } - - # Wheelchair specifications - float_fields = [ - 'seat_width', 'seat_depth', 'seat_to_floor_height', 'back_height', - 'armrest_height', 'footrest_length', 'overall_width', 'overall_length', - 'overall_height', 'seat_angle', 'back_angle', 'client_weight', 'client_height' - ] - for field in float_fields: - if kw.get(field): - try: - vals[field] = float(kw.get(field)) - except (ValueError, TypeError): - pass - - # Selection fields - selection_fields = ['cushion_type', 'backrest_type', 'frame_type', 'wheel_type'] - for field in selection_fields: - if kw.get(field): - vals[field] = kw.get(field) - - # Text fields - text_fields = ['cushion_notes', 'backrest_notes', 'frame_notes', 'wheel_notes', - 'mobility_notes', 'accessibility_notes', 'special_requirements', 'diagnosis'] - for field in text_fields: - if kw.get(field): - vals[field] = kw.get(field) - - # Authorizer - if kw.get('authorizer_id'): - try: - vals['authorizer_id'] = int(kw.get('authorizer_id')) - except (ValueError, TypeError): - pass - - # Country - if kw.get('client_country_id'): - try: - vals['client_country_id'] = int(kw.get('client_country_id')) - except (ValueError, TypeError): - pass - - try: - if assessment_id and assessment_id != 'None': - # Update existing - assessment = Assessment.browse(int(assessment_id)) - if not assessment.exists(): - raise MissingError(_('Assessment not found.')) - - # Check access - has_access = ( - (partner.is_authorizer and assessment.authorizer_id.id == partner.id) or - (partner.is_sales_rep_portal and assessment.sales_rep_id.id == user.id) - ) - if not has_access: - raise AccessError(_('You do not have access to this assessment.')) - - if assessment.state not in ['draft', 'pending_signature']: - raise ValidationError(_('Cannot modify a completed or cancelled assessment.')) - - assessment.write(vals) - _logger.info(f"Updated assessment {assessment.reference}") - - else: - # Create new - vals['sales_rep_id'] = user.id - if partner.is_authorizer: - vals['authorizer_id'] = partner.id - - assessment = Assessment.create(vals) - _logger.info(f"Created new assessment {assessment.reference}") - - # Redirect based on action - action = kw.get('action', 'save') - if action == 'save_signatures': - return request.redirect(f'/my/assessment/{assessment.id}/signatures') - elif action == 'save_exit': - return request.redirect('/my/assessments') - else: - return request.redirect(f'/my/assessment/{assessment.id}') - - except Exception as e: - _logger.error(f"Error saving assessment: {e}") - return request.redirect('/my/assessments') - - @http.route('/my/assessment//signatures', type='http', auth='user', website=True) - def portal_assessment_signatures(self, assessment_id, **kw): - """Signature capture page""" - partner = request.env.user.partner_id - user = request.env.user - - if not partner.is_authorizer and not partner.is_sales_rep_portal: - return request.redirect('/my') - - try: - assessment = request.env['fusion.assessment'].sudo().browse(assessment_id) - if not assessment.exists(): - raise MissingError(_('Assessment not found.')) - - # Check access - has_access = ( - (partner.is_authorizer and assessment.authorizer_id.id == partner.id) or - (partner.is_sales_rep_portal and assessment.sales_rep_id.id == user.id) - ) - if not has_access: - raise AccessError(_('You do not have access to this assessment.')) - - except (AccessError, MissingError): - return request.redirect('/my/assessments') - - values = { - 'assessment': assessment, - 'partner': partner, - 'page_name': 'assessment_signatures', - } - - return request.render('fusion_authorizer_portal.portal_assessment_signatures', values) - - @http.route('/my/assessment//save_signature', type='jsonrpc', auth='user') - def portal_save_signature(self, assessment_id, signature_type='', signature_data='', signer_name='', **kw): - """Save a signature (AJAX)""" - partner = request.env.user.partner_id - user = request.env.user - - if not partner.is_authorizer and not partner.is_sales_rep_portal: - return {'success': False, 'error': 'Access denied'} - - try: - assessment = request.env['fusion.assessment'].sudo().browse(assessment_id) - if not assessment.exists(): - return {'success': False, 'error': 'Assessment not found'} - - # Check access - has_access = ( - (partner.is_authorizer and assessment.authorizer_id.id == partner.id) or - (partner.is_sales_rep_portal and assessment.sales_rep_id.id == user.id) - ) - if not has_access: - return {'success': False, 'error': 'Access denied'} - - if not signature_data: - return {'success': False, 'error': 'No signature data provided'} - - # Remove data URL prefix if present - if signature_data.startswith('data:image'): - signature_data = signature_data.split(',')[1] - - vals = {} - if signature_type == 'page_11': - vals = { - 'signature_page_11': signature_data, - 'signature_page_11_name': signer_name, - 'signature_page_11_date': datetime.now(), - } - elif signature_type == 'page_12': - vals = { - 'signature_page_12': signature_data, - 'signature_page_12_name': signer_name, - 'signature_page_12_date': datetime.now(), - } - else: - return {'success': False, 'error': 'Invalid signature type'} - - assessment.write(vals) - - # Update state if needed - if assessment.state == 'draft': - assessment.state = 'pending_signature' - - return { - 'success': True, - 'signatures_complete': assessment.signatures_complete, - } - - except Exception as e: - _logger.error(f"Error saving signature: {e}") - return {'success': False, 'error': str(e)} - - @http.route('/my/assessment//complete', type='http', auth='user', website=True, methods=['POST'], csrf=True) - def portal_assessment_complete(self, assessment_id, **kw): - """Complete the assessment""" - partner = request.env.user.partner_id - user = request.env.user - - if not partner.is_authorizer and not partner.is_sales_rep_portal: - return request.redirect('/my') - - try: - assessment = request.env['fusion.assessment'].sudo().browse(assessment_id) - if not assessment.exists(): - raise MissingError(_('Assessment not found.')) - - # Check access - has_access = ( - (partner.is_authorizer and assessment.authorizer_id.id == partner.id) or - (partner.is_sales_rep_portal and assessment.sales_rep_id.id == user.id) - ) - if not has_access: - raise AccessError(_('You do not have access to this assessment.')) - - # Complete the assessment - result = assessment.action_complete() - - # Redirect to the created sale order or assessments list - if assessment.sale_order_id: - return request.redirect('/my/assessments?message=completed') - else: - return request.redirect('/my/assessments') - - except ValidationError as e: - _logger.warning(f"Validation error completing assessment: {e}") - return request.redirect(f'/my/assessment/{assessment_id}/signatures?error=signatures_required') - except Exception as e: - _logger.error(f"Error completing assessment: {e}") - return request.redirect(f'/my/assessment/{assessment_id}?error=1') - - # ========================================================================== - # EXPRESS ASSESSMENT FORM ROUTES - # ========================================================================== - - @http.route('/my/assessment/express', type='http', auth='user', website=True) - def portal_assessment_express_new(self, **kw): - """Start a new express assessment (Page 1 - Equipment Selection)""" - partner = request.env.user.partner_id - user = request.env.user - - if not partner.is_sales_rep_portal: - return request.redirect('/my') - - # Get list of authorizers for dropdown - authorizers = request.env['res.partner'].sudo().search([ - ('is_authorizer', '=', True), - ], order='name') - - # JSON-safe authorizer list for searchable dropdown (Markup so t-out won't escape) - authorizers_json = Markup(json.dumps([ - {'id': a.id, 'name': a.name, 'email': a.email or ''} - for a in authorizers - ])) - - # Get existing clients for dropdown - clients = request.env['res.partner'].sudo().search([ - ('customer_rank', '>', 0), - ], order='name', limit=500) - - # Get Google Maps API key - ICP = request.env['ir.config_parameter'].sudo() - google_maps_api_key = ICP.get_param('fusion_claims.google_maps_api_key', '') - - values = { - 'partner': partner, - 'user': user, - 'authorizers': authorizers, - 'authorizers_json': authorizers_json, - 'clients': clients, - 'countries': request.env['res.country'].sudo().search([]), - 'provinces': self._get_canadian_provinces(), - 'default_country': request.env.ref('base.ca', raise_if_not_found=False), - 'page_name': 'assessment_express', - 'current_page': 1, - 'total_pages': 2, - 'assessment': None, - 'google_maps_api_key': google_maps_api_key, - } - - return request.render('fusion_authorizer_portal.portal_assessment_express', values) - - @http.route('/my/assessment/express/', type='http', auth='user', website=True) - def portal_assessment_express_edit(self, assessment_id, page=1, **kw): - """Continue/edit an express assessment""" - partner = request.env.user.partner_id - user = request.env.user - - if not partner.is_sales_rep_portal: - return request.redirect('/my') - - try: - assessment = request.env['fusion.assessment'].sudo().browse(assessment_id) - if not assessment.exists(): - raise MissingError(_('Assessment not found.')) - - # Check access - must be the sales rep who created it - if assessment.sales_rep_id.id != user.id: - raise AccessError(_('You do not have access to this assessment.')) - - if assessment.state in ['cancelled']: - return request.redirect('/my/assessments') - - except (AccessError, MissingError): - return request.redirect('/my/assessments') - - # Get list of authorizers for dropdown - authorizers = request.env['res.partner'].sudo().search([ - ('is_authorizer', '=', True), - ], order='name') - - # JSON-safe authorizer list for searchable dropdown (Markup so t-out won't escape) - authorizers_json = Markup(json.dumps([ - {'id': a.id, 'name': a.name, 'email': a.email or ''} - for a in authorizers - ])) - - # Get existing clients for dropdown - clients = request.env['res.partner'].sudo().search([ - ('customer_rank', '>', 0), - ], order='name', limit=500) - - try: - current_page = int(page) - except (ValueError, TypeError): - current_page = 1 - - # Get Google Maps API key - ICP = request.env['ir.config_parameter'].sudo() - google_maps_api_key = ICP.get_param('fusion_claims.google_maps_api_key', '') - - values = { - 'partner': partner, - 'user': user, - 'assessment': assessment, - 'authorizers': authorizers, - 'authorizers_json': authorizers_json, - 'clients': clients, - 'countries': request.env['res.country'].sudo().search([]), - 'provinces': self._get_canadian_provinces(), - 'default_country': request.env.ref('base.ca', raise_if_not_found=False), - 'page_name': 'assessment_express', - 'current_page': current_page, - 'total_pages': 2, - 'google_maps_api_key': google_maps_api_key, - } - - return request.render('fusion_authorizer_portal.portal_assessment_express', values) - - @http.route('/my/assessment/express/save', type='http', auth='user', website=True, methods=['POST'], csrf=True) - def portal_assessment_express_save(self, **kw): - """Save express assessment data (create or update)""" - partner = request.env.user.partner_id - user = request.env.user - - if not partner.is_sales_rep_portal: - return request.redirect('/my') - - Assessment = request.env['fusion.assessment'].sudo() - assessment_id = kw.get('assessment_id') - current_page = int(kw.get('current_page', 1)) - action = kw.get('action', 'next') # next, back, save, submit - - # Build values from form - vals = self._build_express_assessment_vals(kw) - - try: - if assessment_id and assessment_id != 'None' and assessment_id != '': - # Update existing - assessment = Assessment.browse(int(assessment_id)) - if not assessment.exists(): - raise MissingError(_('Assessment not found.')) - - if assessment.sales_rep_id.id != user.id: - raise AccessError(_('You do not have access to this assessment.')) - - if assessment.state == 'completed': - # Allow updating ONLY consent/signature fields on completed assessments - consent_fields = { - 'consent_signed_by', 'consent_declaration_accepted', 'consent_date', - 'agent_relationship', 'agent_first_name', 'agent_last_name', - 'agent_middle_initial', 'agent_unit', 'agent_street_number', - 'agent_street_name', 'agent_city', 'agent_province', - 'agent_postal_code', 'agent_home_phone', 'agent_business_phone', - 'agent_phone_ext', - } - consent_vals = {k: v for k, v in vals.items() if k in consent_fields} - if consent_vals: - assessment.write(consent_vals) - _logger.info(f"Updated consent fields on completed assessment {assessment.reference}") - elif assessment.state == 'cancelled': - raise ValidationError(_('Cannot modify a cancelled assessment.')) - else: - # Draft - allow full update - assessment.write(vals) - _logger.info(f"Updated express assessment {assessment.reference}") - else: - # Create new - vals['sales_rep_id'] = user.id - vals['state'] = 'draft' - assessment = Assessment.create(vals) - _logger.info(f"Created new express assessment {assessment.reference}") - - # Handle photo uploads - uploaded_photos = request.httprequest.files.getlist('assessment_photos') - if uploaded_photos: - for photo_file in uploaded_photos: - if photo_file and photo_file.filename: - try: - file_content = photo_file.read() - file_base64 = base64.b64encode(file_content) - - # Create attachment linked to assessment - attachment = request.env['ir.attachment'].sudo().create({ - 'name': photo_file.filename, - 'type': 'binary', - 'datas': file_base64, - 'res_model': 'fusion.assessment', - 'res_id': assessment.id, - 'mimetype': photo_file.content_type or 'image/jpeg', - }) - _logger.info(f"Uploaded assessment photo: {photo_file.filename}") - except Exception as e: - _logger.error(f"Error uploading photo {photo_file.filename}: {e}") - - # ===== Handle Page 11 signature capture ===== - signature_data = kw.get('signature_page_11_data', '') - if signature_data and signature_data.startswith('data:image/'): - try: - # Strip data URL prefix: "data:image/png;base64,..." - sig_base64 = signature_data.split(',', 1)[1] - sig_vals = { - 'signature_page_11': sig_base64, - 'signature_page_11_date': fields.Datetime.now(), - } - # Set signer name - if kw.get('consent_signed_by') == 'agent' and kw.get('agent_first_name'): - sig_vals['signature_page_11_name'] = ( - f"{kw.get('agent_first_name', '')} {kw.get('agent_last_name', '')}" - ).strip() - else: - sig_vals['signature_page_11_name'] = ( - f"{kw.get('client_first_name', '')} {kw.get('client_last_name', '')}" - ).strip() - assessment.write(sig_vals) - _logger.info(f"Saved Page 11 signature for assessment {assessment.reference}") - except Exception as e: - _logger.error(f"Error saving Page 11 signature: {e}") - - # Handle navigation - if action == 'submit': - # If already completed, we just saved consent/signature above -- redirect with success - if assessment.state == 'completed': - # Generate filled PDF if signature was added - if assessment.signature_page_11 and assessment.consent_declaration_accepted: - try: - pdf_bytes = assessment.generate_template_pdf('Page 11') - if pdf_bytes: - import base64 as b64 - assessment.write({ - 'signed_page_11_pdf': b64.b64encode(pdf_bytes), - 'signed_page_11_pdf_filename': f'ADP_Page11_{assessment.reference}.pdf', - }) - # Update sale order too - # Issue 8 fix: bypass document lock since this is a portal - # re-signing on an already-completed assessment (SO may have - # progressed past 'submitted' where the lock kicks in) - if assessment.sale_order_id: - assessment.sale_order_id.with_context( - skip_document_lock_validation=True - ).write({ - 'x_fc_signed_pages_11_12': b64.b64encode(pdf_bytes), - 'x_fc_signed_pages_filename': f'ADP_Page11_{assessment.reference}.pdf', - }) - _logger.info(f"Generated Page 11 PDF for completed assessment {assessment.reference}") - except Exception as pdf_e: - _logger.warning(f"PDF generation failed (non-blocking): {pdf_e}") - - # Post consent & signature info to sale order chatter - if assessment.sale_order_id and assessment.signature_page_11: - try: - from markupsafe import Markup - signer = assessment.signature_page_11_name or 'Unknown' - signed_by = 'Applicant' if assessment.consent_signed_by == 'applicant' else 'Agent' - consent_date = str(assessment.consent_date) if assessment.consent_date else 'N/A' - - # Create signature as attachment - sig_att = request.env['ir.attachment'].sudo().create({ - 'name': f'Page11_Signature_{assessment.reference}.png', - 'type': 'binary', - 'datas': assessment.signature_page_11, - 'res_model': 'sale.order', - 'res_id': assessment.sale_order_id.id, - 'mimetype': 'image/png', - }) - - body = Markup( - '' - ) - assessment.sale_order_id.message_post( - body=body, - message_type='comment', - subtype_xmlid='mail.mt_note', - attachment_ids=[sig_att.id], - ) - _logger.info(f"Posted Page 11 consent info to SO {assessment.sale_order_id.name}") - except Exception as chat_e: - _logger.warning(f"Failed to post consent to chatter: {chat_e}") - - so_id = assessment.sale_order_id.id if assessment.sale_order_id else '' - return request.redirect(f'/my/assessments?message=completed&so={so_id}') - - # Complete the express assessment - try: - sale_order = assessment.action_complete_express() - - # Post assessment photos to sale order chatter - photo_attachments = request.env['ir.attachment'].sudo().search([ - ('res_model', '=', 'fusion.assessment'), - ('res_id', '=', assessment.id), - ('mimetype', 'like', 'image/%'), - ]) - if photo_attachments: - # Copy attachments to sale order - attachment_ids = [] - for att in photo_attachments: - new_att = att.copy({ - 'res_model': 'sale.order', - 'res_id': sale_order.id, - }) - attachment_ids.append(new_att.id) - - # Post message to chatter with photos - sale_order.message_post( - body=f"

Assessment Photos
Photos from assessment {assessment.reference} by {request.env.user.name}

", - message_type='comment', - subtype_xmlid='mail.mt_comment', - attachment_ids=attachment_ids, - ) - _logger.info(f"Posted {len(attachment_ids)} assessment photos to sale order {sale_order.name}") - - # Process loaner checkout if loaner data was submitted - loaner_product_id = kw.get('loaner_product_id') - loaner_checkout_flag = kw.get('loaner_checkout', '0') - if loaner_product_id and loaner_checkout_flag == '1': - try: - loaner_vals = { - 'product_id': int(loaner_product_id), - 'sale_order_id': sale_order.id, - 'partner_id': sale_order.partner_id.id, - 'loaner_period_days': int(kw.get('loaner_period_days', 7)), - 'checkout_condition': kw.get('loaner_condition', 'good'), - 'checkout_notes': kw.get('loaner_notes', ''), - 'sales_rep_id': request.env.user.id, - } - if sale_order.x_fc_authorizer_id: - loaner_vals['authorizer_id'] = sale_order.x_fc_authorizer_id.id - if sale_order.partner_shipping_id: - loaner_vals['delivery_address'] = sale_order.partner_shipping_id.contact_address - loaner_lot = kw.get('loaner_lot_id') - if loaner_lot: - loaner_vals['lot_id'] = int(loaner_lot) - checkout = request.env['fusion.loaner.checkout'].sudo().create(loaner_vals) - checkout.action_checkout() - _logger.info(f"Created loaner checkout {checkout.name} for SO {sale_order.name}") - except Exception as le: - _logger.error(f"Error creating loaner checkout: {le}") - - # ===== Generate filled Page 11 PDF if signature exists ===== - if assessment.signature_page_11 and assessment.consent_declaration_accepted: - try: - pdf_bytes = assessment.generate_template_pdf('Page 11') - if pdf_bytes: - import base64 as b64 - assessment.write({ - 'signed_page_11_pdf': b64.b64encode(pdf_bytes), - 'signed_page_11_pdf_filename': f'ADP_Page11_{assessment.reference}.pdf', - }) - # Also store on sale order - # Issue 8 fix: bypass document lock for portal writes - sale_order.with_context( - skip_document_lock_validation=True - ).write({ - 'x_fc_signed_pages_11_12': b64.b64encode(pdf_bytes), - 'x_fc_signed_pages_filename': f'ADP_Page11_{assessment.reference}.pdf', - }) - _logger.info(f"Generated Page 11 PDF for assessment {assessment.reference}") - except Exception as pdf_e: - _logger.warning(f"PDF generation failed (non-blocking): {pdf_e}") - - return request.redirect(f'/my/assessments?message=completed&so={sale_order.id}') - except Exception as e: - _logger.error(f"Error completing express assessment: {e}") - return request.redirect(f'/my/assessment/express/{assessment.id}?error={str(e)}') - elif action == 'start_over': - # Cancel and start fresh - if assessment_id and assessment_id != 'None': - assessment.unlink() - return request.redirect('/my/assessment/express') - else: - # Just save - return request.redirect(f'/my/assessment/express/{assessment.id}?page={current_page}') - - except Exception as e: - _logger.error(f"Error saving express assessment: {e}") - if assessment_id and assessment_id != 'None': - return request.redirect(f'/my/assessment/express/{assessment_id}?page={current_page}&error=1') - return request.redirect('/my/assessment/express?error=1') - - def _build_express_assessment_vals(self, kw): - """Build values dict from express form POST data""" - vals = {} - - # Equipment type - if kw.get('equipment_type'): - vals['equipment_type'] = kw.get('equipment_type') - - # Equipment sub-types - if kw.get('rollator_type'): - vals['rollator_type'] = kw.get('rollator_type') - if kw.get('wheelchair_type'): - vals['wheelchair_type'] = kw.get('wheelchair_type') - if kw.get('powerchair_type'): - vals['powerchair_type'] = kw.get('powerchair_type') - - # Float measurements - float_fields = [ - 'rollator_handle_height', 'rollator_seat_height', - 'seat_width', 'seat_depth', 'seat_to_floor_height', 'back_height', - 'legrest_length', 'cane_height', 'client_weight', - ] - for field in float_fields: - if kw.get(field): - try: - vals[field] = float(kw.get(field)) - except (ValueError, TypeError): - pass - - # Checkbox options - collect as comma-separated strings - # Rollator addons - rollator_addons = kw.getlist('rollator_addons') if hasattr(kw, 'getlist') else [] - if not rollator_addons and 'rollator_addons' in kw: - rollator_addons = [kw.get('rollator_addons')] if kw.get('rollator_addons') else [] - if rollator_addons: - vals['rollator_addons'] = ', '.join(rollator_addons) - - # Wheelchair options - frame_options = kw.getlist('frame_options') if hasattr(kw, 'getlist') else [] - if not frame_options and 'frame_options' in kw: - frame_options = [kw.get('frame_options')] if kw.get('frame_options') else [] - if frame_options: - vals['frame_options'] = ', '.join(frame_options) - - wheel_options = kw.getlist('wheel_options') if hasattr(kw, 'getlist') else [] - if not wheel_options and 'wheel_options' in kw: - wheel_options = [kw.get('wheel_options')] if kw.get('wheel_options') else [] - if wheel_options: - vals['wheel_options'] = ', '.join(wheel_options) - - legrest_options = kw.getlist('legrest_options') if hasattr(kw, 'getlist') else [] - if not legrest_options and 'legrest_options' in kw: - legrest_options = [kw.get('legrest_options')] if kw.get('legrest_options') else [] - if legrest_options: - vals['legrest_options'] = ', '.join(legrest_options) - - additional_adp_options = kw.getlist('additional_adp_options') if hasattr(kw, 'getlist') else [] - if not additional_adp_options and 'additional_adp_options' in kw: - additional_adp_options = [kw.get('additional_adp_options')] if kw.get('additional_adp_options') else [] - if additional_adp_options: - vals['additional_adp_options'] = ', '.join(additional_adp_options) - - # Powerchair options - powerchair_options = kw.getlist('powerchair_options') if hasattr(kw, 'getlist') else [] - if not powerchair_options and 'powerchair_options' in kw: - powerchair_options = [kw.get('powerchair_options')] if kw.get('powerchair_options') else [] - if powerchair_options: - vals['powerchair_options'] = ', '.join(powerchair_options) - - specialty_controls = kw.getlist('specialty_controls') if hasattr(kw, 'getlist') else [] - if not specialty_controls and 'specialty_controls' in kw: - specialty_controls = [kw.get('specialty_controls')] if kw.get('specialty_controls') else [] - if specialty_controls: - vals['specialty_controls'] = ', '.join(specialty_controls) - - # Seatbelt type - if kw.get('seatbelt_type'): - vals['seatbelt_type'] = kw.get('seatbelt_type') - - # Additional customization - if kw.get('additional_customization'): - vals['additional_customization'] = kw.get('additional_customization') - - # Cushion and backrest - if kw.get('cushion_info'): - vals['cushion_info'] = kw.get('cushion_info') - if kw.get('backrest_info'): - vals['backrest_info'] = kw.get('backrest_info') - - # Client type - if kw.get('client_type'): - vals['client_type'] = kw.get('client_type') - - # Client info (Page 2) - if kw.get('client_first_name'): - vals['client_first_name'] = kw.get('client_first_name') - if kw.get('client_middle_name'): - vals['client_middle_name'] = kw.get('client_middle_name') - if kw.get('client_last_name'): - vals['client_last_name'] = kw.get('client_last_name') - - # Build full client name - name_parts = [] - if kw.get('client_first_name'): - name_parts.append(kw.get('client_first_name')) - if kw.get('client_middle_name'): - name_parts.append(kw.get('client_middle_name')) - if kw.get('client_last_name'): - name_parts.append(kw.get('client_last_name')) - if name_parts: - vals['client_name'] = ' '.join(name_parts) - - # Health card - if kw.get('client_health_card'): - vals['client_health_card'] = kw.get('client_health_card') - if kw.get('client_health_card_version'): - vals['client_health_card_version'] = kw.get('client_health_card_version') - - # Address - if kw.get('client_street'): - vals['client_street'] = kw.get('client_street') - if kw.get('client_unit'): - vals['client_unit'] = kw.get('client_unit') - if kw.get('client_city'): - vals['client_city'] = kw.get('client_city') - if kw.get('client_state'): - vals['client_state'] = kw.get('client_state') - if kw.get('client_postal_code'): - vals['client_postal_code'] = kw.get('client_postal_code') - if kw.get('client_country_id'): - try: - vals['client_country_id'] = int(kw.get('client_country_id')) - except (ValueError, TypeError): - pass - - # Contact - if kw.get('client_phone'): - vals['client_phone'] = kw.get('client_phone') - if kw.get('client_email'): - vals['client_email'] = kw.get('client_email') - - # Dates - date_fields = ['assessment_start_date', 'assessment_end_date', 'claim_authorization_date', 'previous_funding_date'] - for field in date_fields: - if kw.get(field): - try: - vals[field] = kw.get(field) - except (ValueError, TypeError): - pass - - # Reason for application - if kw.get('reason_for_application'): - vals['reason_for_application'] = kw.get('reason_for_application') - - # Authorizer - if kw.get('authorizer_id'): - try: - vals['authorizer_id'] = int(kw.get('authorizer_id')) - except (ValueError, TypeError): - pass - - # Existing partner selection - if kw.get('partner_id'): - try: - partner_id = int(kw.get('partner_id')) - if partner_id > 0: - vals['partner_id'] = partner_id - vals['create_new_partner'] = False - else: - vals['create_new_partner'] = True - except (ValueError, TypeError): - vals['create_new_partner'] = True - - # ===== PAGE 11: Consent & Declaration fields ===== - if kw.get('consent_signed_by'): - vals['consent_signed_by'] = kw.get('consent_signed_by') - - if kw.get('consent_declaration_accepted'): - vals['consent_declaration_accepted'] = True - - if kw.get('consent_date'): - try: - vals['consent_date'] = kw.get('consent_date') - except (ValueError, TypeError): - pass - - # Agent fields (only relevant when consent_signed_by == 'agent') - agent_fields = [ - 'agent_relationship', 'agent_first_name', 'agent_last_name', - 'agent_middle_initial', 'agent_unit', 'agent_street_number', - 'agent_street_name', 'agent_city', 'agent_province', - 'agent_postal_code', 'agent_home_phone', 'agent_business_phone', - 'agent_phone_ext', - ] - for field in agent_fields: - if kw.get(field): - vals[field] = kw.get(field) - - return vals - - def _get_canadian_provinces(self): - """Return list of Canadian provinces for dropdown""" - return [ - ('Ontario', 'Ontario'), - ('Quebec', 'Quebec'), - ('British Columbia', 'British Columbia'), - ('Alberta', 'Alberta'), - ('Manitoba', 'Manitoba'), - ('Saskatchewan', 'Saskatchewan'), - ('Nova Scotia', 'Nova Scotia'), - ('New Brunswick', 'New Brunswick'), - ('Newfoundland and Labrador', 'Newfoundland and Labrador'), - ('Prince Edward Island', 'Prince Edward Island'), - ('Northwest Territories', 'Northwest Territories'), - ('Yukon', 'Yukon'), - ('Nunavut', 'Nunavut'), - ] - - # ========================================================================= - # LOANER PORTAL ROUTES - # ========================================================================= - - @http.route('/my/loaner/categories', type='jsonrpc', auth='user', website=True) - def portal_loaner_categories(self, **kw): - """Return loaner product categories.""" - parent = request.env.ref('fusion_claims.product_category_loaner', raise_if_not_found=False) - if not parent: - return [] - categories = request.env['product.category'].sudo().search([ - ('parent_id', '=', parent.id), - ], order='name') - return [{'id': c.id, 'name': c.name} for c in categories] - - @http.route('/my/loaner/products', type='jsonrpc', auth='user', website=True) - def portal_loaner_products(self, **kw): - """Return available loaner products and their serial numbers.""" - domain = [('x_fc_can_be_loaned', '=', True)] - category_id = kw.get('category_id') - if category_id: - domain.append(('categ_id', '=', int(category_id))) - - products = request.env['product.product'].sudo().search(domain) - loaner_location = request.env.ref('fusion_claims.stock_location_loaner', raise_if_not_found=False) - - result = [] - for p in products: - lots = [] - if loaner_location: - quants = request.env['stock.quant'].sudo().search([ - ('product_id', '=', p.id), - ('location_id', '=', loaner_location.id), - ('quantity', '>', 0), - ]) - for q in quants: - if q.lot_id: - lots.append({'id': q.lot_id.id, 'name': q.lot_id.name}) - result.append({ - 'id': p.id, - 'name': p.name, - 'category_id': p.categ_id.id, - 'period_days': p.product_tmpl_id.x_fc_loaner_period_days or 7, - 'lots': lots, - }) - return result - - @http.route('/my/loaner/locations', type='jsonrpc', auth='user', website=True) - def portal_loaner_locations(self, **kw): - """Return internal stock locations for return.""" - locations = request.env['stock.location'].sudo().search([ - ('usage', '=', 'internal'), - ('company_id', '=', request.env.company.id), - ]) - return [{'id': loc.id, 'name': loc.complete_name} for loc in locations] - - @http.route('/my/loaner/checkout', type='jsonrpc', auth='user', website=True) - def portal_loaner_checkout(self, **kw): - """Checkout a loaner from the portal.""" - partner = request.env.user.partner_id - if not partner.is_sales_rep_portal and not partner.is_authorizer: - return {'error': 'Unauthorized'} - - product_id = int(kw.get('product_id', 0)) - lot_id = int(kw.get('lot_id', 0)) if kw.get('lot_id') else False - sale_order_id = int(kw.get('sale_order_id', 0)) if kw.get('sale_order_id') else False - client_id = int(kw.get('client_id', 0)) if kw.get('client_id') else False - loaner_period = int(kw.get('loaner_period_days', 7)) - condition = kw.get('checkout_condition', 'good') - notes = kw.get('checkout_notes', '') - - if not product_id: - return {'error': 'Product is required'} - - vals = { - 'product_id': product_id, - 'loaner_period_days': loaner_period, - 'checkout_condition': condition, - 'checkout_notes': notes, - 'sales_rep_id': request.env.user.id, - } - if lot_id: - vals['lot_id'] = lot_id - if sale_order_id: - so = request.env['sale.order'].sudo().browse(sale_order_id) - if so.exists(): - vals['sale_order_id'] = so.id - vals['partner_id'] = so.partner_id.id - vals['authorizer_id'] = so.x_fc_authorizer_id.id if so.x_fc_authorizer_id else False - vals['delivery_address'] = so.partner_shipping_id.contact_address if so.partner_shipping_id else '' - if client_id and not vals.get('partner_id'): - vals['partner_id'] = client_id - - if not vals.get('partner_id'): - return {'error': 'Client is required'} - - try: - checkout = request.env['fusion.loaner.checkout'].sudo().create(vals) - checkout.action_checkout() - return { - 'success': True, - 'checkout_id': checkout.id, - 'name': checkout.name, - 'message': f'Loaner {checkout.name} checked out successfully', - } - except Exception as e: - _logger.error(f"Loaner checkout error: {e}") - return {'error': str(e)} - - @http.route('/my/loaner/create-product', type='jsonrpc', auth='user', website=True) - def portal_loaner_create_product(self, **kw): - """Quick-create a loaner product with serial number from the portal.""" - partner = request.env.user.partner_id - if not partner.is_sales_rep_portal and not partner.is_authorizer: - return {'error': 'Unauthorized'} - - product_name = kw.get('product_name', '').strip() - serial_number = kw.get('serial_number', '').strip() - - if not product_name: - return {'error': 'Product name is required'} - if not serial_number: - return {'error': 'Serial number is required'} - - try: - # Use provided category or default to Loaner Equipment - category_id = kw.get('category_id') - if category_id: - category = request.env['product.category'].sudo().browse(int(category_id)) - if not category.exists(): - category = None - else: - category = None - - if not category: - category = request.env.ref('fusion_claims.product_category_loaner', raise_if_not_found=False) - if not category: - category = request.env['product.category'].sudo().search([ - ('name', '=', 'Loaner Equipment'), - ], limit=1) - if not category: - category = request.env['product.category'].sudo().create({ - 'name': 'Loaner Equipment', - }) - - # Create product template - product_tmpl = request.env['product.template'].sudo().create({ - 'name': product_name, - 'type': 'consu', - 'tracking': 'serial', - 'categ_id': category.id, - 'x_fc_can_be_loaned': True, - 'x_fc_loaner_period_days': 7, - 'sale_ok': False, - 'purchase_ok': False, - }) - product = product_tmpl.product_variant_id - - # Create serial number (lot) - lot = request.env['stock.lot'].sudo().create({ - 'name': serial_number, - 'product_id': product.id, - 'company_id': request.env.company.id, - }) - - # Add stock in loaner location - loaner_location = request.env.ref('fusion_claims.stock_location_loaner', raise_if_not_found=False) - if loaner_location: - request.env['stock.quant'].sudo().create({ - 'product_id': product.id, - 'location_id': loaner_location.id, - 'lot_id': lot.id, - 'quantity': 1, - }) - - return { - 'success': True, - 'product_id': product.id, - 'product_name': product.name, - 'lot_id': lot.id, - 'lot_name': lot.name, - } - except Exception as e: - _logger.error(f"Loaner product creation error: {e}") - return {'error': str(e)} - - @http.route('/my/loaner/return', type='jsonrpc', auth='user', website=True) - def portal_loaner_return(self, **kw): - """Return/pickup a loaner from the portal.""" - partner = request.env.user.partner_id - if not partner.is_sales_rep_portal and not partner.is_authorizer: - return {'error': 'Unauthorized'} - - checkout_id = int(kw.get('checkout_id', 0)) - return_condition = kw.get('return_condition', 'good') - return_notes = kw.get('return_notes', '') - return_location_id = int(kw.get('return_location_id', 0)) if kw.get('return_location_id') else None - - if not checkout_id: - return {'error': 'Checkout ID is required'} - - try: - checkout = request.env['fusion.loaner.checkout'].sudo().browse(checkout_id) - if not checkout.exists(): - return {'error': 'Checkout not found'} - if checkout.state not in ('checked_out', 'overdue', 'rental_pending'): - return {'error': 'This loaner is not currently checked out'} - - checkout.action_process_return( - return_condition=return_condition, - return_notes=return_notes, - return_location_id=return_location_id, - ) - return { - 'success': True, - 'message': f'Loaner {checkout.name} returned successfully', - } - except Exception as e: - _logger.error(f"Loaner return error: {e}") - return {'error': str(e)} - - # ========================================================================== - # PUBLIC ASSESSMENT BOOKING - # ========================================================================== - - @http.route('/book-assessment', type='http', auth='public', website=True, sitemap=True) - def portal_book_assessment(self, **kw): - """Public page for booking an accessibility assessment.""" - # Get available sales reps for assignment - SalesGroup = request.env.ref('sales_team.group_sale_salesman', raise_if_not_found=False) - sales_reps = [] - if SalesGroup: - sales_reps = request.env['res.users'].sudo().search([ - ('groups_id', 'in', [SalesGroup.id]), - ('active', '=', True), - ]) - - assessment_types = [ - ('stairlift_straight', 'Straight Stair Lift'), - ('stairlift_curved', 'Curved Stair Lift'), - ('vpl', 'Vertical Platform Lift'), - ('ceiling_lift', 'Ceiling Lift'), - ('ramp', 'Custom Ramp'), - ('bathroom', 'Bathroom Modification'), - ('tub_cutout', 'Tub Cutout'), - ] - - values = { - 'assessment_types': assessment_types, - 'sales_reps': sales_reps, - 'success': kw.get('success'), - 'error': kw.get('error'), - } - return request.render('fusion_authorizer_portal.portal_book_assessment', values) - - @http.route('/book-assessment/submit', type='http', auth='public', website=True, methods=['POST'], csrf=True) - def portal_book_assessment_submit(self, **kw): - """Process assessment booking form submission.""" - try: - # Validate required fields - if not kw.get('client_name') or not kw.get('client_phone'): - return request.redirect('/book-assessment?error=Please+provide+client+name+and+phone+number') - - if not kw.get('assessment_type'): - return request.redirect('/book-assessment?error=Please+select+an+assessment+type') - - Assessment = request.env['fusion.accessibility.assessment'].sudo() - - # Determine booking source - booking_source = 'portal' - if kw.get('booking_source'): - booking_source = kw['booking_source'] - - # Parse date - assessment_date = False - if kw.get('assessment_date'): - try: - assessment_date = fields.Date.from_string(kw['assessment_date']) - except Exception: - assessment_date = False - - # Determine sales rep - sales_rep_id = False - if kw.get('sales_rep_id'): - try: - sales_rep_id = int(kw['sales_rep_id']) - except (ValueError, TypeError): - pass - - # Build address string - address_parts = [] - if kw.get('client_street'): - address_parts.append(kw['client_street']) - if kw.get('client_city'): - address_parts.append(kw['client_city']) - if kw.get('client_province'): - address_parts.append(kw['client_province']) - if kw.get('client_postal'): - address_parts.append(kw['client_postal']) - - vals = { - 'assessment_type': kw['assessment_type'], - 'client_name': kw['client_name'], - 'client_phone': kw.get('client_phone', ''), - 'client_email': kw.get('client_email', ''), - 'client_address': ', '.join(address_parts) if address_parts else '', - 'client_address_street': kw.get('client_street', ''), - 'client_address_city': kw.get('client_city', ''), - 'client_address_province': kw.get('client_province', ''), - 'client_address_postal': kw.get('client_postal', ''), - 'assessment_date': assessment_date, - 'booking_source': booking_source, - 'modification_requested': kw.get('modification_requested', ''), - } - - if sales_rep_id: - vals['sales_rep_id'] = sales_rep_id - - # Link authorizer if provided - if kw.get('authorizer_name') and kw.get('authorizer_email'): - Partner = request.env['res.partner'].sudo() - authorizer = Partner.search([('email', '=', kw['authorizer_email'])], limit=1) - if not authorizer: - authorizer = Partner.create({ - 'name': kw['authorizer_name'], - 'email': kw['authorizer_email'], - 'phone': kw.get('authorizer_phone', ''), - 'is_authorizer': True, - }) - vals['authorizer_id'] = authorizer.id - - assessment = Assessment.create(vals) - - # Create calendar event for the sales rep - if assessment_date and sales_rep_id: - try: - from datetime import datetime as dt, timedelta - # Default: 10 AM, 1.5 hour duration - start = dt.combine(assessment_date, dt.min.time().replace(hour=10)) - stop = start + timedelta(hours=1, minutes=30) - event = request.env['calendar.event'].sudo().create({ - 'name': f'Assessment: {kw["client_name"]} ({kw.get("client_city", "")})', - 'start': fields.Datetime.to_string(start), - 'stop': fields.Datetime.to_string(stop), - 'user_id': sales_rep_id, - 'location': vals.get('client_address', ''), - 'description': ( - f'Accessibility Assessment Booking\n' - f'Client: {kw["client_name"]}\n' - f'Phone: {kw.get("client_phone", "")}\n' - f'Type: {kw["assessment_type"]}\n' - f'Request: {kw.get("modification_requested", "")}' - ), - 'partner_ids': [(4, request.env['res.users'].sudo().browse(sales_rep_id).partner_id.id)], - }) - assessment.write({'calendar_event_id': event.id}) - except Exception as e: - _logger.error(f"Failed to create calendar event: {e}") - - # Send authorizer notification email - if assessment.authorizer_id and assessment.authorizer_id.email: - try: - company = request.env.company - body_html = assessment._email_build( - title='Assessment Scheduled', - summary=f'An accessibility assessment has been booked for ' - f'{kw["client_name"]}.', - email_type='info', - sections=[('Booking Details', [ - ('Client', kw['client_name']), - ('Phone', kw.get('client_phone', '')), - ('Address', vals.get('client_address', '')), - ('Assessment Type', dict(Assessment._fields['assessment_type'].selection).get(kw['assessment_type'], '')), - ('Date', str(assessment_date) if assessment_date else 'TBD'), - ('Requested', kw.get('modification_requested', '')), - ])], - note='This booking was made through the online portal.', - sender_name=company.name, - ) - # Replace footer - body_html = body_html.replace( - 'This is an automated notification from the ADP Claims Management System.', - 'This is an automated notification from the Accessibility Case Management System.', - ) - request.env['mail.mail'].sudo().create({ - 'subject': f'Assessment Booked - {kw["client_name"]}', - 'body_html': body_html, - 'email_to': assessment.authorizer_id.email, - 'model': 'fusion.accessibility.assessment', - 'res_id': assessment.id, - }).send() - except Exception as e: - _logger.error(f"Failed to send authorizer notification: {e}") - - # Send Twilio SMS to client - if kw.get('client_phone'): - try: - ICP = request.env['ir.config_parameter'].sudo() - if ICP.get_param('fusion_claims.twilio_enabled', 'False').lower() in ('true', '1', 'yes'): - import requests as req - account_sid = ICP.get_param('fusion_claims.twilio_account_sid', '') - auth_token = ICP.get_param('fusion_claims.twilio_auth_token', '') - from_number = ICP.get_param('fusion_claims.twilio_phone_number', '') - company_phone = request.env.company.phone or '' - date_str = str(assessment_date) if assessment_date else 'a date to be confirmed' - sms_body = ( - f"Hi {kw['client_name']}, your accessibility assessment with " - f"Westin Healthcare has been booked for {date_str}. " - f"For questions, call {company_phone}." - ) - if all([account_sid, auth_token, from_number]): - url = f'https://api.twilio.com/2010-04-01/Accounts/{account_sid}/Messages.json' - req.post(url, data={ - 'To': kw['client_phone'], - 'From': from_number, - 'Body': sms_body, - }, auth=(account_sid, auth_token), timeout=10) - assessment.write({'sms_confirmation_sent': True}) - except Exception as e: - _logger.error(f"Failed to send SMS: {e}") - - return request.redirect('/book-assessment?success=1') - - except Exception as e: - _logger.error(f"Assessment booking error: {e}") - return request.redirect(f'/book-assessment?error={str(e)}') diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/controllers/portal_main.py b/fusion_authorizer_portal/fusion_authorizer_portal/controllers/portal_main.py deleted file mode 100644 index e05288a..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/controllers/portal_main.py +++ /dev/null @@ -1,2468 +0,0 @@ -# -*- coding: utf-8 -*- - -from odoo import http, _, fields -from odoo.http import request -from odoo.addons.portal.controllers.portal import CustomerPortal, pager as portal_pager -from odoo.exceptions import AccessError, MissingError -import base64 -import logging -import pytz - -_logger = logging.getLogger(__name__) - - -class AuthorizerPortal(CustomerPortal): - """Portal controller for Authorizers (OTs/Therapists)""" - - @http.route(['/my', '/my/home'], type='http', auth='user', website=True) - def home(self, **kw): - """Override home to add ADP posting info for Fusion users""" - partner = request.env.user.partner_id - - # Get the standard portal home response - response = super().home(**kw) - - # Add ADP posting info and other data for Fusion users - if hasattr(response, 'qcontext') and (partner.is_authorizer or partner.is_sales_rep_portal or partner.is_client_portal or partner.is_technician_portal): - posting_info = self._get_adp_posting_info() - response.qcontext.update(posting_info) - - # Add signature count (documents to sign) - only if Sign module is installed - sign_count = 0 - sign_module_available = 'sign.request.item' in request.env - if sign_module_available: - sign_count = request.env['sign.request.item'].sudo().search_count([ - ('partner_id', '=', partner.id), - ('state', '=', 'sent'), - ]) - response.qcontext['sign_count'] = sign_count - response.qcontext['sign_module_available'] = sign_module_available - - return response - - def _prepare_home_portal_values(self, counters): - """Add authorizer/sales rep counts to portal home""" - values = super()._prepare_home_portal_values(counters) - partner = request.env.user.partner_id - - if 'authorizer_case_count' in counters: - if partner.is_authorizer: - values['authorizer_case_count'] = request.env['sale.order'].sudo().search_count([ - ('x_fc_authorizer_id', '=', partner.id) - ]) - else: - values['authorizer_case_count'] = 0 - - if 'sales_rep_case_count' in counters: - if partner.is_sales_rep_portal: - values['sales_rep_case_count'] = request.env['sale.order'].sudo().search_count([ - ('user_id', '=', request.env.user.id) - ]) - else: - values['sales_rep_case_count'] = 0 - - if 'assessment_count' in counters: - count = 0 - if partner.is_authorizer: - count += request.env['fusion.assessment'].sudo().search_count([ - ('authorizer_id', '=', partner.id) - ]) - if partner.is_sales_rep_portal: - count += request.env['fusion.assessment'].sudo().search_count([ - ('sales_rep_id', '=', request.env.user.id) - ]) - values['assessment_count'] = count - - if 'technician_delivery_count' in counters: - if partner.is_technician_portal: - values['technician_delivery_count'] = request.env['sale.order'].sudo().search_count([ - ('x_fc_delivery_technician_ids', 'in', [request.env.user.id]) - ]) - else: - values['technician_delivery_count'] = 0 - - # Add ADP posting schedule info for portal users - if partner.is_authorizer or partner.is_sales_rep_portal or partner.is_client_portal or partner.is_technician_portal: - values.update(self._get_adp_posting_info()) - - return values - - def _get_adp_posting_info(self): - """Get ADP posting schedule information for the portal home.""" - from datetime import date, timedelta - - ICP = request.env['ir.config_parameter'].sudo() - - # Get base date and frequency from settings - base_date_str = ICP.get_param('fusion_claims.adp_posting_base_date', '2026-01-23') - frequency = int(ICP.get_param('fusion_claims.adp_posting_frequency_days', '14')) - - try: - base_date = date.fromisoformat(base_date_str) - except (ValueError, TypeError): - base_date = date(2026, 1, 23) - - # Get user's timezone for accurate date display - user_tz = request.env.user.tz or 'UTC' - try: - tz = pytz.timezone(user_tz) - except pytz.exceptions.UnknownTimeZoneError: - tz = pytz.UTC - - # Get today's date in user's timezone - from datetime import datetime - now_utc = datetime.now(pytz.UTC) - now_local = now_utc.astimezone(tz) - today = now_local.date() - - # Calculate next posting date - if today < base_date: - next_posting = base_date - else: - days_since_base = (today - base_date).days - cycles_passed = days_since_base // frequency - next_posting = base_date + timedelta(days=(cycles_passed + 1) * frequency) - - # If today is a posting day, return the next one - if days_since_base % frequency == 0: - next_posting = base_date + timedelta(days=(cycles_passed + 1) * frequency) - - # Calculate key dates for the posting cycle - # Wednesday is submission deadline (posting day - 2 if posting is Friday) - days_until_wednesday = (next_posting.weekday() - 2) % 7 - if days_until_wednesday == 0 and next_posting.weekday() != 2: - days_until_wednesday = 7 - submission_deadline = next_posting - timedelta(days=days_until_wednesday) - - # Get next 3 posting dates for the calendar - posting_dates = [] - current_posting = next_posting - for i in range(6): - posting_dates.append({ - 'date': current_posting.isoformat(), - 'display': current_posting.strftime('%B %d, %Y'), - 'day': current_posting.day, - 'month': current_posting.strftime('%B'), - 'year': current_posting.year, - 'weekday': current_posting.strftime('%A'), - 'is_next': i == 0, - }) - current_posting = current_posting + timedelta(days=frequency) - - # Days until next posting - days_until_posting = (next_posting - today).days - - return { - 'next_posting_date': next_posting, - 'next_posting_display': next_posting.strftime('%B %d, %Y'), - 'next_posting_weekday': next_posting.strftime('%A'), - 'submission_deadline': submission_deadline, - 'submission_deadline_display': submission_deadline.strftime('%B %d, %Y'), - 'days_until_posting': days_until_posting, - 'posting_dates': posting_dates, - 'current_month': today.strftime('%B %Y'), - 'today': today, - } - - # ==================== AUTHORIZER PORTAL ==================== - - @http.route(['/my/authorizer', '/my/authorizer/dashboard'], type='http', auth='user', website=True) - def authorizer_dashboard(self, **kw): - """Authorizer dashboard - simplified mobile-first view""" - partner = request.env.user.partner_id - - if not partner.is_authorizer: - return request.redirect('/my') - - SaleOrder = request.env['sale.order'].sudo() - Assessment = request.env['fusion.assessment'].sudo() - - # Base domain for this authorizer - base_domain = [('x_fc_authorizer_id', '=', partner.id)] - - # Total cases - total_cases = SaleOrder.search_count(base_domain) - - # Assessment counts (express + accessibility) - express_count = Assessment.search_count([('authorizer_id', '=', partner.id)]) - accessibility_count = 0 - if 'fusion.accessibility.assessment' in request.env: - accessibility_count = request.env['fusion.accessibility.assessment'].sudo().search_count([ - ('authorizer_id', '=', partner.id) - ]) - assessment_count = express_count + accessibility_count - - # Cases needing authorizer attention (waiting for application) - needs_attention = SaleOrder.search( - base_domain + [('x_fc_adp_application_status', 'in', [ - 'waiting_for_application', 'assessment_completed', - ])], - order='write_date desc', - limit=10, - ) - - # Human-readable status labels - status_labels = {} - if needs_attention: - status_labels = dict(needs_attention[0]._fields['x_fc_adp_application_status'].selection) - - # Sale type labels - sale_type_labels = {} - if total_cases: - sample = SaleOrder.search(base_domain, limit=1) - if sample and 'x_fc_sale_type' in sample._fields: - sale_type_labels = dict(sample._fields['x_fc_sale_type'].selection) - - # Recent cases (last 5 updated) - recent_cases = SaleOrder.search( - base_domain, - order='write_date desc', - limit=5, - ) - - # Get status labels from recent cases if not already loaded - if not status_labels and recent_cases: - status_labels = dict(recent_cases[0]._fields['x_fc_adp_application_status'].selection) - - # Pending assessments - pending_assessments = Assessment.search([ - ('authorizer_id', '=', partner.id), - ('state', 'in', ['draft', 'pending_signature']) - ], limit=5, order='assessment_date desc') - - company = request.env.company - - values = { - 'partner': partner, - 'company': company, - 'total_cases': total_cases, - 'assessment_count': assessment_count, - 'needs_attention': needs_attention, - 'recent_cases': recent_cases, - 'pending_assessments': pending_assessments, - 'status_labels': status_labels, - 'sale_type_labels': sale_type_labels, - 'page_name': 'authorizer_dashboard', - } - - return request.render('fusion_authorizer_portal.portal_authorizer_dashboard', values) - - @http.route(['/my/authorizer/cases', '/my/authorizer/cases/page/'], type='http', auth='user', website=True) - def authorizer_cases(self, page=1, search='', sortby='date', sale_type='', **kw): - """List of cases assigned to the authorizer""" - partner = request.env.user.partner_id - - if not partner.is_authorizer: - return request.redirect('/my') - - SaleOrder = request.env['sale.order'].sudo() - - # Sale type groupings for filtering - sale_type_groups = { - 'adp': ['adp', 'adp_odsp'], - 'odsp': ['odsp'], - 'march_of_dimes': ['march_of_dimes'], - 'others': ['wsib', 'direct_private', 'insurance', 'muscular_dystrophy', 'other', 'rental'], - } - - # Build domain - from odoo.osv import expression - domain = [('x_fc_authorizer_id', '=', partner.id)] - - # Add sale type filter - if sale_type and sale_type in sale_type_groups: - domain.append(('x_fc_sale_type', 'in', sale_type_groups[sale_type])) - - # Add search filter - if search: - search_domain = [ - '|', '|', '|', '|', - ('partner_id.name', 'ilike', search), - ('name', 'ilike', search), - ('x_fc_claim_number', 'ilike', search), - ('x_fc_client_ref_1', 'ilike', search), - ('x_fc_client_ref_2', 'ilike', search), - ] - domain = expression.AND([domain, search_domain]) - - # Sorting - sortings = { - 'date': {'label': _('Date'), 'order': 'date_order desc'}, - 'name': {'label': _('Reference'), 'order': 'name'}, - 'client': {'label': _('Client'), 'order': 'partner_id'}, - 'state': {'label': _('Status'), 'order': 'state'}, - } - order = sortings.get(sortby, sortings['date'])['order'] - - # Pager - case_count = SaleOrder.search_count(domain) - pager = portal_pager( - url='/my/authorizer/cases', - url_args={'search': search, 'sortby': sortby, 'sale_type': sale_type}, - total=case_count, - page=page, - step=20, - ) - - # Get cases - cases = SaleOrder.search(domain, order=order, limit=20, offset=pager['offset']) - - values = { - 'cases': cases, - 'pager': pager, - 'search': search, - 'sortby': sortby, - 'sortings': sortings, - 'sale_type': sale_type, - 'sale_type_label': { - 'adp': 'ADP Cases', - 'odsp': 'ODSP Cases', - 'march_of_dimes': 'March of Dimes', - 'others': 'Other Cases', - }.get(sale_type, 'All Cases'), - 'page_name': 'authorizer_cases', - } - - return request.render('fusion_authorizer_portal.portal_authorizer_cases', values) - - @http.route('/my/authorizer/cases/search', type='jsonrpc', auth='user') - def authorizer_cases_search(self, query='', **kw): - """AJAX search endpoint for real-time search""" - partner = request.env.user.partner_id - - if not partner.is_authorizer: - return {'error': 'Access denied', 'results': []} - - if len(query) < 2: - return {'results': []} - - SaleOrder = request.env['sale.order'].sudo() - orders = SaleOrder.get_authorizer_portal_cases(partner.id, search_query=query, limit=50) - - results = [] - for order in orders: - results.append({ - 'id': order.id, - 'name': order.name, - 'partner_name': order.partner_id.name if order.partner_id else '', - 'date_order': order.date_order.strftime('%Y-%m-%d') if order.date_order else '', - 'state': order.state, - 'state_display': dict(order._fields['state'].selection).get(order.state, order.state), - 'claim_number': getattr(order, 'x_fc_claim_number', '') or '', - 'client_ref_1': order.x_fc_client_ref_1 or '', - 'client_ref_2': order.x_fc_client_ref_2 or '', - 'url': f'/my/authorizer/case/{order.id}', - }) - - return {'results': results} - - @http.route('/my/authorizer/case/', type='http', auth='user', website=True) - def authorizer_case_detail(self, order_id, **kw): - """View a specific case""" - partner = request.env.user.partner_id - - if not partner.is_authorizer: - return request.redirect('/my') - - try: - order = request.env['sale.order'].sudo().browse(order_id) - if not order.exists() or order.x_fc_authorizer_id.id != partner.id: - raise AccessError(_('You do not have access to this case.')) - except (AccessError, MissingError): - return request.redirect('/my/authorizer/cases') - - # Get documents - documents = request.env['fusion.adp.document'].sudo().search([ - ('sale_order_id', '=', order_id), - ('is_current', '=', True), - ]) - - # Get messages from chatter - only those relevant to this user - # (authored by them, sent to them, or mentioning them) - all_messages = request.env['mail.message'].sudo().search([ - ('model', '=', 'sale.order'), - ('res_id', '=', order_id), - ('message_type', 'in', ['comment', 'notification']), - ('body', '!=', ''), - ('body', '!=', '


'), - ], order='date desc', limit=100) - - # Filter to only show messages relevant to this partner: - # 1. Messages authored by this partner - # 2. Messages where this partner is in notified_partner_ids - # 3. Messages where this partner is mentioned (partner_ids) - def is_relevant_message(msg): - if not msg.body or len(msg.body.strip()) == 0 or '


' in msg.body: - return False - # Authored by current partner - if msg.author_id.id == partner.id: - return True - # Partner is in notified partners - if partner.id in msg.notified_partner_ids.ids: - return True - # Partner is mentioned in partner_ids - if partner.id in msg.partner_ids.ids: - return True - return False - - filtered_messages = all_messages.filtered(is_relevant_message) - - values = { - 'order': order, - 'documents': documents, - 'messages': filtered_messages, - 'page_name': 'authorizer_case_detail', - } - - return request.render('fusion_authorizer_portal.portal_authorizer_case_detail', values) - - @http.route('/my/authorizer/case//comment', type='http', auth='user', website=True, methods=['POST']) - def authorizer_add_comment(self, order_id, comment='', **kw): - """Add a comment to a case - posts to sale order chatter and emails salesperson""" - partner = request.env.user.partner_id - - if not partner.is_authorizer: - return request.redirect('/my') - - if not comment.strip(): - return request.redirect(f'/my/authorizer/case/{order_id}') - - try: - order = request.env['sale.order'].sudo().browse(order_id) - if not order.exists() or order.x_fc_authorizer_id.id != partner.id: - raise AccessError(_('You do not have access to this case.')) - - # Post message to sale order chatter (internal note, not to all followers) - message = order.message_post( - body=comment.strip(), - message_type='comment', - subtype_xmlid='mail.mt_note', # Internal note - doesn't notify followers - author_id=partner.id, - ) - - # Send email notification to the salesperson - if order.user_id and order.user_id.partner_id: - from markupsafe import Markup - salesperson_partner = order.user_id.partner_id - order.message_notify( - partner_ids=[salesperson_partner.id], - body=Markup(f"

New message from Authorizer {partner.name}:

{comment.strip()}

"), - subject=f"[{order.name}] New message from Authorizer", - author_id=partner.id, - ) - - # Also save to fusion.authorizer.comment for portal display - if 'fusion.authorizer.comment' in request.env: - request.env['fusion.authorizer.comment'].sudo().create({ - 'sale_order_id': order_id, - 'author_id': partner.id, - 'comment': comment.strip(), - 'comment_type': 'general', - }) - - except Exception as e: - _logger.error(f"Error adding comment: {e}") - - return request.redirect(f'/my/authorizer/case/{order_id}') - - @http.route('/my/authorizer/case//upload', type='http', auth='user', website=True, methods=['POST'], csrf=True) - def authorizer_upload_document(self, order_id, document_type='full_application', document_file=None, revision_note='', **kw): - """Upload a document for a case""" - partner = request.env.user.partner_id - - if not partner.is_authorizer: - return request.redirect('/my') - - if not document_file or not document_file.filename: - return request.redirect(f'/my/authorizer/case/{order_id}') - - try: - order = request.env['sale.order'].sudo().browse(order_id) - if not order.exists() or order.x_fc_authorizer_id.id != partner.id: - raise AccessError(_('You do not have access to this case.')) - - # Don't allow authorizers to upload 'submitted_final' - if document_type == 'submitted_final': - document_type = 'full_application' - - file_content = document_file.read() - file_base64 = base64.b64encode(file_content) - - request.env['fusion.adp.document'].sudo().create({ - 'sale_order_id': order_id, - 'document_type': document_type, - 'file': file_base64, - 'filename': document_file.filename, - 'revision_note': revision_note, - 'source': 'authorizer', - }) - - except Exception as e: - _logger.error(f"Error uploading document: {e}") - - return request.redirect(f'/my/authorizer/case/{order_id}') - - @http.route('/my/authorizer/document//download', type='http', auth='user') - def authorizer_download_document(self, doc_id, **kw): - """Download a document""" - partner = request.env.user.partner_id - - if not partner.is_authorizer and not partner.is_sales_rep_portal: - return request.redirect('/my') - - try: - document = request.env['fusion.adp.document'].sudo().browse(doc_id) - if not document.exists(): - raise MissingError(_('Document not found.')) - - # Verify access - if document.sale_order_id: - order = document.sale_order_id - has_access = ( - (partner.is_authorizer and order.x_fc_authorizer_id.id == partner.id) or - (partner.is_sales_rep_portal and order.user_id.id == request.env.user.id) - ) - if not has_access: - raise AccessError(_('You do not have access to this document.')) - - file_content = base64.b64decode(document.file) - - # Check if viewing inline or downloading - view_inline = kw.get('view', '0') == '1' - disposition = 'inline' if view_inline else 'attachment' - - return request.make_response( - file_content, - headers=[ - ('Content-Type', document.mimetype or 'application/octet-stream'), - ('Content-Disposition', f'{disposition}; filename="{document.filename}"'), - ('Content-Length', len(file_content)), - ] - ) - - except Exception as e: - _logger.error(f"Error downloading document: {e}") - return request.redirect('/my') - - @http.route(['/my/authorizer/case//attachment/', - '/my/sales/case//attachment/'], type='http', auth='user') - def authorizer_download_attachment(self, order_id, attachment_type, **kw): - """Download an attachment from sale order (original application, xml, proof of delivery)""" - partner = request.env.user.partner_id - - if not partner.is_authorizer and not partner.is_sales_rep_portal: - return request.redirect('/my') - - try: - order = request.env['sale.order'].sudo().browse(order_id) - if not order.exists(): - raise MissingError(_('Order not found.')) - - # Verify access - has_access = ( - (partner.is_authorizer and order.x_fc_authorizer_id.id == partner.id) or - (partner.is_sales_rep_portal and order.user_id.id == request.env.user.id) - ) - if not has_access: - raise AccessError(_('You do not have access to this order.')) - - # Get the attachment based on type - attachment_map = { - 'original_application': ('x_fc_original_application', 'x_fc_original_application_filename', 'application/pdf', 'original_application.pdf'), - 'final_application': ('x_fc_final_submitted_application', 'x_fc_final_application_filename', 'application/pdf', 'final_application.pdf'), - 'xml_file': ('x_fc_xml_file', 'x_fc_xml_filename', 'application/xml', 'application.xml'), - 'proof_of_delivery': ('x_fc_proof_of_delivery', 'x_fc_proof_of_delivery_filename', 'application/pdf', 'proof_of_delivery.pdf'), - } - - if attachment_type not in attachment_map: - raise MissingError(_('Invalid attachment type.')) - - field_name, filename_field, default_mimetype, default_filename = attachment_map[attachment_type] - - if not hasattr(order, field_name) or not getattr(order, field_name): - raise MissingError(_('Attachment not found.')) - - file_content = base64.b64decode(getattr(order, field_name)) - filename = getattr(order, filename_field, None) or default_filename - - # Check if viewing inline or downloading - view_inline = kw.get('view', '0') == '1' - disposition = 'inline' if view_inline else 'attachment' - - return request.make_response( - file_content, - headers=[ - ('Content-Type', default_mimetype), - ('Content-Disposition', f'{disposition}; filename="{filename}"'), - ('Content-Length', len(file_content)), - ] - ) - - except Exception as e: - _logger.error(f"Error downloading attachment: {e}") - return request.redirect('/my') - - @http.route(['/my/authorizer/case//photo/', - '/my/sales/case//photo/'], type='http', auth='user') - def authorizer_view_photo(self, order_id, photo_id, **kw): - """View an approval photo""" - partner = request.env.user.partner_id - - if not partner.is_authorizer and not partner.is_sales_rep_portal: - return request.redirect('/my') - - try: - order = request.env['sale.order'].sudo().browse(order_id) - if not order.exists(): - raise MissingError(_('Order not found.')) - - # Verify access - has_access = ( - (partner.is_authorizer and order.x_fc_authorizer_id.id == partner.id) or - (partner.is_sales_rep_portal and order.user_id.id == request.env.user.id) - ) - if not has_access: - raise AccessError(_('You do not have access to this order.')) - - # Find the photo attachment - attachment = request.env['ir.attachment'].sudo().browse(photo_id) - if not attachment.exists() or attachment.id not in order.x_fc_approval_photo_ids.ids: - raise MissingError(_('Photo not found.')) - - file_content = base64.b64decode(attachment.datas) - - return request.make_response( - file_content, - headers=[ - ('Content-Type', attachment.mimetype or 'image/png'), - ('Content-Disposition', f'inline; filename="{attachment.name}"'), - ('Content-Length', len(file_content)), - ] - ) - - except Exception as e: - _logger.error(f"Error viewing photo: {e}") - return request.redirect('/my') - - # ==================== SALES REP PORTAL ==================== - - @http.route(['/my/sales', '/my/sales/dashboard'], type='http', auth='user', website=True) - def sales_rep_dashboard(self, search='', sale_type='', status='', **kw): - """Sales rep dashboard with search and filters""" - partner = request.env.user.partner_id - user = request.env.user - - if not partner.is_sales_rep_portal: - return request.redirect('/my') - - SaleOrder = request.env['sale.order'].sudo() - Assessment = request.env['fusion.assessment'].sudo() - - # Get case counts by status (unfiltered for stats) - base_domain = [('user_id', '=', user.id)] - - draft_count = SaleOrder.search_count(base_domain + [('state', '=', 'draft')]) - sent_count = SaleOrder.search_count(base_domain + [('state', '=', 'sent')]) - sale_count = SaleOrder.search_count(base_domain + [('state', '=', 'sale')]) - total_count = SaleOrder.search_count(base_domain) - - # Build filtered domain for recent cases - filtered_domain = base_domain.copy() - - # Apply search filter - if search: - search = search.strip() - filtered_domain += [ - '|', '|', '|', - ('name', 'ilike', search), - ('partner_id.name', 'ilike', search), - ('x_fc_claim_number', 'ilike', search), - ('partner_id.email', 'ilike', search), - ] - - # Apply sale type filter - if sale_type: - filtered_domain += [('x_fc_sale_type', '=', sale_type)] - - # Apply status filter - if status: - filtered_domain += [('state', '=', status)] - - # Recent cases (filtered) - recent_cases = SaleOrder.search(filtered_domain, limit=20, order='date_order desc') - - # Assessments - assessment_domain = [('sales_rep_id', '=', user.id)] - pending_assessments = Assessment.search( - assessment_domain + [('state', 'in', ['draft', 'pending_signature'])], - limit=5, order='assessment_date desc' - ) - completed_assessments_count = Assessment.search_count( - assessment_domain + [('state', '=', 'completed')] - ) - - values = { - 'partner': partner, - 'draft_count': draft_count, - 'sent_count': sent_count, - 'sale_count': sale_count, - 'total_count': total_count, - 'recent_cases': recent_cases, - 'pending_assessments': pending_assessments, - 'completed_assessments_count': completed_assessments_count, - 'page_name': 'sales_dashboard', - # Search and filter values - 'search': search, - 'sale_type_filter': sale_type, - 'status_filter': status, - } - - return request.render('fusion_authorizer_portal.portal_sales_dashboard', values) - - @http.route(['/my/sales/cases', '/my/sales/cases/page/'], type='http', auth='user', website=True) - def sales_rep_cases(self, page=1, search='', sortby='date', **kw): - """List of cases for the sales rep""" - partner = request.env.user.partner_id - user = request.env.user - - if not partner.is_sales_rep_portal: - return request.redirect('/my') - - SaleOrder = request.env['sale.order'].sudo() - - # Build domain - from odoo.osv import expression - domain = [('user_id', '=', user.id)] - - # Add search filter - if search: - search_domain = [ - '|', '|', '|', '|', - ('partner_id.name', 'ilike', search), - ('name', 'ilike', search), - ('x_fc_claim_number', 'ilike', search), - ('x_fc_client_ref_1', 'ilike', search), - ('x_fc_client_ref_2', 'ilike', search), - ] - domain = expression.AND([domain, search_domain]) - - # Sorting - sortings = { - 'date': {'label': _('Date'), 'order': 'date_order desc'}, - 'name': {'label': _('Reference'), 'order': 'name'}, - 'client': {'label': _('Client'), 'order': 'partner_id'}, - 'state': {'label': _('Status'), 'order': 'state'}, - } - order = sortings.get(sortby, sortings['date'])['order'] - - # Pager - case_count = SaleOrder.search_count(domain) - pager = portal_pager( - url='/my/sales/cases', - url_args={'search': search, 'sortby': sortby}, - total=case_count, - page=page, - step=20, - ) - - # Get cases - cases = SaleOrder.search(domain, order=order, limit=20, offset=pager['offset']) - - values = { - 'cases': cases, - 'pager': pager, - 'search': search, - 'sortby': sortby, - 'sortings': sortings, - 'page_name': 'sales_cases', - } - - return request.render('fusion_authorizer_portal.portal_sales_cases', values) - - @http.route('/my/sales/cases/search', type='jsonrpc', auth='user') - def sales_rep_cases_search(self, query='', **kw): - """AJAX search endpoint for sales rep real-time search""" - partner = request.env.user.partner_id - user = request.env.user - - if not partner.is_sales_rep_portal: - return {'error': 'Access denied', 'results': []} - - if len(query) < 2: - return {'results': []} - - SaleOrder = request.env['sale.order'].sudo() - orders = SaleOrder.get_sales_rep_portal_cases(user.id, search_query=query, limit=50) - - results = [] - for order in orders: - results.append({ - 'id': order.id, - 'name': order.name, - 'partner_name': order.partner_id.name if order.partner_id else '', - 'date_order': order.date_order.strftime('%Y-%m-%d') if order.date_order else '', - 'state': order.state, - 'state_display': dict(order._fields['state'].selection).get(order.state, order.state), - 'claim_number': getattr(order, 'x_fc_claim_number', '') or '', - 'client_ref_1': order.x_fc_client_ref_1 or '', - 'client_ref_2': order.x_fc_client_ref_2 or '', - 'url': f'/my/sales/case/{order.id}', - }) - - return {'results': results} - - @http.route('/my/sales/case/', type='http', auth='user', website=True) - def sales_rep_case_detail(self, order_id, **kw): - """View a specific case for sales rep""" - partner = request.env.user.partner_id - user = request.env.user - - if not partner.is_sales_rep_portal: - return request.redirect('/my') - - try: - order = request.env['sale.order'].sudo().browse(order_id) - if not order.exists() or order.user_id.id != user.id: - raise AccessError(_('You do not have access to this case.')) - except (AccessError, MissingError): - return request.redirect('/my/sales/cases') - - # Get documents - documents = request.env['fusion.adp.document'].sudo().search([ - ('sale_order_id', '=', order_id), - ('is_current', '=', True), - ]) - - # Get messages from chatter - only those relevant to this user - all_messages = request.env['mail.message'].sudo().search([ - ('model', '=', 'sale.order'), - ('res_id', '=', order_id), - ('message_type', 'in', ['comment', 'notification']), - ('body', '!=', ''), - ('body', '!=', '


'), - ], order='date desc', limit=100) - - # Filter to only show messages relevant to this partner: - # 1. Messages authored by this partner - # 2. Messages where this partner is in notified_partner_ids - # 3. Messages where this partner is mentioned (partner_ids) - def is_relevant_message(msg): - if not msg.body or len(msg.body.strip()) == 0 or '


' in msg.body: - return False - # Authored by current partner - if msg.author_id.id == partner.id: - return True - # Partner is in notified partners - if partner.id in msg.notified_partner_ids.ids: - return True - # Partner is mentioned in partner_ids - if partner.id in msg.partner_ids.ids: - return True - return False - - filtered_messages = all_messages.filtered(is_relevant_message) - - values = { - 'order': order, - 'documents': documents, - 'messages': filtered_messages, - 'page_name': 'sales_case_detail', - } - - return request.render('fusion_authorizer_portal.portal_sales_case_detail', values) - - @http.route('/my/sales/case//comment', type='http', auth='user', website=True, methods=['POST']) - def sales_rep_add_comment(self, order_id, comment='', **kw): - """Add a comment to a case (sales rep) - posts to sale order chatter and emails authorizer""" - partner = request.env.user.partner_id - user = request.env.user - - if not partner.is_sales_rep_portal: - return request.redirect('/my') - - if not comment.strip(): - return request.redirect(f'/my/sales/case/{order_id}') - - try: - order = request.env['sale.order'].sudo().browse(order_id) - if not order.exists() or order.user_id.id != user.id: - raise AccessError(_('You do not have access to this case.')) - - # Post message to sale order chatter (internal note, not to all followers) - message = order.message_post( - body=comment.strip(), - message_type='comment', - subtype_xmlid='mail.mt_note', # Internal note - doesn't notify followers - author_id=partner.id, - ) - - # Send email notification to the authorizer - if order.x_fc_authorizer_id: - from markupsafe import Markup - order.message_notify( - partner_ids=[order.x_fc_authorizer_id.id], - body=Markup(f"

New message from Sales Rep {partner.name}:

{comment.strip()}

"), - subject=f"[{order.name}] New message from Sales Rep", - author_id=partner.id, - ) - - # Also save to fusion.authorizer.comment for portal display - if 'fusion.authorizer.comment' in request.env: - request.env['fusion.authorizer.comment'].sudo().create({ - 'sale_order_id': order_id, - 'author_id': partner.id, - 'comment': comment.strip(), - 'comment_type': 'general', - }) - - except Exception as e: - _logger.error(f"Error adding comment: {e}") - - return request.redirect(f'/my/sales/case/{order_id}') - - # ==================== CLIENT FUNDING CLAIMS PORTAL ==================== - - def _prepare_home_portal_values(self, counters): - """Add client funding claims count to portal home""" - values = super()._prepare_home_portal_values(counters) - partner = request.env.user.partner_id - - if 'funding_claims_count' in counters: - # Count sale orders where partner is the customer - values['funding_claims_count'] = request.env['sale.order'].sudo().search_count([ - ('partner_id', '=', partner.id), - ('x_fc_sale_type', 'in', ['adp', 'adp_odsp', 'odsp', 'march_of_dimes']), - ]) - - return values - - @http.route(['/my/funding-claims', '/my/funding-claims/page/'], type='http', auth='user', website=True) - def client_funding_claims(self, page=1, sortby='date', **kw): - """List of funding claims for the client""" - partner = request.env.user.partner_id - SaleOrder = request.env['sale.order'].sudo() - - # Build domain - orders where partner is the customer - domain = [ - ('partner_id', '=', partner.id), - ('x_fc_sale_type', 'in', ['adp', 'adp_odsp', 'odsp', 'march_of_dimes']), - ] - - # Sorting - sortings = { - 'date': {'label': _('Date'), 'order': 'date_order desc'}, - 'name': {'label': _('Reference'), 'order': 'name'}, - 'status': {'label': _('Status'), 'order': 'x_fc_adp_application_status'}, - } - order = sortings.get(sortby, sortings['date'])['order'] - - # Pager - claim_count = SaleOrder.search_count(domain) - pager = portal_pager( - url='/my/funding-claims', - url_args={'sortby': sortby}, - total=claim_count, - page=page, - step=20, - ) - - # Get claims - claims = SaleOrder.search(domain, order=order, limit=20, offset=pager['offset']) - - values = { - 'claims': claims, - 'pager': pager, - 'sortby': sortby, - 'sortings': sortings, - 'page_name': 'funding_claims', - } - - return request.render('fusion_authorizer_portal.portal_client_claims', values) - - @http.route('/my/funding-claims/', type='http', auth='user', website=True) - def client_funding_claim_detail(self, order_id, **kw): - """View a specific funding claim""" - partner = request.env.user.partner_id - - try: - order = request.env['sale.order'].sudo().browse(order_id) - if not order.exists() or order.partner_id.id != partner.id: - raise AccessError(_('You do not have access to this claim.')) - except (AccessError, MissingError): - return request.redirect('/my/funding-claims') - - # Check if case is closed - documents only visible after case closed - is_case_closed = order.x_fc_adp_application_status == 'case_closed' - - # Get documents (only if case is closed) - documents = [] - if is_case_closed: - documents = request.env['fusion.adp.document'].sudo().search([ - ('sale_order_id', '=', order_id), - ('is_current', '=', True), - ('document_type', 'in', ['submitted_final', 'pages_11_12']), - ]) - - # Get invoices - invoices = order.invoice_ids.filtered(lambda inv: inv.state != 'cancel') - - values = { - 'order': order, - 'is_case_closed': is_case_closed, - 'documents': documents, - 'invoices': invoices, - 'page_name': 'funding_claim_detail', - } - - return request.render('fusion_authorizer_portal.portal_client_claim_detail', values) - - @http.route('/my/funding-claims//document//download', type='http', auth='user') - def client_download_document(self, order_id, doc_id, **kw): - """Download a document from a funding claim""" - partner = request.env.user.partner_id - - try: - order = request.env['sale.order'].sudo().browse(order_id) - if not order.exists() or order.partner_id.id != partner.id: - raise AccessError(_('You do not have access to this claim.')) - - # Check if case is closed - if order.x_fc_adp_application_status != 'case_closed': - raise AccessError(_('Documents are only available after the case is closed.')) - - document = request.env['fusion.adp.document'].sudo().browse(doc_id) - if not document.exists() or document.sale_order_id.id != order_id: - raise MissingError(_('Document not found.')) - - file_content = base64.b64decode(document.file) - - return request.make_response( - file_content, - headers=[ - ('Content-Type', document.mimetype or 'application/octet-stream'), - ('Content-Disposition', f'attachment; filename="{document.filename}"'), - ('Content-Length', len(file_content)), - ] - ) - - except Exception as e: - _logger.error(f"Error downloading document: {e}") - return request.redirect('/my/funding-claims') - - @http.route('/my/funding-claims//proof-of-delivery', type='http', auth='user') - def client_download_proof_of_delivery(self, order_id, **kw): - """Download proof of delivery from a funding claim""" - partner = request.env.user.partner_id - - try: - order = request.env['sale.order'].sudo().browse(order_id) - if not order.exists() or order.partner_id.id != partner.id: - raise AccessError(_('You do not have access to this claim.')) - - # Check if case is closed - if order.x_fc_adp_application_status != 'case_closed': - raise AccessError(_('Documents are only available after the case is closed.')) - - if not order.x_fc_proof_of_delivery: - raise MissingError(_('Proof of delivery not found.')) - - file_content = base64.b64decode(order.x_fc_proof_of_delivery) - filename = order.x_fc_proof_of_delivery_filename or 'proof_of_delivery.pdf' - - return request.make_response( - file_content, - headers=[ - ('Content-Type', 'application/pdf'), - ('Content-Disposition', f'attachment; filename="{filename}"'), - ('Content-Length', len(file_content)), - ] - ) - - except Exception as e: - _logger.error(f"Error downloading proof of delivery: {e}") - return request.redirect('/my/funding-claims') - - # ==================== TECHNICIAN PORTAL ==================== - - def _check_technician_access(self): - """Check if current user is a technician portal user.""" - partner = request.env.user.partner_id - if not partner.is_technician_portal: - return False - return True - - @http.route(['/my/technician', '/my/technician/dashboard'], type='http', auth='user', website=True) - def technician_dashboard(self, **kw): - """Technician dashboard - today's schedule with timeline.""" - if not self._check_technician_access(): - return request.redirect('/my') - - partner = request.env.user.partner_id - user = request.env.user - Task = request.env['fusion.technician.task'].sudo() - SaleOrder = request.env['sale.order'].sudo() - today = fields.Date.context_today(request.env['fusion.technician.task']) - - # Today's tasks - today_tasks = Task.search([ - ('technician_id', '=', user.id), - ('scheduled_date', '=', today), - ('status', '!=', 'cancelled'), - ], order='sequence, time_start, id') - - # Current in-progress task - current_task = today_tasks.filtered(lambda t: t.status == 'in_progress')[:1] - - # Next upcoming task (first scheduled/en_route today) - next_task = today_tasks.filtered(lambda t: t.status in ('scheduled', 'en_route'))[:1] - - # Stats - completed_today = len(today_tasks.filtered(lambda t: t.status == 'completed')) - remaining_today = len(today_tasks.filtered(lambda t: t.status in ('scheduled', 'en_route', 'in_progress'))) - total_today = len(today_tasks) - - # Total travel time for the day - total_travel = sum(today_tasks.mapped('travel_time_minutes')) - - # Legacy: deliveries assigned (for backward compat with existing delivery views) - delivery_domain = [('x_fc_delivery_technician_ids', 'in', [user.id])] - pending_pod_count = SaleOrder.search_count(delivery_domain + [ - ('x_fc_pod_signature', '=', False), - ('x_fc_adp_application_status', '=', 'ready_delivery'), - ]) - - # Tomorrow's task count - from datetime import timedelta - tomorrow = today + timedelta(days=1) - tomorrow_count = Task.search_count([ - ('technician_id', '=', user.id), - ('scheduled_date', '=', tomorrow), - ('status', '!=', 'cancelled'), - ]) - - # Technician's personal start address - start_address = user.sudo().x_fc_start_address or '' - - # Google Maps API key for Places autocomplete - ICP = request.env['ir.config_parameter'].sudo() - google_maps_api_key = ICP.get_param('fusion_claims.google_maps_api_key', '') - - values = { - 'today_tasks': today_tasks, - 'current_task': current_task, - 'next_task': next_task, - 'completed_today': completed_today, - 'remaining_today': remaining_today, - 'total_today': total_today, - 'total_travel': total_travel, - 'pending_pod_count': pending_pod_count, - 'tomorrow_count': tomorrow_count, - 'today_date': today, - 'start_address': start_address, - 'google_maps_api_key': google_maps_api_key, - 'page_name': 'technician_dashboard', - } - return request.render('fusion_authorizer_portal.portal_technician_dashboard', values) - - @http.route(['/my/technician/tasks', '/my/technician/tasks/page/'], type='http', auth='user', website=True) - def technician_tasks(self, page=1, search='', filter_status='all', filter_date='', **kw): - """List of all tasks for the technician.""" - if not self._check_technician_access(): - return request.redirect('/my') - - user = request.env.user - Task = request.env['fusion.technician.task'].sudo() - - domain = [('technician_id', '=', user.id)] - - if filter_status == 'scheduled': - domain.append(('status', '=', 'scheduled')) - elif filter_status == 'in_progress': - domain.append(('status', 'in', ('en_route', 'in_progress'))) - elif filter_status == 'completed': - domain.append(('status', '=', 'completed')) - elif filter_status == 'active': - domain.append(('status', 'not in', ('cancelled', 'completed'))) - # Default: show all - - if filter_date: - domain.append(('scheduled_date', '=', filter_date)) - - if search: - domain += ['|', '|', '|', - ('name', 'ilike', search), - ('partner_id.name', 'ilike', search), - ('address_city', 'ilike', search), - ('sale_order_id.name', 'ilike', search), - ] - - task_count = Task.search_count(domain) - pager = portal_pager( - url='/my/technician/tasks', - url_args={'search': search, 'filter_status': filter_status, 'filter_date': filter_date}, - total=task_count, - page=page, - step=20, - ) - - tasks = Task.search(domain, limit=20, offset=pager['offset'], - order='scheduled_date desc, sequence, time_start') - - values = { - 'tasks': tasks, - 'pager': pager, - 'search': search, - 'filter_status': filter_status, - 'filter_date': filter_date, - 'page_name': 'technician_tasks', - } - return request.render('fusion_authorizer_portal.portal_technician_tasks', values) - - @http.route('/my/technician/task/', type='http', auth='user', website=True) - def technician_task_detail(self, task_id, **kw): - """View a specific technician task.""" - if not self._check_technician_access(): - return request.redirect('/my') - - user = request.env.user - Task = request.env['fusion.technician.task'].sudo() - - try: - task = Task.browse(task_id) - if not task.exists() or task.technician_id.id != user.id: - raise AccessError(_('You do not have access to this task.')) - except (AccessError, MissingError): - return request.redirect('/my/technician/tasks') - - # Check for earlier uncompleted tasks (sequential enforcement) - earlier_incomplete = Task.search([ - ('technician_id', '=', user.id), - ('scheduled_date', '=', task.scheduled_date), - ('time_start', '<', task.time_start), - ('status', 'not in', ['completed', 'cancelled']), - ('id', '!=', task.id), - ], order='time_start', limit=1) - - # Get order lines if linked to a sale order - order_lines = [] - if task.sale_order_id: - order_lines = task.sale_order_id.order_line.filtered(lambda l: not l.display_type) - - # Get VAPID public key for push notifications - vapid_public = request.env['ir.config_parameter'].sudo().get_param( - 'fusion_claims.vapid_public_key', '' - ) - - values = { - 'task': task, - 'order_lines': order_lines, - 'vapid_public_key': vapid_public, - 'page_name': 'technician_task_detail', - 'earlier_incomplete': earlier_incomplete, - } - return request.render('fusion_authorizer_portal.portal_technician_task_detail', values) - - @http.route('/my/technician/task//add-notes', type='json', auth='user', website=True) - def technician_task_add_notes(self, task_id, notes, photos=None, **kw): - """Add notes (and optional photos) to a completed task. - - :param notes: text content of the note - :param photos: list of dicts with 'data' (base64 data-url) and 'name' - """ - if not self._check_technician_access(): - return {'success': False, 'error': 'Access denied'} - user = request.env.user - Task = request.env['fusion.technician.task'].sudo() - Attachment = request.env['ir.attachment'].sudo() - try: - task = Task.browse(task_id) - if not task.exists() or task.technician_id.id != user.id: - return {'success': False, 'error': 'Task not found'} - - from markupsafe import Markup, escape - import re - - # ---------------------------------------------------------- - # Process photos -> create ir.attachment records - # ---------------------------------------------------------- - attachment_ids = [] - if photos: - for i, photo in enumerate(photos): - photo_data = photo.get('data', '') - photo_name = photo.get('name', f'photo_{i+1}.jpg') - if not photo_data: - continue - # Strip data-url prefix (e.g. "data:image/jpeg;base64,...") - if ',' in photo_data: - photo_data = photo_data.split(',', 1)[1] - try: - att = Attachment.create({ - 'name': photo_name, - 'type': 'binary', - 'datas': photo_data, - 'res_model': 'fusion.technician.task', - 'res_id': task.id, - 'mimetype': 'image/jpeg', - }) - attachment_ids.append(att.id) - except Exception as e: - _logger.warning("Failed to attach photo %s: %s", photo_name, e) - - # ---------------------------------------------------------- - # Sanitize and format the notes text - # ---------------------------------------------------------- - safe_notes = str(escape(notes or '')) - formatted_notes = re.sub(r'\n', '
', safe_notes) - - timestamp = fields.Datetime.now().strftime("%b %d, %Y %I:%M %p") - safe_user = str(escape(user.name)) - safe_task = str(escape(task.name)) - - has_text = bool((notes or '').strip()) - photo_count = len(attachment_ids) - - # Build a small photo summary for inline display - photo_html = '' - if photo_count: - photo_html = '
%d photo(s) attached
' % photo_count - - # --- 1. Append to the completion_notes field on the task --- - note_parts = [] - if has_text: - note_parts.append( - '
%s
' % formatted_notes - ) - if photo_html: - note_parts.append(photo_html) - - if note_parts: - new_note = Markup( - '
' - '%s - %s' - '%s' - '
' - ) % (Markup(timestamp), Markup(safe_user), Markup(''.join(note_parts))) - - existing = task.completion_notes or '' - task.completion_notes = Markup(existing) + new_note - - # --- 2. Post to the TASK chatter --- - chatter_parts = [] - if has_text: - chatter_parts.append( - '
%s
' % formatted_notes - ) - if photo_html: - chatter_parts.append(photo_html) - - task_chatter = Markup( - '
' - ' Note Added' - '%s' - 'By %s' - '
' - ) % (Markup(''.join(chatter_parts)), Markup(safe_user)) - - task.message_post( - body=task_chatter, - message_type='comment', - subtype_xmlid='mail.mt_note', - attachment_ids=attachment_ids, - ) - - # --- 3. Post to the SALE ORDER chatter (if linked) --- - if task.sale_order_id: - so_chatter = Markup( - '
' - ' Technician Note - %s' - '%s' - 'By %s on %s' - '
' - ) % (Markup(safe_task), Markup(''.join(chatter_parts)), Markup(safe_user), Markup(timestamp)) - - # Duplicate attachments for the sale order so both records show them - so_att_ids = [] - for att_id in attachment_ids: - att = Attachment.browse(att_id) - so_att = att.copy({ - 'res_model': 'sale.order', - 'res_id': task.sale_order_id.id, - }) - so_att_ids.append(so_att.id) - - task.sale_order_id.message_post( - body=so_chatter, - message_type='comment', - subtype_xmlid='mail.mt_note', - attachment_ids=so_att_ids, - ) - - return {'success': True} - except Exception as e: - _logger.error(f"Add notes error: {e}") - return {'success': False, 'error': str(e)} - - @http.route('/my/technician/task//action', type='json', auth='user', website=True) - def technician_task_action(self, task_id, action, **kw): - """Handle task status changes (start, complete, en_route, cancel).""" - if not self._check_technician_access(): - return {'success': False, 'error': 'Access denied'} - - user = request.env.user - Task = request.env['fusion.technician.task'].sudo() - - try: - task = Task.browse(task_id) - if not task.exists() or task.technician_id.id != user.id: - return {'success': False, 'error': 'Task not found or not assigned to you'} - - if action == 'en_route': - task.action_start_en_route() - elif action == 'start': - task.action_start_task() - elif action == 'complete': - completion_notes = kw.get('completion_notes', '') - if completion_notes: - task.completion_notes = completion_notes - task.action_complete_task() - elif action == 'cancel': - task.action_cancel_task() - else: - return {'success': False, 'error': f'Unknown action: {action}'} - - # For completion, also return next task info - result = { - 'success': True, - 'status': task.status, - 'redirect_url': f'/my/technician/task/{task_id}', - } - if action == 'complete': - next_task = task.get_next_task_for_technician() - if next_task: - result['next_task_id'] = next_task.id - result['next_task_url'] = f'/my/technician/task/{next_task.id}' - result['next_task_name'] = next_task.name - result['next_task_time'] = task._float_to_time_str(next_task.time_start) - else: - result['next_task_id'] = False - result['all_done'] = True - return result - except Exception as e: - _logger.error(f"Task action error: {e}") - return {'success': False, 'error': str(e)} - - @http.route('/my/technician/task//voice-transcribe', type='json', auth='user', website=True) - def technician_voice_transcribe(self, task_id, audio_data, mime_type='audio/webm', **kw): - """Transcribe voice recording using OpenAI Whisper, translate to English.""" - if not self._check_technician_access(): - return {'success': False, 'error': 'Access denied'} - - user = request.env.user - Task = request.env['fusion.technician.task'].sudo() - ICP = request.env['ir.config_parameter'].sudo() - - task = Task.browse(task_id) - if not task.exists() or task.technician_id.id != user.id: - return {'success': False, 'error': 'Task not found'} - - api_key = ICP.get_param('fusion_notes.openai_api_key') or ICP.get_param('fusion_claims.ai_api_key', '') - if not api_key: - return {'success': False, 'error': 'OpenAI API key not configured'} - - import base64 - import tempfile - import os - import requests as http_requests - - try: - # Decode audio - audio_bytes = base64.b64decode(audio_data) - ext_map = {'audio/webm': '.webm', 'audio/ogg': '.ogg', 'audio/mp4': '.m4a', 'audio/wav': '.wav'} - ext = ext_map.get(mime_type, '.webm') - - with tempfile.NamedTemporaryFile(suffix=ext, delete=False) as tmp: - tmp.write(audio_bytes) - tmp_path = tmp.name - - # Call Whisper API - use 'translations' endpoint to auto-translate to English - with open(tmp_path, 'rb') as f: - resp = http_requests.post( - 'https://api.openai.com/v1/audio/translations', - headers={'Authorization': f'Bearer {api_key}'}, - files={'file': (f'recording{ext}', f, mime_type)}, - data={'model': 'whisper-1', 'response_format': 'text'}, - timeout=60, - ) - - os.unlink(tmp_path) - - if resp.status_code != 200: - return {'success': False, 'error': f'Whisper API error: {resp.text}'} - - transcription = resp.text.strip() - - # Store transcription and audio on task - task.write({ - 'voice_note_audio': audio_data, - 'voice_note_transcription': transcription, - }) - - return {'success': True, 'transcription': transcription} - - except Exception as e: - _logger.error(f"Voice transcription error: {e}") - return {'success': False, 'error': str(e)} - - @http.route('/my/technician/task//ai-format', type='json', auth='user', website=True) - def technician_ai_format(self, task_id, text, **kw): - """Use GPT to clean up and format raw notes text.""" - if not self._check_technician_access(): - return {'success': False, 'error': 'Access denied'} - - user = request.env.user - Task = request.env['fusion.technician.task'].sudo() - ICP = request.env['ir.config_parameter'].sudo() - - task = Task.browse(task_id) - if not task.exists() or task.technician_id.id != user.id: - return {'success': False, 'error': 'Task not found'} - - api_key = ICP.get_param('fusion_notes.openai_api_key') or ICP.get_param('fusion_claims.ai_api_key', '') - if not api_key: - return {'success': False, 'error': 'OpenAI API key not configured'} - - ai_model = ICP.get_param('fusion_claims.ai_model', 'gpt-4o-mini') - - import requests as http_requests - try: - task_type_label = dict(Task._fields['task_type'].selection).get(task.task_type, task.task_type) - system_prompt = ( - "You are formatting a field technician's notes into clear, professional text. " - "ALWAYS output in English. If the input is in another language, translate it to English. " - "Fix grammar, spelling, and punctuation. Remove filler words. " - "Keep all facts from the original. Make it concise and professional. " - "If it mentions work done, parts used, issues, or follow-ups, organize them clearly. " - "Return plain text only (no HTML)." - ) - - resp = http_requests.post( - 'https://api.openai.com/v1/chat/completions', - headers={'Authorization': f'Bearer {api_key}', 'Content-Type': 'application/json'}, - json={ - 'model': ai_model, - 'messages': [ - {'role': 'system', 'content': system_prompt}, - {'role': 'user', 'content': f'Task type: {task_type_label}\nClient: {task.partner_id.name or "N/A"}\nRaw notes:\n{text}'}, - ], - 'temperature': 0.3, - 'max_tokens': 1000, - }, - timeout=30, - ) - - if resp.status_code == 200: - data = resp.json() - formatted = data['choices'][0]['message']['content'] - return {'success': True, 'formatted_text': formatted} - else: - return {'success': False, 'error': f'AI service error ({resp.status_code})'} - except Exception as e: - _logger.error(f"AI format error: {e}") - return {'success': False, 'error': str(e)} - - @http.route('/my/technician/task//voice-complete', type='json', auth='user', website=True) - def technician_voice_complete(self, task_id, transcription, **kw): - """Format transcription with GPT and complete the task.""" - if not self._check_technician_access(): - return {'success': False, 'error': 'Access denied'} - - user = request.env.user - Task = request.env['fusion.technician.task'].sudo() - ICP = request.env['ir.config_parameter'].sudo() - - task = Task.browse(task_id) - if not task.exists() or task.technician_id.id != user.id: - return {'success': False, 'error': 'Task not found'} - - api_key = ICP.get_param('fusion_notes.openai_api_key') or ICP.get_param('fusion_claims.ai_api_key', '') - ai_model = ICP.get_param('fusion_claims.ai_model', 'gpt-4o-mini') - - formatted_notes = transcription # fallback - - if api_key: - import requests as http_requests - try: - task_type_label = dict(Task._fields['task_type'].selection).get(task.task_type, task.task_type) - system_prompt = ( - "You are formatting a technician's voice note into a structured completion report. " - "ALWAYS output in English. If the input is in another language, translate it to English. " - "The technician recorded this after completing a field task. " - "Format it into clear, professional HTML with these sections:\n" - "Work Performed: [summary]\n" - "Parts Used: [if mentioned, otherwise 'None mentioned']\n" - "Issues Found: [if any, otherwise 'None']\n" - "Follow-up Required: [yes/no + details]\n" - "Client Feedback: [if mentioned, otherwise 'N/A']\n\n" - "Keep all facts from the original. Fix grammar. Remove filler words. " - "Use
for line breaks, for labels. Keep it concise." - ) - - resp = http_requests.post( - 'https://api.openai.com/v1/chat/completions', - headers={'Authorization': f'Bearer {api_key}', 'Content-Type': 'application/json'}, - json={ - 'model': ai_model, - 'messages': [ - {'role': 'system', 'content': system_prompt}, - {'role': 'user', 'content': f'Task type: {task_type_label}\nTechnician: {user.name}\nVoice note:\n{transcription}'}, - ], - 'temperature': 0.3, - 'max_tokens': 1000, - }, - timeout=30, - ) - - if resp.status_code == 200: - data = resp.json() - formatted_notes = data['choices'][0]['message']['content'] - except Exception as e: - _logger.warning(f"GPT formatting failed, using raw transcription: {e}") - - # Build final HTML completion report - from markupsafe import Markup - completion_html = Markup( - f'
' - f'

Technician: {user.name}
' - f'Task: {task.name} ({dict(Task._fields["task_type"].selection).get(task.task_type, task.task_type)})

' - f'
' - f'{formatted_notes}' - f'
' - ) - - task.write({ - 'completion_notes': completion_html, - 'voice_note_transcription': transcription, - }) - task.action_complete_task() - - return { - 'success': True, - 'formatted_notes': formatted_notes, - 'redirect_url': f'/my/technician/task/{task_id}', - } - - @http.route('/my/technician/tomorrow', type='http', auth='user', website=True) - def technician_tomorrow(self, **kw): - """Next day preparation view.""" - if not self._check_technician_access(): - return request.redirect('/my') - - user = request.env.user - Task = request.env['fusion.technician.task'].sudo() - from datetime import timedelta - today = fields.Date.context_today(Task) - tomorrow = today + timedelta(days=1) - - tomorrow_tasks = Task.search([ - ('technician_id', '=', user.id), - ('scheduled_date', '=', tomorrow), - ('status', '!=', 'cancelled'), - ], order='sequence, time_start, id') - - total_travel = sum(tomorrow_tasks.mapped('travel_time_minutes')) - total_distance = sum(tomorrow_tasks.mapped('travel_distance_km')) - - # Aggregate equipment needed - all_equipment = [] - for t in tomorrow_tasks: - if t.equipment_needed: - all_equipment.append(f"{t.name}: {t.equipment_needed}") - - values = { - 'tomorrow_tasks': tomorrow_tasks, - 'tomorrow_date': tomorrow, - 'total_travel': total_travel, - 'total_distance': total_distance, - 'all_equipment': all_equipment, - 'page_name': 'technician_tomorrow', - } - return request.render('fusion_authorizer_portal.portal_technician_tomorrow', values) - - @http.route('/my/technician/schedule/', type='http', auth='user', website=True) - def technician_schedule_date(self, date, **kw): - """View schedule for a specific date.""" - if not self._check_technician_access(): - return request.redirect('/my') - - user = request.env.user - Task = request.env['fusion.technician.task'].sudo() - - try: - schedule_date = fields.Date.from_string(date) - except (ValueError, TypeError): - return request.redirect('/my/technician') - - tasks = Task.search([ - ('technician_id', '=', user.id), - ('scheduled_date', '=', schedule_date), - ('status', '!=', 'cancelled'), - ], order='sequence, time_start, id') - - total_travel = sum(tasks.mapped('travel_time_minutes')) - - values = { - 'tasks': tasks, - 'schedule_date': schedule_date, - 'total_travel': total_travel, - 'page_name': 'technician_schedule', - } - return request.render('fusion_authorizer_portal.portal_technician_schedule_date', values) - - @http.route('/my/technician/admin/map', type='http', auth='user', website=True) - def technician_location_map(self, **kw): - """Admin map view showing latest technician locations using Google Maps.""" - user = request.env.user - if not user.has_group('sales_team.group_sale_manager') and not user.has_group('sales_team.group_sale_salesman'): - return request.redirect('/my') - - LocationModel = request.env['fusion.technician.location'].sudo() - locations = LocationModel.get_latest_locations() - api_key = request.env['ir.config_parameter'].sudo().get_param( - 'fusion_claims.google_maps_api_key', '' - ) - values = { - 'locations': locations, - 'google_maps_api_key': api_key, - } - return request.render('fusion_authorizer_portal.portal_technician_map', values) - - @http.route('/my/technician/location/log', type='json', auth='user', website=True) - def technician_location_log(self, latitude, longitude, accuracy=None, **kw): - """Log the technician's current GPS location.""" - if not self._check_technician_access(): - return {'success': False} - try: - request.env['fusion.technician.location'].sudo().log_location( - latitude=latitude, - longitude=longitude, - accuracy=accuracy, - ) - return {'success': True} - except Exception as e: - _logger.warning(f"Location log error: {e}") - return {'success': False} - - @http.route('/my/technician/settings/start-location', type='json', auth='user', website=True) - def technician_save_start_location(self, address='', **kw): - """Save the technician's personal start location.""" - if not self._check_technician_access(): - return {'success': False, 'error': 'Access denied'} - try: - request.env.user.sudo().write({ - 'x_fc_start_address': address.strip() if address else False, - }) - return {'success': True} - except Exception as e: - _logger.warning("Error saving start location: %s", e) - return {'success': False, 'error': str(e)} - - @http.route('/my/technician/push/subscribe', type='json', auth='user', website=True) - def technician_push_subscribe(self, endpoint, p256dh, auth, **kw): - """Register a push notification subscription.""" - user = request.env.user - PushSub = request.env['fusion.push.subscription'].sudo() - browser_info = request.httprequest.headers.get('User-Agent', '')[:200] - sub = PushSub.register_subscription(user.id, endpoint, p256dh, auth, browser_info) - return {'success': True, 'subscription_id': sub.id} - - # Keep legacy delivery routes for backward compatibility - @http.route(['/my/technician/deliveries', '/my/technician/deliveries/page/'], type='http', auth='user', website=True) - def technician_deliveries(self, page=1, search='', filter_status='all', **kw): - """Legacy: List of deliveries for the technician (redirects to tasks).""" - return request.redirect('/my/technician/tasks?filter_status=all') - - @http.route('/my/technician/delivery/', type='http', auth='user', website=True) - def technician_delivery_detail(self, order_id, **kw): - """View a specific delivery for technician (legacy, still works).""" - if not self._check_technician_access(): - return request.redirect('/my') - - user = request.env.user - try: - order = request.env['sale.order'].sudo().browse(order_id) - if not order.exists() or user.id not in order.x_fc_delivery_technician_ids.ids: - raise AccessError(_('You do not have access to this delivery.')) - except (AccessError, MissingError): - return request.redirect('/my/technician/tasks') - - values = { - 'order': order, - 'page_name': 'technician_delivery_detail', - } - return request.render('fusion_authorizer_portal.portal_technician_delivery_detail_legacy', values) - - # ==================== POD SIGNATURE CAPTURE ==================== - - @http.route('/my/pod/', type='http', auth='user', website=True) - def pod_signature_page(self, order_id, **kw): - """POD signature capture page - accessible by technicians and sales reps""" - partner = request.env.user.partner_id - user = request.env.user - - try: - order = request.env['sale.order'].sudo().browse(order_id) - if not order.exists(): - raise MissingError(_('Order not found.')) - - # Check access - technician (via delivery list or task assignment), sales rep, or internal staff - has_access = False - user_role = None - - # Technician: check delivery technician list on the order - if partner.is_technician_portal and user.id in order.x_fc_delivery_technician_ids.ids: - has_access = True - user_role = 'technician' - - # Technician: also check if user is assigned to a task linked to this order - if not has_access and partner.is_technician_portal: - task_count = request.env['fusion.technician.task'].sudo().search_count([ - ('sale_order_id', '=', order.id), - ('technician_id', '=', user.id), - ]) - if task_count: - has_access = True - user_role = 'technician' - - # Internal users with field staff flag can always collect POD - if not has_access and not user.share: - has_access = True - user_role = 'technician' - - # Sales rep: own orders - if not has_access: - if partner.is_sales_rep_portal and order.user_id.id == user.id: - has_access = True - user_role = 'sales_rep' - elif order.user_id.id == user.id: - has_access = True - user_role = 'sales_rep' - - if not has_access: - raise AccessError(_('You do not have access to this order.')) - - except (AccessError, MissingError) as e: - _logger.warning(f"POD access denied for user {user.id} on order {order_id}: {e}") - return request.redirect('/my') - - # Get delivery address - delivery_address = order.partner_shipping_id or order.partner_id - - values = { - 'order': order, - 'delivery_address': delivery_address, - 'user_role': user_role, - 'has_existing_signature': bool(order.x_fc_pod_signature), - 'page_name': 'pod_signature', - } - - return request.render('fusion_authorizer_portal.portal_pod_signature', values) - - @http.route('/my/pod//sign', type='json', auth='user', methods=['POST']) - def pod_save_signature(self, order_id, client_name, signature_data, signature_date=None, **kw): - """Save POD signature via AJAX""" - partner = request.env.user.partner_id - user = request.env.user - - try: - order = request.env['sale.order'].sudo().browse(order_id) - if not order.exists(): - return {'success': False, 'error': 'Order not found'} - - # Check access - same logic as pod_signature_page - has_access = False - if partner.is_technician_portal and user.id in order.x_fc_delivery_technician_ids.ids: - has_access = True - elif partner.is_technician_portal: - task_count = request.env['fusion.technician.task'].sudo().search_count([ - ('sale_order_id', '=', order.id), - ('technician_id', '=', user.id), - ]) - if task_count: - has_access = True - if not has_access and not user.share: - has_access = True - if not has_access: - if partner.is_sales_rep_portal and order.user_id.id == user.id: - has_access = True - elif order.user_id.id == user.id: - has_access = True - - if not has_access: - return {'success': False, 'error': 'Access denied'} - - if not client_name or not client_name.strip(): - return {'success': False, 'error': 'Client name is required'} - - if not signature_data: - return {'success': False, 'error': 'Signature is required'} - - # Process signature data (remove data URL prefix if present) - if ',' in signature_data: - signature_data = signature_data.split(',')[1] - - # Parse signature date if provided - from datetime import datetime - sig_date = None - if signature_date: - try: - sig_date = datetime.strptime(signature_date, '%Y-%m-%d').date() - except ValueError: - pass # Leave as None if invalid - - # Determine if this is an ADP sale - is_adp = order.x_fc_sale_type in ('adp', 'adp_odsp') - - # Check if there's already an existing POD signature (for chatter logic) - had_existing_signature = bool(order.x_fc_pod_signature) - - # Save signature data - order.write({ - 'x_fc_pod_signature': signature_data, - 'x_fc_pod_client_name': client_name.strip(), - 'x_fc_pod_signature_date': sig_date, - 'x_fc_pod_signed_by_user_id': user.id, - 'x_fc_pod_signed_datetime': datetime.now(), - }) - - # Generate the signed POD PDF - # For ADP: save to x_fc_proof_of_delivery field - # For non-ADP: don't save to field, just generate for chatter - pdf_content = self._generate_signed_pod_pdf(order, save_to_field=is_adp) - - # Post to chatter - from markupsafe import Markup - date_str = sig_date.strftime('%B %d, %Y') if sig_date else 'Not specified' - pod_type = "ADP Proof of Delivery" if is_adp else "Proof of Delivery" - - if had_existing_signature: - # Update - post note about the update with new attachment - chatter_body = Markup(f''' -
-

{pod_type} Updated

-
    -
  • Client Name: {client_name.strip()}
  • -
  • Signature Date: {date_str}
  • -
  • Updated By: {user.name}
  • -
-

The POD document has been replaced with a new signed version.

-
- ''') - # For non-ADP updates, still attach the new PDF - if not is_adp and pdf_content: - attachment = request.env['ir.attachment'].sudo().create({ - 'name': f'POD_{order.name.replace("/", "_")}.pdf', - 'type': 'binary', - 'datas': base64.b64encode(pdf_content), - 'res_model': 'sale.order', - 'res_id': order.id, - 'mimetype': 'application/pdf', - }) - order.message_post( - body=chatter_body, - message_type='notification', - subtype_xmlid='mail.mt_note', - attachment_ids=[attachment.id], - ) - else: - order.message_post(body=chatter_body, message_type='notification', subtype_xmlid='mail.mt_note') - else: - # New POD - post with attachment - chatter_body = Markup(f''' -
-

{pod_type} Signed

-
    -
  • Client Name: {client_name.strip()}
  • -
  • Signature Date: {date_str}
  • -
  • Collected By: {user.name}
  • -
-
- ''') - - # Create attachment for the chatter (always for new POD) - if pdf_content: - attachment = request.env['ir.attachment'].sudo().create({ - 'name': f'POD_{order.name.replace("/", "_")}.pdf', - 'type': 'binary', - 'datas': base64.b64encode(pdf_content), - 'res_model': 'sale.order', - 'res_id': order.id, - 'mimetype': 'application/pdf', - }) - order.message_post( - body=chatter_body, - message_type='notification', - subtype_xmlid='mail.mt_note', - attachment_ids=[attachment.id], - ) - else: - order.message_post(body=chatter_body, message_type='notification', subtype_xmlid='mail.mt_note') - - return { - 'success': True, - 'message': 'Signature saved successfully', - 'redirect_url': f'/my/technician/delivery/{order_id}' if partner.is_technician_portal else f'/my/sales/case/{order_id}', - } - - except Exception as e: - _logger.error(f"Error saving POD signature: {e}") - return {'success': False, 'error': str(e)} - - def _generate_signed_pod_pdf(self, order, save_to_field=True): - """Generate a signed POD PDF with the signature embedded. - - Args: - order: The sale.order record - save_to_field: If True, save to x_fc_proof_of_delivery field (for ADP orders) - - Returns: - bytes: The PDF content, or None if generation failed - """ - try: - # Determine which report to use based on sale type - is_adp = order.x_fc_sale_type in ('adp', 'adp_odsp') - - if is_adp: - report = request.env.ref('fusion_claims.action_report_proof_of_delivery') - else: - report = request.env.ref('fusion_claims.action_report_proof_of_delivery_standard') - - # Render the POD report (signature is now embedded in the template) - pdf_content, _ = report.sudo()._render_qweb_pdf( - report.id, [order.id] - ) - - # For ADP orders, save to the x_fc_proof_of_delivery field - if save_to_field and is_adp: - order.write({ - 'x_fc_proof_of_delivery': base64.b64encode(pdf_content), - 'x_fc_proof_of_delivery_filename': f'POD_{order.name.replace("/", "_")}.pdf', - }) - - _logger.info(f"Generated signed POD PDF for order {order.name} (ADP: {is_adp})") - return pdf_content - - except Exception as e: - _logger.error(f"Error generating POD PDF for {order.name}: {e}") - return None - - # ========================================================================= - # ACCESSIBILITY ASSESSMENT ROUTES - # ========================================================================= - - @http.route('/my/accessibility', type='http', auth='user', website=True) - def accessibility_assessment_selector(self, **kw): - """Show the accessibility assessment type selector""" - partner = request.env.user.partner_id - - if not partner.is_sales_rep_portal and not partner.is_authorizer: - return request.redirect('/my') - - # Get Google Maps API key - ICP = request.env['ir.config_parameter'].sudo() - google_maps_api_key = ICP.get_param('fusion_claims.google_maps_api_key', '') - - values = { - 'page_name': 'accessibility_selector', - 'google_maps_api_key': google_maps_api_key, - } - return request.render('fusion_authorizer_portal.portal_accessibility_selector', values) - - @http.route('/my/accessibility/list', type='http', auth='user', website=True) - def accessibility_assessment_list(self, page=1, **kw): - """List all accessibility assessments for the current user (sales rep or authorizer)""" - partner = request.env.user.partner_id - - if not partner.is_sales_rep_portal and not partner.is_authorizer: - return request.redirect('/my') - - Assessment = request.env['fusion.accessibility.assessment'].sudo() - - # Build domain based on role - if partner.is_authorizer and partner.is_sales_rep_portal: - domain = ['|', ('authorizer_id', '=', partner.id), ('sales_rep_id', '=', request.env.user.id)] - elif partner.is_authorizer: - domain = [('authorizer_id', '=', partner.id)] - else: - domain = [('sales_rep_id', '=', request.env.user.id)] - - # Pagination - assessment_count = Assessment.search_count(domain) - pager = portal_pager( - url='/my/accessibility/list', - total=assessment_count, - page=page, - step=20, - ) - - assessments = Assessment.search( - domain, - order='assessment_date desc, id desc', - limit=20, - offset=pager['offset'], - ) - - values = { - 'page_name': 'accessibility_list', - 'assessments': assessments, - 'pager': pager, - } - return request.render('fusion_authorizer_portal.portal_accessibility_list', values) - - @http.route('/my/accessibility/stairlift/straight', type='http', auth='user', website=True) - def accessibility_stairlift_straight(self, **kw): - """Straight stair lift assessment form""" - return self._render_accessibility_form('stairlift_straight', 'Straight Stair Lift') - - @http.route('/my/accessibility/stairlift/curved', type='http', auth='user', website=True) - def accessibility_stairlift_curved(self, **kw): - """Curved stair lift assessment form""" - return self._render_accessibility_form('stairlift_curved', 'Curved Stair Lift') - - @http.route('/my/accessibility/vpl', type='http', auth='user', website=True) - def accessibility_vpl(self, **kw): - """Vertical Platform Lift assessment form""" - return self._render_accessibility_form('vpl', 'Vertical Platform Lift') - - @http.route('/my/accessibility/ceiling-lift', type='http', auth='user', website=True) - def accessibility_ceiling_lift(self, **kw): - """Ceiling Lift assessment form""" - return self._render_accessibility_form('ceiling_lift', 'Ceiling Lift') - - @http.route('/my/accessibility/ramp', type='http', auth='user', website=True) - def accessibility_ramp(self, **kw): - """Custom Ramp assessment form""" - return self._render_accessibility_form('ramp', 'Custom Ramp') - - @http.route('/my/accessibility/bathroom', type='http', auth='user', website=True) - def accessibility_bathroom(self, **kw): - """Bathroom Modification assessment form""" - return self._render_accessibility_form('bathroom', 'Bathroom Modification') - - @http.route('/my/accessibility/tub-cutout', type='http', auth='user', website=True) - def accessibility_tub_cutout(self, **kw): - """Tub Cutout assessment form""" - return self._render_accessibility_form('tub_cutout', 'Tub Cutout') - - def _render_accessibility_form(self, assessment_type, title): - """Render an accessibility assessment form""" - partner = request.env.user.partner_id - - if not partner.is_sales_rep_portal and not partner.is_authorizer: - return request.redirect('/my') - - # Get Google Maps API key - ICP = request.env['ir.config_parameter'].sudo() - google_maps_api_key = ICP.get_param('fusion_claims.google_maps_api_key', '') - - from datetime import date - - values = { - 'page_name': f'accessibility_{assessment_type}', - 'assessment_type': assessment_type, - 'title': title, - 'google_maps_api_key': google_maps_api_key, - 'today': date.today().isoformat(), - } - - # Route to specific template based on type - template_map = { - 'stairlift_straight': 'fusion_authorizer_portal.portal_accessibility_stairlift_straight', - 'stairlift_curved': 'fusion_authorizer_portal.portal_accessibility_stairlift_curved', - 'vpl': 'fusion_authorizer_portal.portal_accessibility_vpl', - 'ceiling_lift': 'fusion_authorizer_portal.portal_accessibility_ceiling', - 'ramp': 'fusion_authorizer_portal.portal_accessibility_ramp', - 'bathroom': 'fusion_authorizer_portal.portal_accessibility_bathroom', - 'tub_cutout': 'fusion_authorizer_portal.portal_accessibility_tub_cutout', - } - - template = template_map.get(assessment_type, 'fusion_authorizer_portal.portal_accessibility_selector') - return request.render(template, values) - - @http.route('/my/accessibility/save', type='json', auth='user', methods=['POST'], csrf=True) - def accessibility_assessment_save(self, **post): - """Save an accessibility assessment and optionally create a Sale Order""" - partner = request.env.user.partner_id - - if not partner.is_sales_rep_portal and not partner.is_authorizer: - return {'success': False, 'error': 'Access denied'} - - try: - Assessment = request.env['fusion.accessibility.assessment'].sudo() - - assessment_type = post.get('assessment_type') - if not assessment_type: - return {'success': False, 'error': 'Assessment type is required'} - - # Build assessment values - vals = { - 'assessment_type': assessment_type, - 'sales_rep_id': request.env.user.id, - 'client_name': post.get('client_name', '').strip(), - 'client_address': post.get('client_address', '').strip(), - 'client_unit': post.get('client_unit', '').strip(), - 'client_address_street': post.get('client_address_street', '').strip(), - 'client_address_city': post.get('client_address_city', '').strip(), - 'client_address_province': post.get('client_address_province', '').strip(), - 'client_address_postal': post.get('client_address_postal', '').strip(), - 'client_phone': post.get('client_phone', '').strip(), - 'client_email': post.get('client_email', '').strip(), - 'notes': post.get('notes', '').strip(), - } - - # Parse assessment date - assessment_date = post.get('assessment_date') - if assessment_date: - from datetime import date as dt_date - try: - vals['assessment_date'] = dt_date.fromisoformat(assessment_date) - except ValueError: - vals['assessment_date'] = dt_date.today() - - # Add type-specific fields - if assessment_type == 'stairlift_straight': - vals.update(self._parse_stairlift_straight_fields(post)) - elif assessment_type == 'stairlift_curved': - vals.update(self._parse_stairlift_curved_fields(post)) - elif assessment_type == 'vpl': - vals.update(self._parse_vpl_fields(post)) - elif assessment_type == 'ceiling_lift': - vals.update(self._parse_ceiling_lift_fields(post)) - elif assessment_type == 'ramp': - vals.update(self._parse_ramp_fields(post)) - elif assessment_type == 'bathroom': - vals.update(self._parse_bathroom_fields(post)) - elif assessment_type == 'tub_cutout': - vals.update(self._parse_tub_cutout_fields(post)) - - # Set authorizer if the current user is an authorizer, or from the linked sale order - if partner.is_authorizer: - vals['authorizer_id'] = partner.id - - # Create the assessment - assessment = Assessment.create(vals) - _logger.info(f"Created accessibility assessment {assessment.reference} by {request.env.user.name}") - - # Handle photo attachments - General photos - photos = post.get('photos', []) - if photos: - self._attach_accessibility_photos(assessment, photos, category='general') - - # Handle top landing photos (for curved stair lifts) - top_landing_photos = post.get('top_landing_photos', []) - if top_landing_photos: - self._attach_accessibility_photos(assessment, top_landing_photos, category='top_landing') - - # Handle bottom landing photos (for curved stair lifts) - bottom_landing_photos = post.get('bottom_landing_photos', []) - if bottom_landing_photos: - self._attach_accessibility_photos(assessment, bottom_landing_photos, category='bottom_landing') - - # Handle video attachment - video_data = post.get('assessment_video') - video_filename = post.get('assessment_video_filename') - if video_data: - self._attach_accessibility_video(assessment, video_data, video_filename) - - # Complete the assessment and create Sale Order if requested - create_sale_order = post.get('create_sale_order', True) - if create_sale_order: - sale_order = assessment.action_complete() - return { - 'success': True, - 'assessment_id': assessment.id, - 'assessment_ref': assessment.reference, - 'sale_order_id': sale_order.id, - 'sale_order_name': sale_order.name, - 'message': f'Assessment {assessment.reference} completed. Sale Order {sale_order.name} created.', - 'redirect_url': f'/my/sales/case/{sale_order.id}', - } - else: - return { - 'success': True, - 'assessment_id': assessment.id, - 'assessment_ref': assessment.reference, - 'message': f'Assessment {assessment.reference} saved as draft.', - 'redirect_url': '/my/accessibility/list', - } - - except Exception as e: - _logger.error(f"Error saving accessibility assessment: {e}") - return {'success': False, 'error': str(e)} - - def _parse_stairlift_straight_fields(self, post): - """Parse straight stair lift specific fields""" - return { - 'stair_steps': int(post.get('stair_steps', 0) or 0), - 'stair_nose_to_nose': float(post.get('stair_nose_to_nose', 0) or 0), - 'stair_side': post.get('stair_side') or None, - 'stair_style': post.get('stair_style') or None, - 'stair_power_swivel_upstairs': post.get('stair_power_swivel_upstairs') == 'true', - 'stair_power_folding_footrest': post.get('stair_power_folding_footrest') == 'true', - 'stair_manual_length_override': float(post.get('stair_manual_length_override', 0) or 0), - } - - def _parse_stairlift_curved_fields(self, post): - """Parse curved stair lift specific fields""" - return { - 'stair_curved_steps': int(post.get('stair_curved_steps', 0) or 0), - 'stair_curves_count': int(post.get('stair_curves_count', 0) or 0), - 'stair_top_landing_type': post.get('stair_top_landing_type') or 'none', - 'stair_bottom_landing_type': post.get('stair_bottom_landing_type') or 'none', - 'top_overrun_custom_length': float(post.get('top_overrun_custom_length', 0) or 0), - 'bottom_overrun_custom_length': float(post.get('bottom_overrun_custom_length', 0) or 0), - 'stair_power_swivel_upstairs': post.get('stair_power_swivel_upstairs') == 'true', - 'stair_power_swivel_downstairs': post.get('stair_power_swivel_downstairs') == 'true', - 'stair_auto_folding_footrest': post.get('stair_auto_folding_footrest') == 'true', - 'stair_auto_folding_hinge': post.get('stair_auto_folding_hinge') == 'true', - 'stair_auto_folding_seat': post.get('stair_auto_folding_seat') == 'true', - 'stair_custom_color': post.get('stair_custom_color') == 'true', - 'stair_additional_charging': post.get('stair_additional_charging') == 'true', - 'stair_charging_with_remote': post.get('stair_charging_with_remote') == 'true', - 'stair_curved_manual_override': float(post.get('stair_curved_manual_override', 0) or 0), - } - - def _parse_vpl_fields(self, post): - """Parse VPL specific fields""" - return { - 'vpl_room_width': float(post.get('vpl_room_width', 0) or 0), - 'vpl_room_depth': float(post.get('vpl_room_depth', 0) or 0), - 'vpl_rise_height': float(post.get('vpl_rise_height', 0) or 0), - 'vpl_has_existing_platform': post.get('vpl_has_existing_platform') == 'true', - 'vpl_concrete_depth': float(post.get('vpl_concrete_depth', 0) or 0), - 'vpl_model_type': post.get('vpl_model_type') or None, - 'vpl_has_nearby_plug': post.get('vpl_has_nearby_plug') == 'true', - 'vpl_needs_plug_install': post.get('vpl_needs_plug_install') == 'true', - 'vpl_needs_certification': post.get('vpl_needs_certification') == 'true', - 'vpl_certification_notes': post.get('vpl_certification_notes', '').strip(), - } - - def _parse_ceiling_lift_fields(self, post): - """Parse ceiling lift specific fields""" - return { - 'ceiling_track_length': float(post.get('ceiling_track_length', 0) or 0), - 'ceiling_movement_type': post.get('ceiling_movement_type') or None, - 'ceiling_charging_throughout': post.get('ceiling_charging_throughout') == 'true', - 'ceiling_carry_bar': post.get('ceiling_carry_bar') == 'true', - 'ceiling_additional_slings': int(post.get('ceiling_additional_slings', 0) or 0), - } - - def _parse_ramp_fields(self, post): - """Parse ramp specific fields""" - return { - 'ramp_height': float(post.get('ramp_height', 0) or 0), - 'ramp_ground_incline': float(post.get('ramp_ground_incline', 0) or 0), - 'ramp_at_door': post.get('ramp_at_door') == 'true', - 'ramp_handrail_height': float(post.get('ramp_handrail_height', 32) or 32), - 'ramp_manual_override': float(post.get('ramp_manual_override', 0) or 0), - } - - def _parse_bathroom_fields(self, post): - """Parse bathroom modification specific fields""" - return { - 'bathroom_description': post.get('bathroom_description', '').strip(), - } - - def _parse_tub_cutout_fields(self, post): - """Parse tub cutout specific fields""" - return { - 'tub_internal_height': float(post.get('tub_internal_height', 0) or 0), - 'tub_external_height': float(post.get('tub_external_height', 0) or 0), - 'tub_additional_supplies': post.get('tub_additional_supplies', '').strip(), - } - - def _attach_accessibility_photos(self, assessment, photos, category='general'): - """Attach photos to the accessibility assessment - - Args: - assessment: The assessment record - photos: List of base64 encoded photo data - category: Photo category (general, top_landing, bottom_landing) - """ - Attachment = request.env['ir.attachment'].sudo() - - # Category prefix for file naming - category_prefixes = { - 'general': 'Photo', - 'top_landing': 'TopLanding', - 'bottom_landing': 'BottomLanding', - } - prefix = category_prefixes.get(category, 'Photo') - - for i, photo_data in enumerate(photos): - if not photo_data: - continue - - # Handle base64 data URL format - if ',' in photo_data: - photo_data = photo_data.split(',')[1] - - try: - attachment = Attachment.create({ - 'name': f'{prefix}_{i+1}_{assessment.reference}.jpg', - 'type': 'binary', - 'datas': photo_data, - 'res_model': 'fusion.accessibility.assessment', - 'res_id': assessment.id, - 'mimetype': 'image/jpeg', - 'description': f'{category.replace("_", " ").title()} photo for {assessment.reference}', - }) - _logger.info(f"Attached {category} photo {i+1} to assessment {assessment.reference}") - except Exception as e: - _logger.warning(f"Failed to attach {category} photo {i+1}: {e}") - - def _attach_accessibility_video(self, assessment, video_data, video_filename=None): - """Attach a video to the accessibility assessment - - Args: - assessment: The assessment record - video_data: Base64 encoded video data - video_filename: Original filename (optional) - """ - if not video_data: - return - - Attachment = request.env['ir.attachment'].sudo() - - # Handle base64 data URL format - mimetype = 'video/mp4' - if isinstance(video_data, str) and ',' in video_data: - # Extract mimetype from data URL - header = video_data.split(',')[0] - if 'video/' in header: - mimetype = header.split(':')[1].split(';')[0] - video_data = video_data.split(',')[1] - - # Determine file extension from mimetype - extension_map = { - 'video/mp4': '.mp4', - 'video/webm': '.webm', - 'video/quicktime': '.mov', - 'video/x-msvideo': '.avi', - } - extension = extension_map.get(mimetype, '.mp4') - - filename = video_filename or f'Video_{assessment.reference}{extension}' - - try: - attachment = Attachment.create({ - 'name': filename, - 'type': 'binary', - 'datas': video_data, - 'res_model': 'fusion.accessibility.assessment', - 'res_id': assessment.id, - 'mimetype': mimetype, - 'description': f'Assessment video for {assessment.reference}', - }) - _logger.info(f"Attached video to assessment {assessment.reference}") - except Exception as e: - _logger.warning(f"Failed to attach video to assessment {assessment.reference}: {e}") diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/data/ir_actions_server_data.xml b/fusion_authorizer_portal/fusion_authorizer_portal/data/ir_actions_server_data.xml deleted file mode 100644 index d78d3cc..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/data/ir_actions_server_data.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - Mark as Authorizer - - - list - code - -action = records.action_mark_as_authorizer() - - - - - - Send Portal Invitation - - - list - code - -action = records.action_batch_send_portal_invitation() - - - - - - Mark as Authorizer & Send Invitation - - - list - code - -action = records.action_mark_and_send_invitation() - - - - diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/data/mail_template_data.xml b/fusion_authorizer_portal/fusion_authorizer_portal/data/mail_template_data.xml deleted file mode 100644 index c26a4da..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/data/mail_template_data.xml +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - - Assessment Sequence - fusion.assessment - ASM- - 5 - 1 - 1 - - - - - Accessibility Assessment Sequence - fusion.accessibility.assessment - ACC- - 5 - 1 - 1 - - - - - - - - Authorizer Portal: Case Assigned - - New Case Assigned: {{ object.name }} - {{ object.partner_id.name }} - {{ (object.company_id.email or object.user_id.email or 'noreply@example.com') }} - {{ object.x_fc_authorizer_id.email }} - -
-
-
-

-

New Case Assigned

-

A new ADP case has been assigned to you.

- - - - - -
Case Details
Case
Client
Date
-

View in Portal

-

Best regards,

-
-

This is an automated notification from .

-
-
- -
- - - - Authorizer Portal: Status Changed (Disabled) - - Case Update: {{ object.name }} -

This template is no longer in use.

- -
- - - - - - Assessment Complete - Authorizer Notification - - Assessment Complete: {{ object.reference }} - {{ object.client_name }} - {{ (object.sales_rep_id.company_id.email or 'noreply@example.com') }} - {{ object.authorizer_id.email }} - -
-
-
-

-

Assessment Complete

-

The assessment for has been completed and a sale order has been created.

- - - - - - - - -
Assessment Details
Reference
Client
Date
Sale Order
-
-

Next steps: Please submit the ADP application (including pages 11-12 signed by the client) so we can proceed with the claim submission.

-
-

View in Portal

-

Best regards,

-
-

This is an automated notification from the ADP Claims Management System.

-
-
- -
- - - - - - Assessment Complete - Client Notification - - Your Assessment is Complete - {{ object.reference }} - {{ (object.sales_rep_id.company_id.email or 'noreply@example.com') }} - {{ object.client_email }} - -
-
-
-

-

Assessment Complete

-

Dear , thank you for completing your assessment with us.

- - - - - - - -
Summary
Reference
Date
Therapist
-
-

What happens next:

-
    -
  1. Your assessment will be reviewed by our team
  2. -
  3. We will submit the ADP application on your behalf
  4. -
  5. You will be notified once approval is received
  6. -
  7. Your equipment will be ordered and delivered
  8. -
-
-

If you have any questions, please do not hesitate to contact us.

-

Best regards,

-
-

This is an automated notification from the ADP Claims Management System.

-
-
- -
- - - - - - Authorizer Portal: Document Uploaded - - New Document Uploaded: {{ object.name }} - {{ (object.company_id.email or 'noreply@example.com') }} - {{ object.x_fc_authorizer_id.email }} - -
-
-
-

-

New Document Available

-

A new document has been uploaded for case ().

-

View in Portal

-

Best regards,

-
-

This is an automated notification from .

-
-
- -
- -
diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/data/portal_menu_data.xml b/fusion_authorizer_portal/fusion_authorizer_portal/data/portal_menu_data.xml deleted file mode 100644 index b42b421..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/data/portal_menu_data.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/data/welcome_articles.xml b/fusion_authorizer_portal/fusion_authorizer_portal/data/welcome_articles.xml deleted file mode 100644 index dfbdf68..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/data/welcome_articles.xml +++ /dev/null @@ -1,432 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/models/__init__.py b/fusion_authorizer_portal/fusion_authorizer_portal/models/__init__.py deleted file mode 100644 index 297f041..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/models/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- - -from . import res_partner -from . import res_users -from . import authorizer_comment -from . import adp_document -from . import assessment -from . import accessibility_assessment -from . import sale_order -from . import pdf_template \ No newline at end of file diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/models/accessibility_assessment.py b/fusion_authorizer_portal/fusion_authorizer_portal/models/accessibility_assessment.py deleted file mode 100644 index 07a0fa7..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/models/accessibility_assessment.py +++ /dev/null @@ -1,874 +0,0 @@ -# -*- coding: utf-8 -*- - -import logging -import math -from datetime import timedelta -from markupsafe import Markup -from odoo import api, fields, models, _ -from odoo.exceptions import UserError - -_logger = logging.getLogger(__name__) - - -class FusionAccessibilityAssessment(models.Model): - _name = 'fusion.accessibility.assessment' - _description = 'Accessibility Assessment' - _inherit = ['mail.thread', 'mail.activity.mixin', 'fusion.email.builder.mixin'] - _order = 'assessment_date desc, id desc' - _rec_name = 'display_name' - - # ========================================================================== - # COMMON FIELDS (all assessment types) - # ========================================================================== - reference = fields.Char( - string='Reference', - readonly=True, - copy=False, - default=lambda self: _('New'), - ) - - display_name = fields.Char( - compute='_compute_display_name', - store=True, - ) - - assessment_type = fields.Selection( - selection=[ - ('stairlift_straight', 'Straight Stair Lift'), - ('stairlift_curved', 'Curved Stair Lift'), - ('vpl', 'Vertical Platform Lift'), - ('ceiling_lift', 'Ceiling Lift'), - ('ramp', 'Custom Ramp'), - ('bathroom', 'Bathroom Modification'), - ('tub_cutout', 'Tub Cutout'), - ], - string='Assessment Type', - required=True, - tracking=True, - ) - - state = fields.Selection( - selection=[ - ('draft', 'Draft'), - ('completed', 'Completed'), - ('cancelled', 'Cancelled'), - ], - string='Status', - default='draft', - tracking=True, - ) - - # Client Information - client_name = fields.Char(string='Client Name', required=True) - client_address = fields.Char(string='Address') - client_unit = fields.Char(string='Unit/Apt/Suite') - client_address_street = fields.Char(string='Street') - client_address_city = fields.Char(string='City') - client_address_province = fields.Char(string='Province') - client_address_postal = fields.Char(string='Postal Code') - client_phone = fields.Char(string='Phone') - client_email = fields.Char(string='Email') - - # Booking fields - booking_source = fields.Selection( - selection=[ - ('phone_authorizer', 'Phone - Authorizer'), - ('phone_client', 'Phone - Client'), - ('walk_in', 'Walk-In'), - ('portal', 'Online Booking'), - ], - string='Booking Source', - default='phone_client', - help='How the assessment was booked', - ) - modification_requested = fields.Text( - string='Modification Requested', - help='What the client or authorizer is looking for', - ) - sms_confirmation_sent = fields.Boolean( - string='SMS Confirmation Sent', - default=False, - ) - calendar_event_id = fields.Many2one( - 'calendar.event', - string='Calendar Event', - readonly=True, - copy=False, - ) - - # Relationships - sales_rep_id = fields.Many2one( - 'res.users', - string='Sales Rep', - default=lambda self: self.env.user, - tracking=True, - ) - authorizer_id = fields.Many2one( - 'res.partner', - string='Authorizer/OT', - tracking=True, - help='The Occupational Therapist or Authorizer for this assessment', - ) - partner_id = fields.Many2one( - 'res.partner', - string='Client Partner', - help='Linked partner record (created on completion)', - ) - sale_order_id = fields.Many2one( - 'sale.order', - string='Created Sale Order', - readonly=True, - copy=False, - ) - - # Dates - assessment_date = fields.Date( - string='Assessment Date', - default=fields.Date.today, - ) - - # General Notes - notes = fields.Text(string='General Notes') - - # ========================================================================== - # STAIR LIFT - STRAIGHT FIELDS - # ========================================================================== - stair_steps = fields.Integer(string='Number of Steps') - stair_nose_to_nose = fields.Float(string='Nose to Nose Distance (inches)') - stair_side = fields.Selection( - selection=[('left', 'Left'), ('right', 'Right')], - string='Installation Side', - ) - stair_style = fields.Selection( - selection=[ - ('standard', 'Standard Stair Lift'), - ('slide_track', 'Slide Track Stair Lift'), - ('foldable_hinge', 'Foldable Hinge Stair Lift'), - ], - string='Stair Lift Style', - ) - stair_power_swivel_upstairs = fields.Boolean(string='Power Swivel (Upstairs)') - stair_power_folding_footrest = fields.Boolean(string='Power Folding Footrest') - stair_calculated_length = fields.Float( - string='Calculated Track Length (inches)', - compute='_compute_stair_straight_length', - store=True, - ) - stair_manual_length_override = fields.Float(string='Manual Length Override (inches)') - stair_final_length = fields.Float( - string='Final Track Length (inches)', - compute='_compute_stair_final_length', - store=True, - ) - - # ========================================================================== - # STAIR LIFT - CURVED FIELDS - # ========================================================================== - stair_curved_steps = fields.Integer(string='Number of Steps (Curved)') - stair_curves_count = fields.Integer(string='Number of Curves') - - # Top Landing Options - stair_top_landing_type = fields.Selection( - selection=[ - ('none', 'Standard (No special landing)'), - ('90_exit', '90° Exit'), - ('90_parking', '90° Parking'), - ('180_parking', '180° Parking'), - ('flush_landing', 'Flush Landing'), - ('vertical_overrun', 'Vertical Overrun (Custom)'), - ], - string='Top Landing Type', - default='none', - help='Type of landing at the top of the staircase', - ) - top_overrun_custom_length = fields.Float( - string='Top Overrun Length (inches)', - help='Custom overrun length when Vertical Overrun is selected', - ) - - # Bottom Landing Options - stair_bottom_landing_type = fields.Selection( - selection=[ - ('none', 'Standard (No special landing)'), - ('90_park', '90° Park'), - ('180_park', '180° Park'), - ('drop_nose', 'Drop Nose Landing'), - ('short_vertical', 'Short Vertical Start'), - ('horizontal_overrun', 'Horizontal Overrun (Custom)'), - ], - string='Bottom Landing Type', - default='none', - help='Type of landing at the bottom of the staircase', - ) - bottom_overrun_custom_length = fields.Float( - string='Bottom Overrun Length (inches)', - help='Custom overrun length when Horizontal Overrun is selected', - ) - - # Legacy fields kept for backwards compatibility - stair_has_drop_nose = fields.Boolean(string='Has Drop Nose (Legacy)') - stair_parking_type = fields.Selection( - selection=[ - ('none', 'No Parking'), - ('90_degree', '90° Parking (+2 feet)'), - ('180_degree', '180° Parking (+4 feet)'), - ], - string='Parking Type (Legacy)', - default='none', - ) - stair_power_swivel_downstairs = fields.Boolean(string='Power Swivel (Downstairs)') - stair_auto_folding_footrest = fields.Boolean(string='Automatic Folding Footrest') - stair_auto_folding_hinge = fields.Boolean(string='Automatic Folding Hinge') - stair_auto_folding_seat = fields.Boolean(string='Automatic Folding Seat') - stair_custom_color = fields.Boolean(string='Customizable Colored Seat') - stair_additional_charging = fields.Boolean(string='Additional Charging Station') - stair_charging_with_remote = fields.Boolean(string='Charging Station with Remote') - stair_curved_calculated_length = fields.Float( - string='Calculated Track Length (inches)', - compute='_compute_stair_curved_length', - store=True, - ) - stair_curved_manual_override = fields.Float(string='Manual Length Override (inches)') - stair_curved_final_length = fields.Float( - string='Final Track Length (inches)', - compute='_compute_stair_curved_final_length', - store=True, - ) - - # ========================================================================== - # VERTICAL PLATFORM LIFT (VPL) FIELDS - # ========================================================================== - vpl_room_width = fields.Float(string='Room Width (inches)') - vpl_room_depth = fields.Float(string='Room Depth (inches)') - vpl_rise_height = fields.Float(string='Total Rise Height (inches)') - vpl_has_existing_platform = fields.Boolean(string='Existing Platform Available') - vpl_concrete_depth = fields.Float(string='Concrete Depth (inches)', help='Minimum 4 inches required') - vpl_model_type = fields.Selection( - selection=[ - ('ac', 'AC Model (Dedicated 15-amp breaker required)'), - ('dc', 'DC Model (No dedicated breaker required)'), - ], - string='Model Type', - ) - vpl_has_nearby_plug = fields.Boolean(string='Power Plug Nearby') - vpl_plug_specs = fields.Char(string='Plug Specifications', default='110V / 15-amp') - vpl_needs_plug_install = fields.Boolean(string='Needs Plug Installation') - vpl_needs_certification = fields.Boolean(string='Needs City Certification') - vpl_certification_notes = fields.Text(string='Certification Notes') - - # ========================================================================== - # CEILING LIFT FIELDS - # ========================================================================== - ceiling_track_length = fields.Float(string='Total Track Length (feet)') - ceiling_movement_type = fields.Selection( - selection=[ - ('manual', 'Manual Movement (left-to-right)'), - ('powered', 'Powered Movement (left-to-right)'), - ], - string='Horizontal Movement Type', - help='All ceiling lifts move up/down with power. This is for left-to-right movement.', - ) - ceiling_charging_throughout = fields.Boolean( - string='Charging Throughout Track', - help='Charging available throughout the track instead of one location', - ) - ceiling_carry_bar = fields.Boolean(string='Carry Bar') - ceiling_additional_slings = fields.Integer(string='Additional Slings Needed') - - # ========================================================================== - # CUSTOM RAMP FIELDS - # ========================================================================== - ramp_height = fields.Float(string='Total Height (inches from ground)') - ramp_ground_incline = fields.Float(string='Ground Incline (degrees)', help='Optional - if ground is inclined') - ramp_at_door = fields.Boolean(string='Ramp at Door', help='Requires 5ft landing at door') - ramp_calculated_length = fields.Float( - string='Calculated Ramp Length (inches)', - compute='_compute_ramp_length', - store=True, - help='Ontario Building Code: 12 inches length per 1 inch height', - ) - ramp_landings_needed = fields.Integer( - string='Landings Needed', - compute='_compute_ramp_landings', - store=True, - help='Landing required every 30 feet (minimum 5 feet each)', - ) - ramp_total_length = fields.Float( - string='Total Length with Landings (inches)', - compute='_compute_ramp_total_length', - store=True, - ) - ramp_handrail_height = fields.Float( - string='Handrail Height (inches)', - default=32.0, - help='Minimum 32 inches required', - ) - ramp_manual_override = fields.Float(string='Manual Length Override (inches)') - - # ========================================================================== - # BATHROOM MODIFICATION FIELDS - # ========================================================================== - bathroom_description = fields.Text( - string='Modification Description', - help='Describe all bathroom modifications needed', - ) - - # ========================================================================== - # TUB CUTOUT FIELDS - # ========================================================================== - tub_internal_height = fields.Float(string='Internal Height of Tub (inches)') - tub_external_height = fields.Float(string='External Height of Tub (inches)') - tub_additional_supplies = fields.Text(string='Additional Supplies Needed') - - # ========================================================================== - # COMPUTED FIELDS - # ========================================================================== - - @api.depends('reference', 'assessment_type', 'client_name') - def _compute_display_name(self): - type_labels = dict(self._fields['assessment_type'].selection) - for rec in self: - type_label = type_labels.get(rec.assessment_type, '') - rec.display_name = f"{rec.reference or 'New'} - {type_label} - {rec.client_name or ''}" - - @api.depends('stair_steps', 'stair_nose_to_nose') - def _compute_stair_straight_length(self): - """Straight stair lift: (steps × nose_to_nose) + 13" top landing""" - for rec in self: - if rec.stair_steps and rec.stair_nose_to_nose: - rec.stair_calculated_length = (rec.stair_steps * rec.stair_nose_to_nose) + 13 - else: - rec.stair_calculated_length = 0 - - @api.depends('stair_calculated_length', 'stair_manual_length_override') - def _compute_stair_final_length(self): - """Use manual override if provided, otherwise use calculated""" - for rec in self: - if rec.stair_manual_length_override: - rec.stair_final_length = rec.stair_manual_length_override - else: - rec.stair_final_length = rec.stair_calculated_length - - @api.depends('stair_curved_steps', 'stair_curves_count', - 'stair_top_landing_type', 'stair_bottom_landing_type', - 'top_overrun_custom_length', 'bottom_overrun_custom_length') - def _compute_stair_curved_length(self): - """Curved stair lift calculation: - - 12" per step - - 16" per curve - - Top landing type additions (or custom overrun) - - Bottom landing type additions (or custom overrun) - """ - # Track length additions for each landing type (in inches) - # Note: vertical_overrun and horizontal_overrun use custom lengths - TOP_LANDING_LENGTHS = { - 'none': 0, - '90_exit': 24, # 2 feet - '90_parking': 24, # 2 feet - '180_parking': 48, # 4 feet - 'flush_landing': 12, # 1 foot - } - - BOTTOM_LANDING_LENGTHS = { - 'none': 0, - '90_park': 24, # 2 feet - '180_park': 48, # 4 feet - 'drop_nose': 12, # 1 foot - 'short_vertical': 12, # 1 foot - } - - for rec in self: - if rec.stair_curved_steps: - base_length = rec.stair_curved_steps * 12 # 12" per step - curves_length = (rec.stair_curves_count or 0) * 16 # 16" per curve - - # Top landing length - use custom if overrun selected - if rec.stair_top_landing_type == 'vertical_overrun': - top_landing = rec.top_overrun_custom_length or 0 - else: - top_landing = TOP_LANDING_LENGTHS.get(rec.stair_top_landing_type or 'none', 0) - - # Bottom landing length - use custom if overrun selected - if rec.stair_bottom_landing_type == 'horizontal_overrun': - bottom_landing = rec.bottom_overrun_custom_length or 0 - else: - bottom_landing = BOTTOM_LANDING_LENGTHS.get(rec.stair_bottom_landing_type or 'none', 0) - - rec.stair_curved_calculated_length = ( - base_length + curves_length + top_landing + bottom_landing - ) - else: - rec.stair_curved_calculated_length = 0 - - @api.depends('stair_curved_calculated_length', 'stair_curved_manual_override') - def _compute_stair_curved_final_length(self): - """Use manual override if provided, otherwise use calculated""" - for rec in self: - if rec.stair_curved_manual_override: - rec.stair_curved_final_length = rec.stair_curved_manual_override - else: - rec.stair_curved_final_length = rec.stair_curved_calculated_length - - @api.depends('ramp_height') - def _compute_ramp_length(self): - """Ontario Building Code: 12 inches length per 1 inch height (1:12 ratio)""" - for rec in self: - if rec.ramp_height: - rec.ramp_calculated_length = rec.ramp_height * 12 - else: - rec.ramp_calculated_length = 0 - - @api.depends('ramp_calculated_length') - def _compute_ramp_landings(self): - """Landing required every 30 feet (360 inches)""" - for rec in self: - if rec.ramp_calculated_length: - # Calculate how many landings are needed (every 30 feet = 360 inches) - rec.ramp_landings_needed = math.ceil(rec.ramp_calculated_length / 360) - else: - rec.ramp_landings_needed = 0 - - @api.depends('ramp_calculated_length', 'ramp_landings_needed', 'ramp_at_door') - def _compute_ramp_total_length(self): - """Total length including landings (5 feet = 60 inches each)""" - for rec in self: - base_length = rec.ramp_calculated_length or 0 - landings_length = (rec.ramp_landings_needed or 0) * 60 # 5 feet per landing - door_landing = 60 if rec.ramp_at_door else 0 # 5 feet at door - rec.ramp_total_length = base_length + landings_length + door_landing - - # ========================================================================== - # CRUD METHODS - # ========================================================================== - - @api.model_create_multi - def create(self, vals_list): - for vals in vals_list: - if vals.get('reference', _('New')) == _('New'): - vals['reference'] = self.env['ir.sequence'].next_by_code( - 'fusion.accessibility.assessment' - ) or _('New') - return super().create(vals_list) - - # ========================================================================== - # BUSINESS LOGIC - # ========================================================================== - - def action_complete(self): - """Complete the assessment and create a Sale Order""" - self.ensure_one() - - if not self.client_name: - raise UserError(_('Please enter the client name.')) - - # Create or find partner - partner = self._ensure_partner() - - # Create draft sale order - sale_order = self._create_draft_sale_order(partner) - - # Add tag based on assessment type - self._add_assessment_tag(sale_order) - - # Copy photos from assessment to sale order chatter - self._copy_photos_to_sale_order(sale_order) - - # Update state - self.write({ - 'state': 'completed', - 'sale_order_id': sale_order.id, - 'partner_id': partner.id, - }) - - # Send email notification to office - self._send_completion_email(sale_order) - - # Schedule follow-up activity for sales rep - self._schedule_followup_activity(sale_order) - - _logger.info(f"Completed accessibility assessment {self.reference}, created SO {sale_order.name}") - - return sale_order - - def _add_assessment_tag(self, sale_order): - """Add a tag to the sale order based on assessment type""" - self.ensure_one() - - # Map assessment types to tag names (ALL CAPS) - tag_map = { - 'stairlift_straight': 'STRAIGHT STAIR LIFT', - 'stairlift_curved': 'CURVED STAIR LIFT', - 'vpl': 'VERTICAL PLATFORM LIFT', - 'ceiling_lift': 'CEILING LIFT', - 'ramp': 'CUSTOM RAMP', - 'bathroom': 'BATHROOM MODIFICATION', - 'tub_cutout': 'TUB CUTOUT', - } - - tag_name = tag_map.get(self.assessment_type) - if not tag_name: - return - - # Find or create the tag - Tag = self.env['crm.tag'].sudo() - tag = Tag.search([('name', '=', tag_name)], limit=1) - if not tag: - tag = Tag.create({'name': tag_name}) - _logger.info(f"Created new tag: {tag_name}") - - # Add tag to sale order - if hasattr(sale_order, 'tag_ids'): - sale_order.write({'tag_ids': [(4, tag.id)]}) - _logger.info(f"Added tag '{tag_name}' to SO {sale_order.name}") - - def _copy_photos_to_sale_order(self, sale_order): - """Copy assessment photos to sale order chatter""" - self.ensure_one() - - Attachment = self.env['ir.attachment'].sudo() - - # Find photos attached to this assessment - photos = Attachment.search([ - ('res_model', '=', 'fusion.accessibility.assessment'), - ('res_id', '=', self.id), - ('mimetype', 'like', 'image/%'), - ]) - - if not photos: - return - - # Copy attachments to sale order and post in chatter - attachment_ids = [] - for photo in photos: - new_attachment = photo.copy({ - 'res_model': 'sale.order', - 'res_id': sale_order.id, - }) - attachment_ids.append(new_attachment.id) - - if attachment_ids: - type_labels = dict(self._fields['assessment_type'].selection) - type_label = type_labels.get(self.assessment_type, 'Accessibility') - - sale_order.message_post( - body=Markup(f''' -
- Assessment Photos
- {len(attachment_ids)} photo(s) from {type_label} Assessment ({self.reference}) -
- '''), - message_type='comment', - subtype_xmlid='mail.mt_note', - attachment_ids=attachment_ids, - ) - _logger.info(f"Copied {len(attachment_ids)} photos to SO {sale_order.name}") - - def _send_completion_email(self, sale_order): - """Send email notification to office about assessment completion""" - self.ensure_one() - - ICP = self.env['ir.config_parameter'].sudo() - - # Check if email notifications are enabled - if not ICP.get_param('fusion_claims.enable_email_notifications', 'True') == 'True': - return - - # Get office notification emails from company - company = self.env.company - office_partners = company.sudo().x_fc_office_notification_ids - email_list = [p.email for p in office_partners if p.email] - office_emails = ', '.join(email_list) - - if not office_emails: - _logger.warning("No office notification recipients configured for accessibility assessment completion") - return - - type_labels = dict(self._fields['assessment_type'].selection) - type_label = type_labels.get(self.assessment_type, 'Accessibility') - - body = self._email_build( - title='Accessibility Assessment Completed', - summary=f'A new {type_label.lower()} assessment has been completed for ' - f'{self.client_name}. A sale order has been created.', - email_type='info', - sections=[('Assessment Details', [ - ('Type', type_label), - ('Reference', self.reference), - ('Client', self.client_name), - ('Sales Rep', self.sales_rep_id.name if self.sales_rep_id else 'N/A'), - ('Sale Order', sale_order.name), - ])], - button_url=f'{sale_order.get_base_url()}/web#id={sale_order.id}&model=sale.order&view_type=form', - button_text='View Sale Order', - ) - - # Send email - mail_values = { - 'subject': f'Accessibility Assessment Completed: {type_label} - {self.client_name}', - 'body_html': body, - 'email_to': office_emails, - 'email_from': self.env.company.email or 'noreply@example.com', - } - - try: - mail = self.env['mail.mail'].sudo().create(mail_values) - mail.send() - _logger.info(f"Sent accessibility assessment completion email to {office_emails}") - except Exception as e: - _logger.error(f"Failed to send assessment completion email: {e}") - - def _schedule_followup_activity(self, sale_order): - """Schedule a follow-up activity for the sales rep""" - self.ensure_one() - - if not self.sales_rep_id: - return - - type_labels = dict(self._fields['assessment_type'].selection) - type_label = type_labels.get(self.assessment_type, 'Accessibility') - - # Get the "To Do" activity type - activity_type = self.env.ref('mail.mail_activity_data_todo', raise_if_not_found=False) - if not activity_type: - _logger.warning("Could not find 'To Do' activity type") - return - - # Schedule activity for tomorrow - due_date = fields.Date.today() + timedelta(days=1) - - try: - sale_order.activity_schedule( - activity_type_id=activity_type.id, - date_deadline=due_date, - user_id=self.sales_rep_id.id, - summary=f'Follow up on {type_label} Assessment', - note=f'Assessment {self.reference} for {self.client_name} has been completed. Please follow up with the client.', - ) - _logger.info(f"Scheduled follow-up activity for {self.sales_rep_id.name} on SO {sale_order.name}") - except Exception as e: - _logger.error(f"Failed to schedule follow-up activity: {e}") - - def _ensure_partner(self): - """Find or create a partner for the client""" - self.ensure_one() - Partner = self.env['res.partner'].sudo() - - # First, try to find existing partner by email - if self.client_email: - existing = Partner.search([('email', '=ilike', self.client_email)], limit=1) - if existing: - return existing - - # Create new partner - partner_vals = { - 'name': self.client_name, - 'email': self.client_email, - 'phone': self.client_phone, - 'street': self.client_address_street or self.client_address, - 'street2': self.client_unit or False, - 'city': self.client_address_city, - 'zip': self.client_address_postal, - 'customer_rank': 1, - } - - # Set province/state if provided - if self.client_address_province: - state = self.env['res.country.state'].sudo().search([ - ('code', '=ilike', self.client_address_province), - ('country_id.code', '=', 'CA'), - ], limit=1) - if state: - partner_vals['state_id'] = state.id - partner_vals['country_id'] = state.country_id.id - else: - # Default to Canada - canada = self.env.ref('base.ca', raise_if_not_found=False) - if canada: - partner_vals['country_id'] = canada.id - - partner = Partner.create(partner_vals) - _logger.info(f"Created partner {partner.name} from accessibility assessment {self.reference}") - return partner - - def _create_draft_sale_order(self, partner): - """Create a draft sale order from the assessment""" - self.ensure_one() - - SaleOrder = self.env['sale.order'].sudo() - - type_labels = dict(self._fields['assessment_type'].selection) - type_label = type_labels.get(self.assessment_type, 'Accessibility') - - so_vals = { - 'partner_id': partner.id, - 'user_id': self.sales_rep_id.id if self.sales_rep_id else self.env.user.id, - 'state': 'draft', - 'origin': f'Accessibility: {self.reference} ({type_label})', - 'x_fc_sale_type': 'direct_private', # Accessibility items typically private pay - } - - sale_order = SaleOrder.create(so_vals) - _logger.info(f"Created draft sale order {sale_order.name} from accessibility assessment {self.reference}") - - # Post assessment details to chatter - assessment_html = self._format_assessment_html_table() - sale_order.message_post( - body=Markup(assessment_html), - message_type='comment', - subtype_xmlid='mail.mt_note', - ) - - return sale_order - - def _format_assessment_html_table(self): - """Format assessment details as HTML for chatter""" - type_labels = dict(self._fields['assessment_type'].selection) - type_label = type_labels.get(self.assessment_type, 'Unknown') - - html = f''' - ' - return html - - def action_cancel(self): - """Cancel the assessment""" - self.ensure_one() - self.write({'state': 'cancelled'}) - - def action_reset_to_draft(self): - """Reset to draft state""" - self.ensure_one() - self.write({'state': 'draft'}) diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/models/adp_document.py b/fusion_authorizer_portal/fusion_authorizer_portal/models/adp_document.py deleted file mode 100644 index 9108fd8..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/models/adp_document.py +++ /dev/null @@ -1,183 +0,0 @@ -# -*- coding: utf-8 -*- - -from odoo import api, fields, models, _ -from odoo.exceptions import UserError -import base64 -import logging - -_logger = logging.getLogger(__name__) - - -class ADPDocument(models.Model): - _name = 'fusion.adp.document' - _description = 'ADP Application Document' - _order = 'upload_date desc, revision desc' - _rec_name = 'display_name' - - # Relationships - sale_order_id = fields.Many2one( - 'sale.order', - string='Sale Order', - ondelete='cascade', - index=True, - ) - - assessment_id = fields.Many2one( - 'fusion.assessment', - string='Assessment', - ondelete='cascade', - index=True, - ) - - # Document Type - document_type = fields.Selection([ - ('full_application', 'Full ADP Application (14 pages)'), - ('pages_11_12', 'Pages 11 & 12 (Signature Pages)'), - ('page_11', 'Page 11 Only (Authorizer Signature)'), - ('page_12', 'Page 12 Only (Client Signature)'), - ('submitted_final', 'Final Submitted Application'), - ('assessment_report', 'Assessment Report'), - ('assessment_signed', 'Signed Pages from Assessment'), - ('other', 'Other Document'), - ], string='Document Type', required=True, default='full_application') - - # File Data - file = fields.Binary( - string='File', - required=True, - attachment=True, - ) - - filename = fields.Char( - string='Filename', - required=True, - ) - - file_size = fields.Integer( - string='File Size (bytes)', - compute='_compute_file_size', - store=True, - ) - - mimetype = fields.Char( - string='MIME Type', - default='application/pdf', - ) - - # Revision Tracking - revision = fields.Integer( - string='Revision', - default=1, - readonly=True, - ) - - revision_note = fields.Text( - string='Revision Note', - help='Notes about what changed in this revision', - ) - - is_current = fields.Boolean( - string='Is Current Version', - default=True, - index=True, - ) - - # Upload Information - uploaded_by = fields.Many2one( - 'res.users', - string='Uploaded By', - default=lambda self: self.env.user, - readonly=True, - ) - - upload_date = fields.Datetime( - string='Upload Date', - default=fields.Datetime.now, - readonly=True, - ) - - source = fields.Selection([ - ('authorizer', 'Authorizer Portal'), - ('sales_rep', 'Sales Rep Portal'), - ('internal', 'Internal User'), - ('assessment', 'Assessment Form'), - ], string='Source', default='internal') - - # Display - display_name = fields.Char( - string='Display Name', - compute='_compute_display_name', - store=True, - ) - - @api.depends('file') - def _compute_file_size(self): - for doc in self: - if doc.file: - doc.file_size = len(base64.b64decode(doc.file)) - else: - doc.file_size = 0 - - @api.depends('document_type', 'filename', 'revision') - def _compute_display_name(self): - type_labels = dict(self._fields['document_type'].selection) - for doc in self: - type_label = type_labels.get(doc.document_type, doc.document_type) - doc.display_name = f"{type_label} - v{doc.revision} ({doc.filename or 'No file'})" - - @api.model_create_multi - def create(self, vals_list): - """Override create to handle revision numbering""" - for vals in vals_list: - # Find existing documents of the same type for the same order/assessment - domain = [('document_type', '=', vals.get('document_type'))] - - if vals.get('sale_order_id'): - domain.append(('sale_order_id', '=', vals.get('sale_order_id'))) - if vals.get('assessment_id'): - domain.append(('assessment_id', '=', vals.get('assessment_id'))) - - existing = self.search(domain, order='revision desc', limit=1) - - if existing: - # Mark existing as not current and increment revision - existing.is_current = False - vals['revision'] = existing.revision + 1 - else: - vals['revision'] = 1 - - vals['is_current'] = True - - return super().create(vals_list) - - def action_download(self): - """Download the document""" - self.ensure_one() - return { - 'type': 'ir.actions.act_url', - 'url': f'/web/content/{self._name}/{self.id}/file/{self.filename}?download=true', - 'target': 'self', - } - - def get_document_url(self): - """Get the download URL for portal access""" - self.ensure_one() - return f'/my/authorizer/document/{self.id}/download' - - @api.model - def get_documents_for_order(self, sale_order_id, document_type=None, current_only=True): - """Get documents for a sale order, optionally filtered by type""" - domain = [('sale_order_id', '=', sale_order_id)] - if document_type: - domain.append(('document_type', '=', document_type)) - if current_only: - domain.append(('is_current', '=', True)) - return self.search(domain, order='document_type, revision desc') - - @api.model - def get_revision_history(self, sale_order_id, document_type): - """Get all revisions of a specific document type""" - return self.search([ - ('sale_order_id', '=', sale_order_id), - ('document_type', '=', document_type), - ], order='revision desc') diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/models/assessment.py b/fusion_authorizer_portal/fusion_authorizer_portal/models/assessment.py deleted file mode 100644 index be76e66..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/models/assessment.py +++ /dev/null @@ -1,1633 +0,0 @@ -# -*- coding: utf-8 -*- - -from odoo import api, fields, models, _ -from odoo.exceptions import UserError, ValidationError -from markupsafe import Markup -from datetime import datetime, timedelta -import base64 -import json -import logging - -_logger = logging.getLogger(__name__) - - -class FusionAssessment(models.Model): - _name = 'fusion.assessment' - _description = 'ADP Assessment' - _inherit = ['mail.thread', 'mail.activity.mixin', 'fusion.email.builder.mixin'] - _order = 'assessment_date desc, id desc' - _rec_name = 'display_name' - - # Status - state = fields.Selection([ - ('draft', 'In Progress'), - ('pending_signature', 'Pending Signatures'), - ('completed', 'Completed'), - ('cancelled', 'Cancelled'), - ], string='Status', default='draft', tracking=True, index=True) - - display_name = fields.Char( - string='Display Name', - compute='_compute_display_name', - store=True, - ) - - # Reference - reference = fields.Char( - string='Reference', - readonly=True, - copy=False, - default=lambda self: _('New'), - ) - - # ===== EXPRESS FORM: EQUIPMENT TYPE ===== - equipment_type = fields.Selection([ - ('rollator', 'Rollator'), - ('wheelchair', 'Wheelchair'), - ('powerchair', 'Powerchair'), - ], string='Equipment Type', tracking=True, index=True) - - # Rollator Types - rollator_type = fields.Selection([ - ('type_1', 'Type 1'), - ('type_2', 'Type 2'), - ('type_3', 'Type 3'), - ], string='Rollator Type') - - # Wheelchair Types (Adult Manual) - wheelchair_type = fields.Selection([ - ('type_1', 'Type 1 - Adult Manual Standard Wheelchair'), - ('type_2', 'Type 2 - Adult Manual Lightweight Wheelchair'), - ('type_3', 'Type 3 - Adult Manual Ultra Lightweight Wheelchair'), - ('type_4', 'Type 4 - Adult Manual Tilt Wheelchair'), - ('type_5', 'Type 5 - Adult Manual Dynamic Tilt Wheelchair'), - ], string='Wheelchair Type') - - # Powerchair Types - powerchair_type = fields.Selection([ - ('type_1', 'Adult Power Base Type 1'), - ('type_2', 'Adult Power Base Type 2'), - ('type_3', 'Adult Power Base Type 3'), - ], string='Powerchair Type') - - # ===== EXPRESS FORM: ROLLATOR MEASUREMENTS ===== - rollator_handle_height = fields.Float(string='Handle Height (inches)', digits=(10, 2)) - rollator_seat_height = fields.Float(string='Seat Height (inches)', digits=(10, 2)) - - # ===== EXPRESS FORM: ROLLATOR ADDONS ===== - rollator_addons = fields.Text( - string='Rollator Addons', - help='Comma-separated list of selected rollator addons', - ) - - # ===== EXPRESS FORM: WHEELCHAIR/POWERCHAIR MEASUREMENTS ===== - legrest_length = fields.Float(string='Legrest Length (inches)', digits=(10, 2)) - cane_height = fields.Float(string='Cane Height (inches)', digits=(10, 2), help='Ground to Canes') - - # ===== EXPRESS FORM: WHEELCHAIR OPTIONS ===== - frame_options = fields.Text( - string='Frame Options', - help='Comma-separated list: Recliner Option, Dynamic Tilt Frame, Titanium Frame', - ) - - wheel_options = fields.Text( - string='Wheel Options/Addons', - help='Comma-separated list of wheel options', - ) - - legrest_options = fields.Text( - string='Legrest Accessories', - help='Comma-separated list of legrest accessories', - ) - - additional_adp_options = fields.Text( - string='Additional ADP Funded Options', - help='Comma-separated list of additional ADP options', - ) - - seatbelt_type = fields.Selection([ - ('standard', 'Standard Belt - No Padding'), - ('padded', 'Padded Belt - Positioning Belts (Modular)'), - ('4point', '4 Point Seat Belt - Positioning Belts (Modular)'), - ('chest_harness', 'Chest Harness - Positioning Belts (Modular)'), - ('additional_pads', 'Additional Pads - Positioning Belts (Custom)'), - ], string='Seat Belt Type') - - # ===== EXPRESS FORM: POWERCHAIR OPTIONS ===== - powerchair_options = fields.Text( - string='Powerchair Additional Options', - help='Comma-separated list of powerchair additional ADP options', - ) - - specialty_controls = fields.Text( - string='Specialty Components', - help='Comma-separated list of specialty controls (rationale required)', - ) - - # ===== EXPRESS FORM: ADDITIONAL INFO ===== - additional_customization = fields.Text( - string='Additional Information/Customization', - help='Free-form notes for customization requirements', - ) - - cushion_info = fields.Char( - string='Cushion', - help='Cushion details for wheelchair/powerchair', - ) - - backrest_info = fields.Char( - string='Backrest', - help='Backrest details for wheelchair/powerchair', - ) - - # ===== EXPRESS FORM: KEY DATES (map to SO x_fc_ fields) ===== - assessment_start_date = fields.Date( - string='Assessment Start Date', - tracking=True, - ) - assessment_end_date = fields.Date( - string='Assessment End Date', - tracking=True, - ) - claim_authorization_date = fields.Date( - string='Claim Authorization Date', - tracking=True, - ) - - # ===== EXPRESS FORM: CLIENT TYPE ===== - client_type = fields.Selection([ - ('reg', 'REG - Regular ADP'), - ('ods', 'ODS - ODSP'), - ('acs', 'ACS - ACSD'), - ('owp', 'OWP - Ontario Works'), - ], string='Client Type', default='reg', - help='REG = ADP only, ODS/ACS/OWP = ADP + ODSP') - - # ===== EXPRESS FORM: REASON FOR APPLICATION ===== - reason_for_application = fields.Selection([ - ('first_access', 'First Time Access - NO previous ADP'), - ('additions', 'Additions'), - ('mod_non_adp', 'Modification/Upgrade - Original NOT through ADP'), - ('mod_adp', 'Modification/Upgrade - Original through ADP'), - ('replace_status', 'Replacement - Change in Status'), - ('replace_size', 'Replacement - Change in Body Size'), - ('replace_worn', 'Replacement - Worn out (past useful life)'), - ('replace_lost', 'Replacement - Lost'), - ('replace_stolen', 'Replacement - Stolen'), - ('replace_damaged', 'Replacement - Damaged beyond repair'), - ('replace_no_longer_meets', 'Replacement - No longer meets needs'), - ('growth', 'Growth/Change in condition'), - ], string='Reason for Application') - - previous_funding_date = fields.Date( - string='Previous Funding Date', - help='Date of previous ADP funding (for replacements)', - ) - - # ===== EXPRESS FORM: CLIENT BIOGRAPHIC (enhanced) ===== - client_middle_name = fields.Char(string='Middle Name') - client_health_card_version = fields.Char(string='Health Card Version', help='Version code on health card') - - # ===== CLIENT INFORMATION ===== - client_name = fields.Char( - string='Client Name', - required=True, - tracking=True, - ) - client_first_name = fields.Char(string='First Name') - client_last_name = fields.Char(string='Last Name') - - client_address = fields.Text(string='Address') - client_street = fields.Char(string='Street') - client_unit = fields.Char(string='Unit/Apt/Suite') - client_city = fields.Char(string='City') - client_state = fields.Char(string='Province/State', default='Ontario') - client_postal_code = fields.Char(string='Postal Code') - client_country_id = fields.Many2one('res.country', string='Country', default=lambda self: self.env.ref('base.ca', raise_if_not_found=False)) - - client_phone = fields.Char(string='Phone') - client_mobile = fields.Char(string='Mobile') - client_email = fields.Char(string='Email') - - client_dob = fields.Date(string='Date of Birth') - client_health_card = fields.Char(string='Health Card Number') - - # Link to existing partner or create new - partner_id = fields.Many2one( - 'res.partner', - string='Client Partner', - help='Link to existing customer record', - ) - create_new_partner = fields.Boolean( - string='Create New Client', - default=True, - help='If checked, a new customer record will be created on completion', - ) - - # Client References (for searchability) - client_reference_1 = fields.Char(string='Client Reference 1') - client_reference_2 = fields.Char(string='Client Reference 2') - - # ===== ASSESSMENT PARTICIPANTS ===== - sales_rep_id = fields.Many2one( - 'res.users', - string='Sales Rep', - default=lambda self: self.env.user, - tracking=True, - ) - - authorizer_id = fields.Many2one( - 'res.partner', - string='Authorizer/OT', - tracking=True, - help='The Occupational Therapist or Authorizer conducting the assessment', - ) - - # ===== ASSESSMENT DATE/LOCATION ===== - assessment_date = fields.Datetime( - string='Assessment Date', - default=fields.Datetime.now, - required=True, - tracking=True, - ) - - assessment_location = fields.Selection([ - ('home', 'Client Home'), - ('clinic', 'Clinic/Office'), - ('hospital', 'Hospital'), - ('ltc', 'Long Term Care'), - ('other', 'Other'), - ], string='Location Type', default='home') - - assessment_location_notes = fields.Text(string='Location Notes') - - # ===== WHEELCHAIR SPECIFICATIONS ===== - # Measurements (in inches) - seat_width = fields.Float(string='Seat Width (inches)', digits=(10, 2)) - seat_depth = fields.Float(string='Seat Depth (inches)', digits=(10, 2)) - seat_to_floor_height = fields.Float(string='Seat to Floor Height (inches)', digits=(10, 2)) - back_height = fields.Float(string='Back Height (inches)', digits=(10, 2)) - armrest_height = fields.Float(string='Armrest Height (inches)', digits=(10, 2)) - footrest_length = fields.Float(string='Footrest Length (inches)', digits=(10, 2)) - - # Additional Measurements - overall_width = fields.Float(string='Overall Width (inches)', digits=(10, 2)) - overall_length = fields.Float(string='Overall Length (inches)', digits=(10, 2)) - overall_height = fields.Float(string='Overall Height (inches)', digits=(10, 2)) - seat_angle = fields.Float(string='Seat Angle (degrees)', digits=(10, 1)) - back_angle = fields.Float(string='Back Angle (degrees)', digits=(10, 1)) - - # Client Measurements - client_weight = fields.Float(string='Client Weight (lbs)', digits=(10, 1)) - client_height = fields.Float(string='Client Height (inches)', digits=(10, 1)) - - # ===== PRODUCT TYPES ===== - cushion_type = fields.Selection([ - ('foam', 'Foam'), - ('gel', 'Gel'), - ('air', 'Air'), - ('hybrid', 'Hybrid'), - ('custom', 'Custom Molded'), - ('other', 'Other'), - ], string='Cushion Type') - cushion_notes = fields.Text(string='Cushion Notes') - - backrest_type = fields.Selection([ - ('standard', 'Standard'), - ('adjustable', 'Adjustable Tension'), - ('solid', 'Solid Back'), - ('contoured', 'Contoured'), - ('custom', 'Custom'), - ('other', 'Other'), - ], string='Backrest Type') - backrest_notes = fields.Text(string='Backrest Notes') - - frame_type = fields.Selection([ - ('folding', 'Folding'), - ('rigid', 'Rigid'), - ('tilt', 'Tilt-in-Space'), - ('reclining', 'Reclining'), - ('standing', 'Standing'), - ('power', 'Power'), - ('other', 'Other'), - ], string='Frame Type') - frame_notes = fields.Text(string='Frame Notes') - - wheel_type = fields.Selection([ - ('pneumatic', 'Pneumatic'), - ('solid', 'Solid'), - ('flat_free', 'Flat-Free'), - ('mag', 'Mag Wheels'), - ('spoke', 'Spoke Wheels'), - ('other', 'Other'), - ], string='Wheel Type') - wheel_notes = fields.Text(string='Wheel Notes') - - # ===== ACCESSIBILITY/MOBILITY NEEDS ===== - mobility_notes = fields.Text( - string='Mobility Needs', - help='Document the client mobility needs and challenges', - ) - - accessibility_notes = fields.Text( - string='Accessibility Notes', - help='Document accessibility requirements and home environment', - ) - - special_requirements = fields.Text( - string='Special Requirements', - help='Any special requirements or customizations needed', - ) - - diagnosis = fields.Text( - string='Diagnosis/Condition', - help='Relevant medical diagnosis or conditions', - ) - - # ===== PAGE 11: CONSENT & DECLARATION ===== - consent_signed_by = fields.Selection([ - ('applicant', 'Applicant'), - ('agent', 'Agent'), - ], string='Consent Signed By', default='applicant', - help='Who signed the ADP consent declaration') - - consent_declaration_accepted = fields.Boolean( - string='Consent Declaration Accepted', - help='Whether the consent declaration checkbox was checked', - ) - consent_date = fields.Date( - string='Consent Date', - help='Date the consent was signed', - ) - - # Agent info (only if consent_signed_by == 'agent') - agent_relationship = fields.Selection([ - ('spouse', 'Spouse'), - ('parent', 'Parent(s)'), - ('child', 'Child'), - ('power_of_attorney', 'Power of Attorney'), - ('public_guardian', 'Public Guardian/Trustee'), - ], string='Agent Relationship') - agent_first_name = fields.Char(string='Agent First Name') - agent_last_name = fields.Char(string='Agent Last Name') - agent_middle_initial = fields.Char(string='Agent Middle Initial') - agent_unit = fields.Char(string='Agent Unit') - agent_street_number = fields.Char(string='Agent Street Number') - agent_street_name = fields.Char(string='Agent Street Name') - agent_city = fields.Char(string='Agent City') - agent_province = fields.Char(string='Agent Province', default='Ontario') - agent_postal_code = fields.Char(string='Agent Postal Code') - agent_home_phone = fields.Char(string='Agent Home Phone') - agent_business_phone = fields.Char(string='Agent Business Phone') - agent_phone_ext = fields.Char(string='Agent Phone Ext') - - # Generated filled PDF from template engine - signed_page_11_pdf = fields.Binary(string='Signed Page 11 PDF') - signed_page_11_pdf_filename = fields.Char(string='Signed Page 11 Filename') - - # ===== SIGNATURES ===== - signature_page_11 = fields.Binary( - string='Page 11 Signature (Authorizer)', - help='Digital signature for ADP Application Page 11', - ) - signature_page_11_name = fields.Char(string='Page 11 Signer Name') - signature_page_11_date = fields.Datetime(string='Page 11 Signed Date') - - signature_page_12 = fields.Binary( - string='Page 12 Signature (Client)', - help='Digital signature for ADP Application Page 12', - ) - signature_page_12_name = fields.Char(string='Page 12 Signer Name') - signature_page_12_date = fields.Datetime(string='Page 12 Signed Date') - - signatures_complete = fields.Boolean( - string='Signatures Complete', - compute='_compute_signatures_complete', - store=True, - ) - - # ===== RELATIONSHIPS ===== - document_ids = fields.One2many( - 'fusion.adp.document', - 'assessment_id', - string='Documents', - ) - - comment_ids = fields.One2many( - 'fusion.authorizer.comment', - 'assessment_id', - string='Comments', - ) - - sale_order_id = fields.Many2one( - 'sale.order', - string='Created Sale Order', - readonly=True, - copy=False, - ) - - # ===== COMPUTED FIELDS ===== - document_count = fields.Integer( - string='Document Count', - compute='_compute_document_count', - ) - - @api.depends('client_name', 'reference', 'equipment_type') - def _compute_display_name(self): - equipment_labels = {'rollator': 'Rollator', 'wheelchair': 'Wheelchair', 'powerchair': 'Powerchair'} - for assessment in self: - if assessment.reference and assessment.reference != 'New': - equip = equipment_labels.get(assessment.equipment_type, '') - equip_suffix = f' ({equip})' if equip else '' - assessment.display_name = f"{assessment.reference} - {assessment.client_name or 'Unknown'}{equip_suffix}" - else: - assessment.display_name = assessment.client_name or _('New Assessment') - - @api.depends('signature_page_11', 'signature_page_12') - def _compute_signatures_complete(self): - for assessment in self: - assessment.signatures_complete = bool(assessment.signature_page_11 and assessment.signature_page_12) - - @api.depends('document_ids') - def _compute_document_count(self): - for assessment in self: - assessment.document_count = len(assessment.document_ids) - - @api.model_create_multi - def create(self, vals_list): - """Override create to generate reference number""" - for vals in vals_list: - if vals.get('reference', 'New') == 'New': - vals['reference'] = self.env['ir.sequence'].next_by_code('fusion.assessment') or 'New' - return super().create(vals_list) - - def action_mark_pending_signature(self): - """Move to pending signature state""" - self.ensure_one() - self.state = 'pending_signature' - return True - - def action_complete(self): - """Complete the assessment and create draft sale order""" - self.ensure_one() - - if not self.signatures_complete: - raise UserError(_('Please ensure both Page 11 and Page 12 signatures are captured before completing.')) - - # Create or link partner - partner = self._ensure_partner() - - # Create draft sale order - sale_order = self._create_draft_sale_order(partner) - - # Generate signed documents - self._generate_signed_documents() - - # Update state - self.write({ - 'state': 'completed', - 'sale_order_id': sale_order.id, - 'partner_id': partner.id, - }) - - # Send notifications - self._send_completion_notifications() - - return { - 'type': 'ir.actions.act_window', - 'name': _('Created Sale Order'), - 'res_model': 'sale.order', - 'res_id': sale_order.id, - 'view_mode': 'form', - 'target': 'current', - } - - def action_complete_express(self): - """Complete express assessment and create draft sale order (no signatures required)""" - self.ensure_one() - - # Validate required fields - if not self.equipment_type: - raise UserError(_('Please select an equipment type.')) - if not self.authorizer_id: - raise UserError(_('Please select an authorizer.')) - if not self.client_name: - raise UserError(_('Please enter the client name.')) - - # Create or link partner - partner = self._ensure_partner() - - # Create draft sale order - sale_order = self._create_draft_sale_order(partner) - - # Update state - self.write({ - 'state': 'completed', - 'sale_order_id': sale_order.id, - 'partner_id': partner.id, - }) - - _logger.info(f"Completed express assessment {self.reference}, created SO {sale_order.name}") - - return sale_order - - def action_cancel(self): - """Cancel the assessment""" - self.ensure_one() - self.state = 'cancelled' - return True - - def action_reset_draft(self): - """Reset to draft state""" - self.ensure_one() - self.state = 'draft' - return True - - def _ensure_partner(self): - """Ensure a partner exists for the client, create if needed""" - self.ensure_one() - - if self.partner_id: - return self.partner_id - - if not self.create_new_partner: - raise UserError(_('Please select an existing client or check "Create New Client".')) - - # Build address - address_parts = [] - if self.client_street: - address_parts.append(self.client_street) - if self.client_city: - address_parts.append(self.client_city) - if self.client_state: - address_parts.append(self.client_state) - if self.client_postal_code: - address_parts.append(self.client_postal_code) - - partner_vals = { - 'name': self.client_name, - 'street': self.client_street or '', - 'street2': self.client_unit or False, - 'city': self.client_city or '', - 'zip': self.client_postal_code or '', - 'phone': self.client_phone or '', - 'email': self.client_email or '', - 'customer_rank': 1, - } - - if self.client_country_id: - partner_vals['country_id'] = self.client_country_id.id - - partner = self.env['res.partner'].sudo().create(partner_vals) - _logger.info(f"Created new partner {partner.name} (ID: {partner.id}) from assessment {self.reference}") - - return partner - - def _create_draft_sale_order(self, partner): - """Create a draft sale order from the assessment""" - self.ensure_one() - - SaleOrder = self.env['sale.order'].sudo() - CrmTag = self.env['crm.tag'].sudo() - - # Determine sale type based on client type - # REG = ADP only, ODS/ACS/OWP = ADP + ODSP - sale_type = 'adp' - if self.client_type in ['ods', 'acs', 'owp']: - sale_type = 'adp_odsp' - - # Determine the correct workflow status for the SO. - # The write() auto-transition (assessment_completed -> waiting_for_application) - # does NOT fire during create(), so we set the final target status directly. - if self.assessment_start_date and self.assessment_end_date: - # Both dates filled = assessment completed -> advance to waiting_for_application - target_status = 'waiting_for_application' - elif self.assessment_start_date: - # Only start date = assessment is scheduled - target_status = 'assessment_scheduled' - else: - target_status = 'quotation' - - # Prepare values - so_vals = { - 'partner_id': partner.id, - 'user_id': self.sales_rep_id.id if self.sales_rep_id else self.env.user.id, - 'state': 'draft', - 'origin': f'Assessment: {self.reference}', - 'x_fc_sale_type': sale_type, - # Issue 2 fix: Set assessment back-link for traceability - 'assessment_id': self.id, - # Set the correct workflow status directly - 'x_fc_adp_application_status': target_status, - } - - # Set authorizer if available - if self.authorizer_id: - so_vals['x_fc_authorizer_id'] = self.authorizer_id.id - - # Set client references if available - if self.client_reference_1: - so_vals['x_fc_client_ref_1'] = self.client_reference_1 - if self.client_reference_2: - so_vals['x_fc_client_ref_2'] = self.client_reference_2 - - # Map assessment dates to SO x_fc_ fields - if self.assessment_start_date: - so_vals['x_fc_assessment_start_date'] = self.assessment_start_date - if self.assessment_end_date: - so_vals['x_fc_assessment_end_date'] = self.assessment_end_date - if self.claim_authorization_date: - so_vals['x_fc_claim_authorization_date'] = self.claim_authorization_date - - # Map reason for application - if self.reason_for_application: - so_vals['x_fc_reason_for_application'] = self.reason_for_application - if self.previous_funding_date: - so_vals['x_fc_previous_funding_date'] = self.previous_funding_date - - # Map client type (assessment uses lowercase, sale.order uses uppercase) - if self.client_type: - client_type_map = { - 'reg': 'REG', - 'ods': 'ODS', - 'acs': 'ACS', - 'owp': 'OWP', - } - so_vals['x_fc_client_type'] = client_type_map.get(self.client_type, self.client_type.upper()) - - # ===================================================================== - # Issue 3 & 4 fix: Map Page 11 consent & signature tracking to SO - # ===================================================================== - if self.consent_signed_by: - # Map consent_signed_by to x_fc_page11_signer_type - if self.consent_signed_by == 'applicant': - so_vals['x_fc_page11_signer_type'] = 'client' - so_vals['x_fc_page11_signer_name'] = self.client_name or '' - elif self.consent_signed_by == 'agent': - # Map agent_relationship to signer_type - agent_type_map = { - 'spouse': 'spouse', - 'parent': 'parent', - 'child': 'legal_guardian', - 'power_of_attorney': 'poa', - 'public_guardian': 'public_trustee', - } - so_vals['x_fc_page11_signer_type'] = agent_type_map.get( - self.agent_relationship, 'legal_guardian' - ) - agent_name = f"{self.agent_first_name or ''} {self.agent_last_name or ''}".strip() - so_vals['x_fc_page11_signer_name'] = agent_name or self.client_name or '' - if self.agent_relationship: - relationship_labels = dict(self._fields['agent_relationship'].selection) - so_vals['x_fc_page11_signer_relationship'] = relationship_labels.get( - self.agent_relationship, self.agent_relationship - ) - - if self.consent_date: - so_vals['x_fc_page11_signed_date'] = self.consent_date - - # Build tags list - tag_ids = [] - - # Always add ADP tag - adp_tag = CrmTag.search([('name', 'ilike', 'ADP')], limit=1) - if adp_tag: - tag_ids.append(adp_tag.id) - - # Add equipment type tag based on selection - equipment_tag_name = None - if self.equipment_type == 'wheelchair' and self.wheelchair_type: - type_map = { - 'type_1': 'TYPE 1 WHEELCHAIR', - 'type_2': 'TYPE 2 WHEELCHAIR', - 'type_3': 'TYPE 3 WHEELCHAIR', - 'type_4': 'TYPE 4 WHEELCHAIR', - 'type_5': 'TYPE 5 WHEELCHAIR', - } - equipment_tag_name = type_map.get(self.wheelchair_type) - elif self.equipment_type == 'rollator' and self.rollator_type: - type_map = { - 'type_1': 'TYPE 1 ROLLATOR', - 'type_2': 'TYPE 2 ROLLATOR', - 'type_3': 'TYPE 3 ROLLATOR', - } - equipment_tag_name = type_map.get(self.rollator_type) - elif self.equipment_type == 'powerchair' and self.powerchair_type: - type_map = { - 'type_1': 'TYPE 1 POWERCHAIR', - 'type_2': 'TYPE 2 POWERCHAIR', - 'type_3': 'TYPE 3 POWERCHAIR', - } - equipment_tag_name = type_map.get(self.powerchair_type) - - # Find or create the equipment tag - if equipment_tag_name: - equipment_tag = CrmTag.search([('name', 'ilike', equipment_tag_name)], limit=1) - if not equipment_tag: - # Create the tag if it doesn't exist - equipment_tag = CrmTag.create({'name': equipment_tag_name}) - _logger.info(f"Created new CRM tag: {equipment_tag_name}") - tag_ids.append(equipment_tag.id) - - # Add tags to sale order values - if tag_ids: - so_vals['tag_ids'] = [(6, 0, tag_ids)] - - sale_order = SaleOrder.create(so_vals) - _logger.info(f"Created draft sale order {sale_order.name} from assessment {self.reference} " - f"with sale_type={sale_type}, status={target_status}") - - # ===================================================================== - # Issue 6 fix: Post workflow-consistent chatter messages - # ===================================================================== - # Post a workflow status message matching what backend wizards would generate - equipment_labels = { - 'rollator': 'Rollator', 'wheelchair': 'Wheelchair', 'powerchair': 'Powerchair', - } - equipment_label = equipment_labels.get(self.equipment_type, 'Equipment') - sales_rep_name = self.sales_rep_id.name if self.sales_rep_id else self.env.user.name - authorizer_name = self.authorizer_id.name if self.authorizer_id else 'N/A' - - workflow_msg = Markup( - '' - ) - sale_order.message_post( - body=workflow_msg, - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - - # Post assessment details to chatter as HTML table - assessment_html = self._format_assessment_html_table() - sale_order.message_post( - body=Markup(assessment_html), - message_type='comment', - subtype_xmlid='mail.mt_note', - ) - - # ===================================================================== - # Issue 4 fix: Post consent & agent details to chatter - # ===================================================================== - if self.consent_signed_by: - consent_label = 'Applicant' if self.consent_signed_by == 'applicant' else 'Agent' - consent_parts = [ - f'
  • Signed by: {consent_label}
  • ', - ] - if self.consent_date: - consent_parts.append(f'
  • Consent date: {self.consent_date}
  • ') - if self.consent_declaration_accepted: - consent_parts.append('
  • Declaration accepted: Yes
  • ') - - # Add agent details if signed by agent - if self.consent_signed_by == 'agent': - agent_name = f"{self.agent_first_name or ''} {self.agent_last_name or ''}".strip() - if agent_name: - consent_parts.append(f'
  • Agent name: {agent_name}
  • ') - if self.agent_relationship: - rel_labels = dict(self._fields['agent_relationship'].selection) - consent_parts.append( - f'
  • Relationship: ' - f'{rel_labels.get(self.agent_relationship, self.agent_relationship)}
  • ' - ) - agent_addr_parts = [] - if self.agent_unit: - agent_addr_parts.append(f'Unit {self.agent_unit}') - if self.agent_street_number: - agent_addr_parts.append(self.agent_street_number) - if self.agent_street_name: - agent_addr_parts.append(self.agent_street_name) - if self.agent_city: - agent_addr_parts.append(self.agent_city) - if self.agent_province: - agent_addr_parts.append(self.agent_province) - if self.agent_postal_code: - agent_addr_parts.append(self.agent_postal_code) - if agent_addr_parts: - consent_parts.append( - f'
  • Agent address: {", ".join(agent_addr_parts)}
  • ' - ) - phones = [] - if self.agent_home_phone: - phones.append(f'Home: {self.agent_home_phone}') - if self.agent_business_phone: - ext = f' ext {self.agent_phone_ext}' if self.agent_phone_ext else '' - phones.append(f'Business: {self.agent_business_phone}{ext}') - if phones: - consent_parts.append( - f'
  • Agent phone: {", ".join(phones)}
  • ' - ) - - consent_msg = Markup( - '' - ) - sale_order.message_post( - body=consent_msg, - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - - # Send email notification to sales person and authorizer - self._send_assessment_completed_email(sale_order) - - # Schedule follow-up activity for sales rep - self._schedule_followup_activity(sale_order) - - return sale_order - - def _schedule_followup_activity(self, sale_order): - """Schedule a follow-up activity for the sales rep""" - self.ensure_one() - - sales_rep = self.sales_rep_id or self.env.user - if not sales_rep: - return - - # Get the "To Do" activity type - activity_type = self.env.ref('mail.mail_activity_data_todo', raise_if_not_found=False) - if not activity_type: - _logger.warning("Could not find 'To Do' activity type") - return - - # Get equipment type label - equipment_labels = { - 'wheelchair': 'Wheelchair', - 'rollator': 'Rollator', - 'powerchair': 'Powerchair', - } - equipment_label = equipment_labels.get(self.equipment_type, 'Equipment') - - # Schedule activity for tomorrow - due_date = fields.Date.today() + timedelta(days=1) - - try: - sale_order.activity_schedule( - activity_type_id=activity_type.id, - date_deadline=due_date, - user_id=sales_rep.id, - summary=f'Follow up on {equipment_label} Assessment', - note=f'Assessment {self.reference} for {self.client_name} has been completed. Please follow up with the client and authorizer.', - ) - _logger.info(f"Scheduled follow-up activity for {sales_rep.name} on SO {sale_order.name}") - except Exception as e: - _logger.error(f"Failed to schedule follow-up activity: {e}") - - def _send_assessment_completed_email(self, sale_order): - """Send email notification to sales person, authorizer, and office about completed assessment. - Includes the full assessment report so recipients can review without logging in.""" - self.ensure_one() - - if not self._email_is_enabled(): - return - - to_emails = [] - cc_emails = [] - if self.authorizer_id and self.authorizer_id.email: - to_emails.append(self.authorizer_id.email) - if self.sales_rep_id and self.sales_rep_id.email: - cc_emails.append(self.sales_rep_id.email) - company = self.env.company - office_partners = company.sudo().x_fc_office_notification_ids - cc_emails.extend([p.email for p in office_partners if p.email]) - if not to_emails and not cc_emails: - return - - sales_rep_name = self.sales_rep_id.name if self.sales_rep_id else 'The Sales Team' - assessment_date = self.assessment_end_date.strftime('%B %d, %Y') if self.assessment_end_date else 'Today' - equipment_labels = {'rollator': 'Rollator', 'wheelchair': 'Wheelchair', 'powerchair': 'Powerchair'} - equipment_label = equipment_labels.get(self.equipment_type, 'Equipment') - - # Build the detailed assessment report sections for the email - report_sections = self._build_assessment_email_sections(sale_order, equipment_label, assessment_date) - - email_body = self._email_build( - title='Assessment Completed', - summary=f'The ADP assessment for {self.client_name} has been completed ' - f'on {assessment_date}. A draft sales order has been created. ' - f'The full assessment report is included below.', - email_type='success', - sections=report_sections, - note='Next steps: Please submit the ADP application ' - '(including pages 11-12 signed by the client) so we can proceed with the claim submission.', - button_url=f'{sale_order.get_base_url()}/web#id={sale_order.id}&model=sale.order&view_type=form', - button_text='View Sale Order', - sender_name=sales_rep_name, - ) - - email_to = ', '.join(to_emails) if to_emails else ', '.join(cc_emails[:1]) - email_cc = ', '.join(cc_emails) if to_emails else ', '.join(cc_emails[1:]) - try: - self.env['mail.mail'].sudo().create({ - 'subject': f'Assessment Completed - {self.client_name} ({equipment_label}) - {sale_order.name}', - 'body_html': email_body, - 'email_to': email_to, 'email_cc': email_cc, - 'model': 'sale.order', 'res_id': sale_order.id, - 'auto_delete': True, - }).send() - chatter_body = Markup( - '' - ) - sale_order.message_post(body=chatter_body, message_type='notification', subtype_xmlid='mail.mt_note') - _logger.info(f"Sent assessment completed email for {self.reference}") - except Exception as e: - _logger.error(f"Failed to send assessment completed email: {e}") - - def _build_assessment_email_sections(self, sale_order, equipment_label, assessment_date): - """Build comprehensive email sections with all assessment details. - Returns a list of (heading, rows) tuples for _email_build().""" - self.ensure_one() - - sections = [] - - # --- Section 1: Overview --- - overview_rows = [ - ('Reference', self.reference), - ('Sales Order', sale_order.name), - ('Client', self.client_name), - ('Equipment', equipment_label), - ('Assessment Date', assessment_date), - ('Authorizer/OT', self.authorizer_id.name if self.authorizer_id else None), - ('Sales Rep', self.sales_rep_id.name if self.sales_rep_id else None), - ] - if self.client_type: - ct_labels = { - 'reg': 'REG - Regular ADP', - 'ods': 'ODS - ODSP', - 'acs': 'ACS - ACSD', - 'owp': 'OWP - Ontario Works', - } - overview_rows.append(('Client Type', ct_labels.get(self.client_type, self.client_type))) - if self.reason_for_application: - reason_labels = dict(self._fields['reason_for_application'].selection) - overview_rows.append(('Reason for Application', reason_labels.get( - self.reason_for_application, self.reason_for_application))) - if self.previous_funding_date: - overview_rows.append(('Previous Funding Date', str(self.previous_funding_date))) - sections.append(('Assessment Overview', overview_rows)) - - # --- Section 2: Client Information --- - client_rows = [ - ('Name', self.client_name), - ] - if self.client_first_name or self.client_last_name: - full = f"{self.client_first_name or ''} {self.client_middle_name or ''} {self.client_last_name or ''}".strip() - client_rows.append(('Full Name', full)) - if self.client_weight: - client_rows.append(('Weight', f'{int(self.client_weight)} lbs')) - if self.client_dob: - client_rows.append(('Date of Birth', str(self.client_dob))) - if self.client_health_card: - version = f' ({self.client_health_card_version})' if self.client_health_card_version else '' - client_rows.append(('Health Card', f'{self.client_health_card}{version}')) - # Address - addr_parts = [p for p in [ - self.client_street, self.client_unit, self.client_city, - self.client_state, self.client_postal_code, - ] if p] - if addr_parts: - client_rows.append(('Address', ', '.join(addr_parts))) - if self.client_phone: - client_rows.append(('Phone', self.client_phone)) - if self.client_mobile: - client_rows.append(('Mobile', self.client_mobile)) - if self.client_email: - client_rows.append(('Email', self.client_email)) - sections.append(('Client Information', client_rows)) - - # --- Section 3: Equipment Type & Subtype --- - equip_rows = [('Equipment Type', equipment_label)] - - if self.equipment_type == 'rollator': - if self.rollator_type: - type_labels = dict(self._fields['rollator_type'].selection) - equip_rows.append(('Rollator Type', type_labels.get(self.rollator_type, self.rollator_type))) - elif self.equipment_type == 'wheelchair': - if self.wheelchair_type: - type_labels = dict(self._fields['wheelchair_type'].selection) - equip_rows.append(('Wheelchair Type', type_labels.get(self.wheelchair_type, self.wheelchair_type))) - elif self.equipment_type == 'powerchair': - if self.powerchair_type: - type_labels = dict(self._fields['powerchair_type'].selection) - equip_rows.append(('Powerchair Type', type_labels.get(self.powerchair_type, self.powerchair_type))) - - sections.append(('Equipment Selection', equip_rows)) - - # --- Section 4: Measurements --- - meas_rows = [] - if self.equipment_type == 'rollator': - if self.rollator_handle_height: - meas_rows.append(('Handle Height', f'{self.rollator_handle_height}"')) - if self.rollator_seat_height: - meas_rows.append(('Seat Height', f'{self.rollator_seat_height}"')) - else: - # Wheelchair / Powerchair measurements - if self.seat_width: - meas_rows.append(('Seat Width', f'{self.seat_width}"')) - if self.seat_depth: - meas_rows.append(('Seat Depth', f'{self.seat_depth}"')) - if self.legrest_length: - meas_rows.append(('Legrest Length', f'{self.legrest_length}"')) - if self.seat_to_floor_height: - sfh_label = f'{self.seat_to_floor_height}" (Including Cushion)' if self.equipment_type == 'wheelchair' else f'{self.seat_to_floor_height}"' - meas_rows.append(('Seat to Floor Height', sfh_label)) - if self.cane_height: - meas_rows.append(('Cane Height', f'{self.cane_height}" (Ground to Canes)')) - if self.back_height: - meas_rows.append(('Back Height', f'{self.back_height}"')) - if self.armrest_height: - meas_rows.append(('Armrest Height', f'{self.armrest_height}"')) - if self.footrest_length: - meas_rows.append(('Footrest Length', f'{self.footrest_length}"')) - if meas_rows: - sections.append(('Measurements', meas_rows)) - - # --- Section 5: Options & Addons --- - options_rows = [] - if self.equipment_type == 'rollator' and self.rollator_addons: - for addon in self.rollator_addons.split(','): - addon = addon.strip() - if addon: - options_rows.append((addon, 'Yes')) - elif self.equipment_type == 'wheelchair': - if self.frame_options: - for opt in self.frame_options.split(','): - opt = opt.strip() - if opt: - options_rows.append((f'Frame: {opt}', 'Yes')) - if self.wheel_options: - for opt in self.wheel_options.split(','): - opt = opt.strip() - if opt: - options_rows.append((f'Wheel: {opt}', 'Yes')) - if self.legrest_options: - for opt in self.legrest_options.split(','): - opt = opt.strip() - if opt: - options_rows.append((f'Legrest: {opt}', 'Yes')) - if self.additional_adp_options: - for opt in self.additional_adp_options.split(','): - opt = opt.strip() - if opt: - options_rows.append((f'ADP Option: {opt}', 'Yes')) - elif self.equipment_type == 'powerchair': - if self.powerchair_options: - for opt in self.powerchair_options.split(','): - opt = opt.strip() - if opt: - options_rows.append((f'Powerchair: {opt}', 'Yes')) - if self.specialty_controls: - for opt in self.specialty_controls.split(','): - opt = opt.strip() - if opt: - options_rows.append((f'Specialty: {opt}', 'Yes')) - - # Seatbelt (wheelchair & powerchair) - if self.seatbelt_type and self.equipment_type in ('wheelchair', 'powerchair'): - belt_labels = dict(self._fields['seatbelt_type'].selection) - options_rows.append(('Seat Belt', belt_labels.get(self.seatbelt_type, self.seatbelt_type))) - - # Cushion & Backrest - if self.cushion_info: - options_rows.append(('Cushion', self.cushion_info)) - if self.backrest_info: - options_rows.append(('Backrest', self.backrest_info)) - - if options_rows: - sections.append(('Options & Accessories', options_rows)) - - # --- Section 6: Additional Notes --- - notes_rows = [] - if self.additional_customization: - notes_rows.append(('Customization', self.additional_customization)) - if self.mobility_notes: - notes_rows.append(('Mobility Needs', self.mobility_notes)) - if self.accessibility_notes: - notes_rows.append(('Accessibility', self.accessibility_notes)) - if self.special_requirements: - notes_rows.append(('Special Requirements', self.special_requirements)) - if self.diagnosis: - notes_rows.append(('Diagnosis/Condition', self.diagnosis)) - if notes_rows: - sections.append(('Additional Notes', notes_rows)) - - # --- Section 7: Key Dates --- - date_rows = [] - if self.assessment_start_date: - date_rows.append(('Assessment Start', self.assessment_start_date.strftime('%B %d, %Y'))) - if self.assessment_end_date: - date_rows.append(('Assessment End', self.assessment_end_date.strftime('%B %d, %Y'))) - if self.claim_authorization_date: - date_rows.append(('Claim Authorization', self.claim_authorization_date.strftime('%B %d, %Y'))) - if date_rows: - sections.append(('Key Dates', date_rows)) - - # --- Section 8: Consent Information --- - if self.consent_signed_by: - consent_rows = [] - consent_label = 'Applicant' if self.consent_signed_by == 'applicant' else 'Agent' - consent_rows.append(('Signed By', consent_label)) - if self.consent_date: - consent_rows.append(('Consent Date', str(self.consent_date))) - if self.consent_declaration_accepted: - consent_rows.append(('Declaration Accepted', 'Yes')) - if self.consent_signed_by == 'agent': - agent_name = f"{self.agent_first_name or ''} {self.agent_last_name or ''}".strip() - if agent_name: - consent_rows.append(('Agent Name', agent_name)) - if self.agent_relationship: - rel_labels = dict(self._fields['agent_relationship'].selection) - consent_rows.append(('Relationship', rel_labels.get( - self.agent_relationship, self.agent_relationship))) - sections.append(('Consent & Declaration (Page 11)', consent_rows)) - - return sections - - def _format_assessment_html_table(self): - """Format assessment data as HTML table for chatter""" - self.ensure_one() - - # Get equipment type display name - equipment_labels = { - 'rollator': 'Rollator', - 'wheelchair': 'Wheelchair', - 'powerchair': 'Powerchair', - } - equipment_display = equipment_labels.get(self.equipment_type, 'Unknown') - - # Start building HTML - html = f''' -

    ADP Assessment - {equipment_display}

    - - - - - - ''' - - row_num = 0 - def add_row(label, value, is_header=False): - nonlocal html, row_num - if is_header: - html += f''' - - - - ''' - else: - bg = '#f9f9f9' if row_num % 2 == 0 else '#ffffff' - html += f''' - - - - - ''' - row_num += 1 - - # Client Type - if self.client_type: - client_type_labels = { - 'reg': 'REG - Regular ADP', - 'ods': 'ODS - ODSP', - 'acs': 'ACS - ACSD', - 'owp': 'OWP - Ontario Works', - } - add_row('Client Type', client_type_labels.get(self.client_type, self.client_type)) - - # Equipment Type - add_row('Equipment Type', equipment_display) - - # Client Weight - shown prominently at the top - if self.client_weight: - add_row('Client Weight', f'{int(self.client_weight)} lbs') - - # Type-specific info - if self.equipment_type == 'rollator': - if self.rollator_type: - type_labels = dict(self._fields['rollator_type'].selection) - add_row('Rollator Type', type_labels.get(self.rollator_type, self.rollator_type)) - - add_row('Measurements', '', is_header=True) - if self.rollator_handle_height: - add_row('Handle Height', f'{self.rollator_handle_height}"') - if self.rollator_seat_height: - add_row('Seat Height', f'{self.rollator_seat_height}"') - - if self.rollator_addons: - add_row('Addons', '', is_header=True) - for addon in self.rollator_addons.split(','): - addon = addon.strip() - if addon: - add_row(addon, 'Yes') - - elif self.equipment_type == 'wheelchair': - if self.wheelchair_type: - type_labels = dict(self._fields['wheelchair_type'].selection) - add_row('Wheelchair Type', type_labels.get(self.wheelchair_type, self.wheelchair_type)) - - add_row('Measurements', '', is_header=True) - if self.seat_width: - add_row('Seat Width', f'{self.seat_width}"') - if self.seat_depth: - add_row('Seat Depth', f'{self.seat_depth}"') - if self.legrest_length: - add_row('Legrest Length', f'{self.legrest_length}"') - if self.seat_to_floor_height: - add_row('Seat to Floor Height', f'{self.seat_to_floor_height}" (Including Cushion)') - if self.cane_height: - add_row('Cane Height', f'{self.cane_height}" (Ground to Canes)') - if self.back_height: - add_row('Back Height', f'{self.back_height}"') - - if self.frame_options: - add_row('Frame Options - ADP Funded', '', is_header=True) - for opt in self.frame_options.split(','): - opt = opt.strip() - if opt: - add_row(opt, 'Yes') - - if self.wheel_options: - add_row('Wheel Options/Addons - ADP Funded', '', is_header=True) - for opt in self.wheel_options.split(','): - opt = opt.strip() - if opt: - add_row(opt, 'Yes') - - if self.legrest_options: - add_row('Legrest Accessories - ADP Funded', '', is_header=True) - for opt in self.legrest_options.split(','): - opt = opt.strip() - if opt: - add_row(opt, 'Yes') - - if self.additional_adp_options: - add_row('Additional ADP Funded Options', '', is_header=True) - for opt in self.additional_adp_options.split(','): - opt = opt.strip() - if opt: - add_row(opt, 'Yes') - - if self.seatbelt_type: - belt_labels = dict(self._fields['seatbelt_type'].selection) - add_row('Seat Belt Type', belt_labels.get(self.seatbelt_type, self.seatbelt_type)) - - elif self.equipment_type == 'powerchair': - if self.powerchair_type: - type_labels = dict(self._fields['powerchair_type'].selection) - add_row('Powerchair Type', type_labels.get(self.powerchair_type, self.powerchair_type)) - - add_row('Measurements', '', is_header=True) - if self.seat_width: - add_row('Seat Width', f'{self.seat_width}"') - if self.seat_depth: - add_row('Seat Depth', f'{self.seat_depth}"') - if self.legrest_length: - add_row('Legrest Length', f'{self.legrest_length}"') - if self.seat_to_floor_height: - add_row('Seat to Floor Height', f'{self.seat_to_floor_height}"') - if self.cane_height: - add_row('Cane Height', f'{self.cane_height}" (Ground to Canes)') - if self.back_height: - add_row('Back Height', f'{self.back_height}"') - if self.armrest_height: - add_row('Armrest Height', f'{self.armrest_height}"') - if self.footrest_length: - add_row('Footrest Length', f'{self.footrest_length}"') - - if self.seatbelt_type: - belt_labels = dict(self._fields['seatbelt_type'].selection) - add_row('Seat Belt Type', belt_labels.get(self.seatbelt_type, self.seatbelt_type)) - - if self.powerchair_options: - add_row('Powerchair - Additional ADP Funded Options', '', is_header=True) - for opt in self.powerchair_options.split(','): - opt = opt.strip() - if opt: - add_row(opt, 'Yes') - - if self.specialty_controls: - add_row('Specialty Components (Rationale Required)', '', is_header=True) - for opt in self.specialty_controls.split(','): - opt = opt.strip() - if opt: - add_row(opt, 'Yes') - - # Cushion & Backrest (wheelchair/powerchair) - if self.cushion_info: - add_row('Cushion', self.cushion_info) - if self.backrest_info: - add_row('Backrest', self.backrest_info) - - # Additional customization notes - if self.additional_customization: - add_row('Additional Information/Customization', self.additional_customization) - - # Client info summary - add_row('Client Information', '', is_header=True) - add_row('Client Name', self.client_name or '') - if self.client_weight: - add_row('Client Weight', f'{int(self.client_weight)} lbs') - if self.client_health_card: - version = f' ({self.client_health_card_version})' if self.client_health_card_version else '' - add_row('Health Card', f'{self.client_health_card}{version}') - if self.client_phone: - add_row('Phone', self.client_phone) - if self.client_email: - add_row('Email', self.client_email) - - # Dates - add_row('Key Dates', '', is_header=True) - if self.assessment_start_date: - add_row('Assessment Start Date', str(self.assessment_start_date)) - if self.assessment_end_date: - add_row('Assessment End Date', str(self.assessment_end_date)) - if self.claim_authorization_date: - add_row('Claim Authorization Date', str(self.claim_authorization_date)) - - if self.reason_for_application: - reason_labels = dict(self._fields['reason_for_application'].selection) - add_row('Reason for Application', reason_labels.get(self.reason_for_application, self.reason_for_application)) - - html += '
    FieldValue
    {label}
    {label}{value}
    ' - return html - - def _format_specifications_for_order(self): - """Format wheelchair specifications for the sale order notes (legacy)""" - self.ensure_one() - - lines = [ - f"=== Assessment Specifications ({self.reference}) ===", - "", - "MEASUREMENTS:", - ] - - if self.seat_width: - lines.append(f" Seat Width: {self.seat_width}\"") - if self.seat_depth: - lines.append(f" Seat Depth: {self.seat_depth}\"") - if self.seat_to_floor_height: - lines.append(f" Seat to Floor: {self.seat_to_floor_height}\"") - if self.back_height: - lines.append(f" Back Height: {self.back_height}\"") - if self.armrest_height: - lines.append(f" Armrest Height: {self.armrest_height}\"") - if self.footrest_length: - lines.append(f" Footrest Length: {self.footrest_length}\"") - - lines.append("") - lines.append("PRODUCT SELECTIONS:") - - if self.cushion_type: - lines.append(f" Cushion: {dict(self._fields['cushion_type'].selection).get(self.cushion_type, self.cushion_type)}") - if self.backrest_type: - lines.append(f" Backrest: {dict(self._fields['backrest_type'].selection).get(self.backrest_type, self.backrest_type)}") - if self.frame_type: - lines.append(f" Frame: {dict(self._fields['frame_type'].selection).get(self.frame_type, self.frame_type)}") - if self.wheel_type: - lines.append(f" Wheels: {dict(self._fields['wheel_type'].selection).get(self.wheel_type, self.wheel_type)}") - - if self.mobility_notes: - lines.append("") - lines.append("MOBILITY NEEDS:") - lines.append(f" {self.mobility_notes}") - - if self.accessibility_notes: - lines.append("") - lines.append("ACCESSIBILITY NOTES:") - lines.append(f" {self.accessibility_notes}") - - if self.special_requirements: - lines.append("") - lines.append("SPECIAL REQUIREMENTS:") - lines.append(f" {self.special_requirements}") - - return "\n".join(lines) - - def _generate_signed_documents(self): - """Generate document records for signed pages""" - self.ensure_one() - - ADPDocument = self.env['fusion.adp.document'].sudo() - - # Create Page 11 document if signature exists - if self.signature_page_11: - ADPDocument.create({ - 'assessment_id': self.id, - 'sale_order_id': self.sale_order_id.id if self.sale_order_id else False, - 'document_type': 'page_11', - 'file': self.signature_page_11, - 'filename': f'page_11_signature_{self.reference}.png', - 'mimetype': 'image/png', - 'source': 'assessment', - }) - - # Create Page 12 document if signature exists - if self.signature_page_12: - ADPDocument.create({ - 'assessment_id': self.id, - 'sale_order_id': self.sale_order_id.id if self.sale_order_id else False, - 'document_type': 'page_12', - 'file': self.signature_page_12, - 'filename': f'page_12_signature_{self.reference}.png', - 'mimetype': 'image/png', - 'source': 'assessment', - }) - - def _send_completion_notifications(self): - """Send email notifications when assessment is completed""" - self.ensure_one() - - # Send to authorizer - if self.authorizer_id and self.authorizer_id.email: - try: - template = self.env.ref('fusion_authorizer_portal.mail_template_assessment_complete_authorizer', raise_if_not_found=False) - if template: - template.send_mail(self.id, force_send=True) - _logger.info(f"Sent assessment completion email to authorizer {self.authorizer_id.email}") - except Exception as e: - _logger.error(f"Failed to send authorizer notification: {e}") - - # Send to client - if self.client_email: - try: - template = self.env.ref('fusion_authorizer_portal.mail_template_assessment_complete_client', raise_if_not_found=False) - if template: - template.send_mail(self.id, force_send=True) - _logger.info(f"Sent assessment completion email to client {self.client_email}") - except Exception as e: - _logger.error(f"Failed to send client notification: {e}") - - def action_view_documents(self): - """View related documents""" - self.ensure_one() - return { - 'type': 'ir.actions.act_window', - 'name': _('Documents'), - 'res_model': 'fusion.adp.document', - 'view_mode': 'list,form', - 'domain': [('assessment_id', '=', self.id)], - 'context': {'default_assessment_id': self.id}, - } - - def action_view_sale_order(self): - """View the created sale order""" - self.ensure_one() - if not self.sale_order_id: - raise UserError(_('No sale order has been created yet.')) - return { - 'type': 'ir.actions.act_window', - 'name': _('Sale Order'), - 'res_model': 'sale.order', - 'res_id': self.sale_order_id.id, - 'view_mode': 'form', - 'target': 'current', - } - - # ===== PDF TEMPLATE ENGINE INTEGRATION ===== - - def _get_pdf_context(self): - """Return a flat dict of all assessment data for PDF template filling. - - This is the data source for the generic PDF template engine. - Each key can be mapped to a field on any PDF template via field_key. - """ - self.ensure_one() - - ctx = { - # Client biographical - 'client_last_name': self.client_last_name or '', - 'client_first_name': self.client_first_name or '', - 'client_middle_name': self.client_middle_name or '', - 'client_name': self.client_name or '', - 'client_health_card': self.client_health_card or '', - 'client_health_card_version': self.client_health_card_version or '', - 'client_street': self.client_street or '', - 'client_unit': self.client_unit or '', - 'client_city': self.client_city or '', - 'client_state': self.client_state or '', - 'client_postal_code': self.client_postal_code or '', - 'client_phone': self.client_phone or '', - 'client_email': self.client_email or '', - 'client_weight': str(int(self.client_weight)) if self.client_weight else '', - - # Client type - 'client_type': self.client_type or '', - 'client_type_reg': self.client_type == 'reg', - 'client_type_ods': self.client_type == 'ods', - 'client_type_acs': self.client_type == 'acs', - 'client_type_owp': self.client_type == 'owp', - - # Consent & Declaration (Page 11) - 'consent_signed_by': self.consent_signed_by or '', - 'consent_applicant': self.consent_signed_by == 'applicant', - 'consent_agent': self.consent_signed_by == 'agent', - 'consent_declaration_accepted': self.consent_declaration_accepted, - 'consent_date': str(self.consent_date) if self.consent_date else '', - - # Agent info - 'agent_relationship': self.agent_relationship or '', - 'agent_rel_spouse': self.agent_relationship == 'spouse', - 'agent_rel_parent': self.agent_relationship == 'parent', - 'agent_rel_child': self.agent_relationship == 'child', - 'agent_rel_poa': self.agent_relationship == 'power_of_attorney', - 'agent_rel_guardian': self.agent_relationship == 'public_guardian', - 'agent_first_name': self.agent_first_name or '', - 'agent_last_name': self.agent_last_name or '', - 'agent_middle_initial': self.agent_middle_initial or '', - 'agent_unit': self.agent_unit or '', - 'agent_street_number': self.agent_street_number or '', - 'agent_street_name': self.agent_street_name or '', - 'agent_city': self.agent_city or '', - 'agent_province': self.agent_province or '', - 'agent_postal_code': self.agent_postal_code or '', - 'agent_home_phone': self.agent_home_phone or '', - 'agent_business_phone': self.agent_business_phone or '', - 'agent_phone_ext': self.agent_phone_ext or '', - - # Equipment - 'equipment_type': self.equipment_type or '', - 'seat_width': str(self.seat_width) if self.seat_width else '', - 'seat_depth': str(self.seat_depth) if self.seat_depth else '', - 'seat_to_floor_height': str(self.seat_to_floor_height) if self.seat_to_floor_height else '', - 'back_height': str(self.back_height) if self.back_height else '', - 'legrest_length': str(self.legrest_length) if self.legrest_length else '', - 'cane_height': str(self.cane_height) if self.cane_height else '', - - # Dates - 'assessment_start_date': str(self.assessment_start_date) if self.assessment_start_date else '', - 'assessment_end_date': str(self.assessment_end_date) if self.assessment_end_date else '', - 'claim_authorization_date': str(self.claim_authorization_date) if self.claim_authorization_date else '', - - # Reason - 'reason_for_application': self.reason_for_application or '', - - # Reference - 'reference': self.reference or '', - } - - # Authorizer info - if self.authorizer_id: - ctx['authorizer_name'] = self.authorizer_id.name or '' - ctx['authorizer_phone'] = self.authorizer_id.phone or '' - ctx['authorizer_email'] = self.authorizer_id.email or '' - - return ctx - - def _get_pdf_signatures(self): - """Return a dict of signature binaries for PDF template filling.""" - self.ensure_one() - sigs = {} - if self.signature_page_11: - sigs['signature_page_11'] = base64.b64decode(self.signature_page_11) - if self.signature_page_12: - sigs['signature_page_12'] = base64.b64decode(self.signature_page_12) - return sigs - - def generate_template_pdf(self, template_name='adp_page_11'): - """Generate a filled PDF using the named template. - - Args: - template_name: the name field of the fusion.pdf.template record - - Returns: - bytes of the filled PDF, or None if template not found - """ - self.ensure_one() - - template = self.env['fusion.pdf.template'].search([ - ('state', '=', 'active'), - ('name', 'ilike', template_name), - ], limit=1) - - if not template: - _logger.warning("No active PDF template found matching '%s'", template_name) - return None - - context_data = self._get_pdf_context() - signatures = self._get_pdf_signatures() - - try: - pdf_bytes = template.generate_filled_pdf(context_data, signatures) - _logger.info("Generated filled PDF from template '%s' for assessment %s", - template.name, self.reference) - return pdf_bytes - except Exception as e: - _logger.error("Failed to generate PDF for assessment %s: %s", self.reference, e) - return None diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/models/authorizer_comment.py b/fusion_authorizer_portal/fusion_authorizer_portal/models/authorizer_comment.py deleted file mode 100644 index 50fdaea..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/models/authorizer_comment.py +++ /dev/null @@ -1,85 +0,0 @@ -# -*- coding: utf-8 -*- - -from odoo import api, fields, models, _ -import logging - -_logger = logging.getLogger(__name__) - - -class AuthorizerComment(models.Model): - _name = 'fusion.authorizer.comment' - _description = 'Authorizer/Sales Rep Comment' - _order = 'create_date desc' - _rec_name = 'display_name' - - sale_order_id = fields.Many2one( - 'sale.order', - string='Sale Order', - required=True, - ondelete='cascade', - index=True, - ) - - assessment_id = fields.Many2one( - 'fusion.assessment', - string='Assessment', - ondelete='cascade', - index=True, - ) - - author_id = fields.Many2one( - 'res.partner', - string='Author', - required=True, - default=lambda self: self.env.user.partner_id, - index=True, - ) - - author_user_id = fields.Many2one( - 'res.users', - string='Author User', - default=lambda self: self.env.user, - index=True, - ) - - comment = fields.Text( - string='Comment', - required=True, - ) - - comment_type = fields.Selection([ - ('general', 'General Comment'), - ('question', 'Question'), - ('update', 'Status Update'), - ('internal', 'Internal Note'), - ], string='Type', default='general') - - is_internal = fields.Boolean( - string='Internal Only', - default=False, - help='If checked, this comment will not be visible to portal users', - ) - - display_name = fields.Char( - string='Display Name', - compute='_compute_display_name', - store=True, - ) - - @api.depends('author_id', 'create_date') - def _compute_display_name(self): - for comment in self: - if comment.author_id and comment.create_date: - comment.display_name = f"{comment.author_id.name} - {comment.create_date.strftime('%Y-%m-%d %H:%M')}" - else: - comment.display_name = _('New Comment') - - @api.model_create_multi - def create(self, vals_list): - """Override create to set author from current user if not provided""" - for vals in vals_list: - if not vals.get('author_id'): - vals['author_id'] = self.env.user.partner_id.id - if not vals.get('author_user_id'): - vals['author_user_id'] = self.env.user.id - return super().create(vals_list) diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/models/pdf_template.py b/fusion_authorizer_portal/fusion_authorizer_portal/models/pdf_template.py deleted file mode 100644 index ab2de8a..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/models/pdf_template.py +++ /dev/null @@ -1,328 +0,0 @@ -# -*- coding: utf-8 -*- -# Fusion PDF Template Engine -# Generic system for filling any funding agency's PDF forms - -import base64 -import logging -from io import BytesIO - -from odoo import api, fields, models, _ -from odoo.exceptions import UserError - -_logger = logging.getLogger(__name__) - - -class FusionPdfTemplate(models.Model): - _name = 'fusion.pdf.template' - _description = 'PDF Form Template' - _order = 'category, name' - - name = fields.Char(string='Template Name', required=True) - category = fields.Selection([ - ('adp', 'ADP - Assistive Devices Program'), - ('mod', 'March of Dimes'), - ('odsp', 'ODSP'), - ('hardship', 'Hardship Funding'), - ('other', 'Other'), - ], string='Funding Agency', required=True, default='adp') - version = fields.Char(string='Form Version', default='1.0') - state = fields.Selection([ - ('draft', 'Draft'), - ('active', 'Active'), - ('archived', 'Archived'), - ], string='Status', default='draft', tracking=True) - - # The actual PDF template file - pdf_file = fields.Binary(string='PDF Template', required=True, attachment=True) - pdf_filename = fields.Char(string='PDF Filename') - page_count = fields.Integer( - string='Page Count', - compute='_compute_page_count', - store=True, - ) - - # Page preview images for the visual editor - preview_ids = fields.One2many( - 'fusion.pdf.template.preview', 'template_id', - string='Page Previews', - ) - - # Field positions configured via the visual editor - field_ids = fields.One2many( - 'fusion.pdf.template.field', 'template_id', - string='Template Fields', - ) - field_count = fields.Integer( - string='Fields', - compute='_compute_field_count', - ) - - notes = fields.Text( - string='Notes', - help='Usage notes, which assessments/forms use this template', - ) - - def write(self, vals): - res = super().write(vals) - if 'pdf_file' in vals and vals['pdf_file']: - for rec in self: - try: - rec.action_generate_previews() - except Exception as e: - _logger.warning("Auto preview generation failed for %s: %s", rec.name, e) - return res - - @api.model_create_multi - def create(self, vals_list): - records = super().create(vals_list) - for rec in records: - if rec.pdf_file: - try: - rec.action_generate_previews() - except Exception as e: - _logger.warning("Auto preview generation failed for %s: %s", rec.name, e) - return records - - @api.depends('pdf_file') - def _compute_page_count(self): - for rec in self: - if rec.pdf_file: - try: - from odoo.tools.pdf import PdfFileReader - pdf_data = base64.b64decode(rec.pdf_file) - reader = PdfFileReader(BytesIO(pdf_data)) - rec.page_count = reader.getNumPages() - except Exception as e: - _logger.warning("Could not read PDF page count: %s", e) - rec.page_count = 0 - else: - rec.page_count = 0 - - def action_generate_previews(self): - """Generate PNG preview images from the PDF using poppler (pdftoppm). - Falls back gracefully if the PDF is protected or poppler is not available. - """ - self.ensure_one() - if not self.pdf_file: - raise UserError(_('Please upload a PDF file first.')) - - import subprocess - import tempfile - import os - - pdf_data = base64.b64decode(self.pdf_file) - - try: - with tempfile.TemporaryDirectory() as tmpdir: - pdf_path = os.path.join(tmpdir, 'template.pdf') - with open(pdf_path, 'wb') as f: - f.write(pdf_data) - - # Use pdftoppm to convert each page to PNG - result = subprocess.run( - ['pdftoppm', '-png', '-r', '200', pdf_path, os.path.join(tmpdir, 'page')], - capture_output=True, timeout=30, - ) - - if result.returncode != 0: - stderr = result.stderr.decode('utf-8', errors='replace') - _logger.warning("pdftoppm failed: %s", stderr) - raise UserError(_( - 'Could not generate previews automatically. ' - 'The PDF may be protected. Please upload preview images manually ' - 'in the Page Previews tab (screenshots of each page).' - )) - - # Find generated PNG files - png_files = sorted([ - f for f in os.listdir(tmpdir) - if f.startswith('page-') and f.endswith('.png') - ]) - - if not png_files: - raise UserError(_('No pages were generated. Please upload preview images manually.')) - - # Delete existing previews - self.preview_ids.unlink() - - # Create preview records - for idx, png_file in enumerate(png_files): - png_path = os.path.join(tmpdir, png_file) - with open(png_path, 'rb') as f: - image_data = base64.b64encode(f.read()) - - self.env['fusion.pdf.template.preview'].create({ - 'template_id': self.id, - 'page': idx + 1, - 'image': image_data, - 'image_filename': f'page_{idx + 1}.png', - }) - - _logger.info("Generated %d preview images for template %s", len(png_files), self.name) - - except subprocess.TimeoutExpired: - raise UserError(_('PDF conversion timed out. Please upload preview images manually.')) - except FileNotFoundError: - raise UserError(_( - 'poppler-utils (pdftoppm) is not installed on the server. ' - 'Please upload preview images manually in the Page Previews tab.' - )) - - @api.depends('field_ids') - def _compute_field_count(self): - for rec in self: - rec.field_count = len(rec.field_ids) - - def action_activate(self): - """Set template to active.""" - self.ensure_one() - if not self.pdf_file: - raise UserError(_('Please upload a PDF file before activating.')) - self.state = 'active' - - def action_archive(self): - """Archive the template.""" - self.ensure_one() - self.state = 'archived' - - def action_reset_draft(self): - """Reset to draft.""" - self.ensure_one() - self.state = 'draft' - - def action_open_field_editor(self): - """Open the visual field position editor.""" - self.ensure_one() - return { - 'type': 'ir.actions.act_url', - 'url': f'/fusion/pdf-editor/{self.id}', - 'target': 'new', - } - - def generate_filled_pdf(self, context_data, signatures=None): - """Generate a filled PDF using this template and the provided data. - - Args: - context_data: flat dict of {field_key: value} - signatures: dict of {field_key: binary_png} for signature fields - - Returns: - bytes of the filled PDF - """ - self.ensure_one() - if not self.pdf_file: - raise UserError(_('Template has no PDF file.')) - if self.state != 'active': - _logger.warning("Generating PDF from non-active template %s", self.name) - - from ..utils.pdf_filler import PDFTemplateFiller - - template_bytes = base64.b64decode(self.pdf_file) - - # Build fields_by_page dict - fields_by_page = {} - for field in self.field_ids.filtered(lambda f: f.is_active): - page = field.page - if page not in fields_by_page: - fields_by_page[page] = [] - fields_by_page[page].append({ - 'field_name': field.name, - 'field_key': field.field_key or field.name, - 'pos_x': field.pos_x, - 'pos_y': field.pos_y, - 'width': field.width, - 'height': field.height, - 'field_type': field.field_type, - 'font_size': field.font_size, - 'font_name': field.font_name or 'Helvetica', - 'text_align': field.text_align or 'left', - }) - - return PDFTemplateFiller.fill_template( - template_bytes, fields_by_page, context_data, signatures - ) - - -class FusionPdfTemplatePreview(models.Model): - _name = 'fusion.pdf.template.preview' - _description = 'PDF Template Page Preview' - _order = 'page' - - template_id = fields.Many2one( - 'fusion.pdf.template', string='Template', - required=True, ondelete='cascade', index=True, - ) - page = fields.Integer(string='Page Number', required=True, default=1) - image = fields.Binary(string='Page Image (PNG)', attachment=True) - image_filename = fields.Char(string='Image Filename') - - -class FusionPdfTemplateField(models.Model): - _name = 'fusion.pdf.template.field' - _description = 'PDF Template Field' - _order = 'page, sequence' - - template_id = fields.Many2one( - 'fusion.pdf.template', string='Template', - required=True, ondelete='cascade', index=True, - ) - name = fields.Char( - string='Field Name', required=True, - help='Internal identifier, e.g. client_last_name', - ) - label = fields.Char( - string='Display Label', - help='Human-readable label shown in the editor, e.g. "Last Name"', - ) - sequence = fields.Integer(string='Sequence', default=10) - page = fields.Integer(string='Page', default=1, required=True) - - # Percentage-based positioning (0.0 to 1.0) -- same as sign.item - pos_x = fields.Float( - string='Position X', digits=(4, 3), - help='Horizontal position as ratio (0.0 = left edge, 1.0 = right edge)', - ) - pos_y = fields.Float( - string='Position Y', digits=(4, 3), - help='Vertical position as ratio (0.0 = top edge, 1.0 = bottom edge)', - ) - width = fields.Float( - string='Width', digits=(4, 3), default=0.150, - help='Width as ratio of page width', - ) - height = fields.Float( - string='Height', digits=(4, 3), default=0.015, - help='Height as ratio of page height', - ) - - # Rendering settings - field_type = fields.Selection([ - ('text', 'Text'), - ('checkbox', 'Checkbox'), - ('signature', 'Signature Image'), - ('date', 'Date'), - ], string='Field Type', default='text', required=True) - font_size = fields.Float(string='Font Size', default=10.0) - font_name = fields.Selection([ - ('Helvetica', 'Helvetica'), - ('Courier', 'Courier'), - ('Times-Roman', 'Times Roman'), - ], string='Font', default='Helvetica') - text_align = fields.Selection([ - ('left', 'Left'), - ('center', 'Center'), - ('right', 'Right'), - ], string='Text Alignment', default='left') - - # Data mapping - field_key = fields.Char( - string='Data Key', - help='Key to look up in the data context dict.\n' - 'Examples: client_last_name, client_health_card, consent_date, signature_page_11\n' - 'The generating code passes a flat dict of all available data.', - ) - default_value = fields.Char( - string='Default Value', - help='Fallback value if field_key returns empty', - ) - is_active = fields.Boolean(string='Active', default=True) diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/models/res_partner.py b/fusion_authorizer_portal/fusion_authorizer_portal/models/res_partner.py deleted file mode 100644 index 129a5a8..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/models/res_partner.py +++ /dev/null @@ -1,764 +0,0 @@ -# -*- coding: utf-8 -*- - -from odoo import api, fields, models, _ -from odoo.exceptions import UserError -from markupsafe import Markup, escape -import logging - -_logger = logging.getLogger(__name__) - - -class ResPartner(models.Model): - _inherit = 'res.partner' - - # Portal Role Flags - is_authorizer = fields.Boolean( - string='Is Authorizer', - default=False, - help='Check if this partner is an Authorizer (OT/Therapist) who can access the Authorizer Portal', - ) - is_sales_rep_portal = fields.Boolean( - string='Is Sales Rep (Portal)', - default=False, - help='Check if this partner is a Sales Rep who can access the Sales Rep Portal', - ) - is_client_portal = fields.Boolean( - string='Is Client (Portal)', - default=False, - help='Check if this partner can access the Funding Claims Portal to view their claims', - ) - is_technician_portal = fields.Boolean( - string='Is Technician (Portal)', - default=False, - help='Check if this partner is a Field Technician who can access the Technician Portal for deliveries', - ) - - # Computed field for assigned deliveries (for technicians) - assigned_delivery_count = fields.Integer( - string='Assigned Deliveries', - compute='_compute_assigned_delivery_count', - help='Number of sale orders assigned to this partner as delivery technician', - ) - - # Geocoding coordinates (for travel time calculations) - x_fc_latitude = fields.Float( - string='Latitude', - digits=(10, 7), - help='GPS latitude of the partner address (auto-geocoded)', - ) - x_fc_longitude = fields.Float( - string='Longitude', - digits=(10, 7), - help='GPS longitude of the partner address (auto-geocoded)', - ) - - # Link to portal user account - authorizer_portal_user_id = fields.Many2one( - 'res.users', - string='Portal User Account', - help='The portal user account linked to this authorizer/sales rep', - copy=False, - ) - - # Portal access status tracking - portal_access_status = fields.Selection( - selection=[ - ('no_access', 'No Access'), - ('invited', 'Invited'), - ('active', 'Active'), - ], - string='Portal Status', - compute='_compute_portal_access_status', - store=True, - help='Tracks portal access: No Access = no portal user, Invited = user created but never logged in, Active = user has logged in', - ) - - # Computed counts - assigned_case_count = fields.Integer( - string='Assigned Cases', - compute='_compute_assigned_case_count', - help='Number of sale orders assigned to this partner as authorizer', - ) - - assessment_count = fields.Integer( - string='Assessments', - compute='_compute_assessment_count', - help='Number of assessments linked to this partner', - ) - - @api.depends('authorizer_portal_user_id', 'authorizer_portal_user_id.login_date') - def _compute_portal_access_status(self): - """Compute portal access status based on user account and login history.""" - for partner in self: - if not partner.authorizer_portal_user_id: - partner.portal_access_status = 'no_access' - elif partner.authorizer_portal_user_id.login_date: - partner.portal_access_status = 'active' - else: - partner.portal_access_status = 'invited' - - @api.depends('is_authorizer') - def _compute_assigned_case_count(self): - """Count sale orders where this partner is the authorizer""" - SaleOrder = self.env['sale.order'].sudo() - for partner in self: - if partner.is_authorizer: - # Use x_fc_authorizer_id field from fusion_claims - domain = [('x_fc_authorizer_id', '=', partner.id)] - partner.assigned_case_count = SaleOrder.search_count(domain) - else: - partner.assigned_case_count = 0 - - @api.depends('is_authorizer', 'is_sales_rep_portal') - def _compute_assessment_count(self): - """Count assessments where this partner is involved""" - Assessment = self.env['fusion.assessment'].sudo() - for partner in self: - count = 0 - if partner.is_authorizer: - count += Assessment.search_count([('authorizer_id', '=', partner.id)]) - if partner.is_sales_rep_portal and partner.authorizer_portal_user_id: - count += Assessment.search_count([('sales_rep_id', '=', partner.authorizer_portal_user_id.id)]) - partner.assessment_count = count - - @api.depends('is_technician_portal') - def _compute_assigned_delivery_count(self): - """Count sale orders assigned to this partner as delivery technician""" - SaleOrder = self.env['sale.order'].sudo() - for partner in self: - if partner.is_technician_portal and partner.authorizer_portal_user_id: - # Technicians are linked via user_id in x_fc_delivery_technician_ids - domain = [('x_fc_delivery_technician_ids', 'in', [partner.authorizer_portal_user_id.id])] - partner.assigned_delivery_count = SaleOrder.search_count(domain) - else: - partner.assigned_delivery_count = 0 - - def _assign_portal_role_groups(self, portal_user): - """Assign role-specific portal groups to a portal user based on contact checkboxes.""" - groups_to_add = [] - if self.is_technician_portal: - g = self.env.ref('fusion_authorizer_portal.group_technician_portal', raise_if_not_found=False) - if g and g not in portal_user.group_ids: - groups_to_add.append((4, g.id)) - if self.is_authorizer: - g = self.env.ref('fusion_authorizer_portal.group_authorizer_portal', raise_if_not_found=False) - if g and g not in portal_user.group_ids: - groups_to_add.append((4, g.id)) - if self.is_sales_rep_portal: - g = self.env.ref('fusion_authorizer_portal.group_sales_rep_portal', raise_if_not_found=False) - if g and g not in portal_user.group_ids: - groups_to_add.append((4, g.id)) - if groups_to_add: - portal_user.sudo().write({'group_ids': groups_to_add}) - - def _assign_internal_role_groups(self, internal_user): - """Assign backend groups to an internal user based on contact checkboxes. - Also sets x_fc_is_field_staff so the user appears in technician/staff dropdowns. - Returns list of group names that were added.""" - added = [] - needs_field_staff = False - - if self.is_technician_portal: - # Add Field Technician group - g = self.env.ref('fusion_claims.group_field_technician', raise_if_not_found=False) - if g and g not in internal_user.group_ids: - internal_user.sudo().write({'group_ids': [(4, g.id)]}) - added.append('Field Technician') - needs_field_staff = True - - if self.is_sales_rep_portal: - # Internal sales reps don't need a portal group but should show in staff dropdowns - added.append('Sales Rep (internal)') - needs_field_staff = True - - if self.is_authorizer: - # Internal authorizers already have full backend access - added.append('Authorizer (internal)') - - # Mark as field staff so they appear in technician/delivery dropdowns - if needs_field_staff and hasattr(internal_user, 'x_fc_is_field_staff'): - if not internal_user.x_fc_is_field_staff: - internal_user.sudo().write({'x_fc_is_field_staff': True}) - added.append('Field Staff') - - return added - - def action_grant_portal_access(self): - """Grant portal access to this partner, or update permissions for existing users.""" - self.ensure_one() - - if not self.email: - raise UserError(_('Please set an email address before granting portal access.')) - - email_normalized = self.email.strip().lower() - - # ── Step 1: Find existing user ── - # Search by partner_id first (direct link) - existing_user = self.env['res.users'].sudo().search([ - ('partner_id', '=', self.id), - ], limit=1) - - # If not found by partner, search by email (handles internal users - # whose auto-created partner is different from this contact) - if not existing_user: - existing_user = self.env['res.users'].sudo().search([ - '|', - ('login', '=ilike', email_normalized), - ('email', '=ilike', email_normalized), - ], limit=1) - - # ── Step 2: Handle existing user ── - if existing_user: - from datetime import datetime - self.authorizer_portal_user_id = existing_user - - if not existing_user.share: - # ── INTERNAL user: assign backend groups, do NOT add portal ── - groups_added = self._assign_internal_role_groups(existing_user) - groups_text = ', '.join(groups_added) if groups_added else 'No new groups needed' - chatter_msg = Markup( - '
    ' - '
    ' - ' Internal User — Permissions Updated' - '
    ' - '
    ' - '' - f'' - f'' - f'' - f'' - f'' - f'' - '
    User:{escape(existing_user.name)} (ID: {existing_user.id})
    Login:{escape(existing_user.login)}
    Type:Internal (backend) user
    Groups added:{escape(groups_text)}
    Updated by:{escape(self.env.user.name)}
    Updated at:{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
    ' - '
    ' - '
    ' - ) - self.message_post(body=chatter_msg, message_type='notification', subtype_xmlid='mail.mt_note') - notify_msg = _('Internal user detected. Backend permissions updated: %s') % groups_text - else: - # ── Existing PORTAL user: ensure role groups are set ── - portal_group = self.env.ref('base.group_portal', raise_if_not_found=False) - if portal_group and portal_group not in existing_user.group_ids: - existing_user.sudo().write({'group_ids': [(4, portal_group.id)]}) - self._assign_portal_role_groups(existing_user) - chatter_msg = Markup( - '
    ' - '
    ' - ' Portal Access — Roles Updated' - '
    ' - '
    ' - '' - f'' - f'' - f'' - f'' - f'' - '
    Status:Portal user exists — roles updated
    User:{escape(existing_user.name)} (ID: {existing_user.id})
    Login:{escape(existing_user.login)}
    Checked by:{escape(self.env.user.name)}
    Checked at:{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
    ' - '
    ' - '
    ' - ) - self.message_post(body=chatter_msg, message_type='notification', subtype_xmlid='mail.mt_note') - notify_msg = _('Portal user already exists — role groups updated (User ID: %s).') % existing_user.id - - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': _('Access Updated'), - 'message': notify_msg, - 'type': 'info', - 'sticky': False, - } - } - - # No existing user found - create portal user directly - portal_group = self.env.ref('base.group_portal', raise_if_not_found=False) - if not portal_group: - raise UserError(_('Portal group not found. Please contact administrator.')) - - try: - # Create user without groups first (Odoo 17+ compatibility) - portal_user = self.env['res.users'].sudo().with_context(no_reset_password=True, knowledge_skip_onboarding_article=True).create({ - 'name': self.name, - 'login': email_normalized, - 'email': self.email, - 'partner_id': self.id, - 'active': True, - }) - # Add portal group after creation - portal_user.sudo().write({ - 'group_ids': [(6, 0, [portal_group.id])], - }) - # Assign role-specific portal groups based on contact checkboxes - self._assign_portal_role_groups(portal_user) - self.authorizer_portal_user_id = portal_user - - # Create welcome Knowledge article for the user - self._create_welcome_article(portal_user) - - # Send professional portal invitation email - email_sent = False - try: - email_sent = self._send_portal_invitation_email(portal_user) - except Exception as mail_error: - _logger.warning(f"Could not send portal invitation email: {mail_error}") - - # Post message in chatter - sent_by = self.env.user.name - from datetime import datetime - sent_at = datetime.now().strftime('%Y-%m-%d %H:%M:%S') - - if email_sent: - status_text = 'Invitation email sent successfully' - border_color = '#28a745' - header_bg = '#28a745' - body_bg = '#f0fff0' - else: - status_text = 'User created but email could not be sent' - border_color = '#fd7e14' - header_bg = '#fd7e14' - body_bg = '#fff8f0' - - chatter_msg = Markup( - f'
    ' - f'
    ' - ' Portal Access Granted' - '
    ' - f'
    ' - '' - f'' - f'' - f'' - f'' - f'' - '
    Email:{self.email}
    Sent by:{sent_by}
    Sent at:{sent_at}
    User ID:{portal_user.id}
    Status:{status_text}
    ' - '
    ' - '
    ' - ) - - self.message_post(body=chatter_msg, message_type='notification', subtype_xmlid='mail.mt_note') - - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': _('Portal Access Granted'), - 'message': _('Portal user created for %s. A password reset email has been sent.') % self.email, - 'type': 'success', - 'sticky': False, - } - } - except Exception as e: - _logger.error(f"Failed to create portal user: {e}") - raise UserError(_('Failed to create portal user: %s') % str(e)) - - def _create_welcome_article(self, portal_user): - """Create a role-specific welcome Knowledge article for the new portal user. - - Determines the role from partner flags and renders the matching template. - The article is private to the user and set as a favorite. - """ - self.ensure_one() - - # Check if Knowledge module is installed - if 'knowledge.article' not in self.env: - _logger.info("Knowledge module not installed, skipping welcome article") - return - - # Determine role and template - if self.is_technician_portal: - template_xmlid = 'fusion_authorizer_portal.welcome_article_technician' - icon = '🔧' - title = f"Welcome {self.name} - Technician Portal" - elif self.is_authorizer: - template_xmlid = 'fusion_authorizer_portal.welcome_article_authorizer' - icon = '📋' - title = f"Welcome {self.name} - Authorizer Portal" - elif self.is_sales_rep_portal: - template_xmlid = 'fusion_authorizer_portal.welcome_article_sales_rep' - icon = '💼' - title = f"Welcome {self.name} - Sales Portal" - elif self.is_client_portal: - template_xmlid = 'fusion_authorizer_portal.welcome_article_client' - icon = '👤' - title = f"Welcome {self.name}" - else: - template_xmlid = 'fusion_authorizer_portal.welcome_article_client' - icon = '👋' - title = f"Welcome {self.name}" - - company = self.env.company - render_ctx = { - 'user_name': self.name or 'Valued Partner', - 'company_name': company.name or 'Our Company', - 'company_email': company.email or '', - 'company_phone': company.phone or '', - } - - try: - body = self.env['ir.qweb']._render( - template_xmlid, - render_ctx, - minimal_qcontext=True, - raise_if_not_found=False, - ) - - if not body: - _logger.warning(f"Welcome article template not found: {template_xmlid}") - return - - article = self.env['knowledge.article'].sudo().create({ - 'name': title, - 'icon': icon, - 'body': body, - 'internal_permission': 'none', - 'is_article_visible_by_everyone': False, - 'article_member_ids': [(0, 0, { - 'partner_id': self.id, - 'permission': 'write', - })], - 'favorite_ids': [(0, 0, { - 'sequence': 0, - 'user_id': portal_user.id, - })], - }) - - _logger.info(f"Created welcome article '{title}' (ID: {article.id}) for {self.name}") - - except Exception as e: - _logger.warning(f"Failed to create welcome article for {self.name}: {e}") - - def _send_portal_invitation_email(self, portal_user, is_resend=False): - """Send a professional portal invitation email to the partner. - - Generates a signup URL and sends a branded invitation email - instead of the generic Odoo password reset email. - - Returns True if email was sent successfully, False otherwise. - """ - self.ensure_one() - - # Generate signup token and build URL - partner = portal_user.sudo().partner_id - - # Set signup type to 'signup' - this auto-logs in after password is set - partner.signup_prepare(signup_type='signup') - - # Use Odoo's built-in URL generation with signup_email context - # so the email is pre-filled and user just sets password - signup_urls = partner.with_context( - signup_valid=True, - create_user=True, - )._get_signup_url_for_action() - signup_url = signup_urls.get(partner.id) - - if not signup_url: - base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') - signup_url = f"{base_url}/web/reset_password" - _logger.warning(f"Could not generate signup URL for {self.email}, using generic reset page") - - company = self.env.company - company_name = company.name or 'Our Company' - base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') - partner_name = self.name or 'Valued Partner' - - subject = f"You're Invited to the {company_name} Portal" if not is_resend else f"Portal Access Reminder - {company_name}" - - invite_text = 'We are pleased to invite you' if not is_resend else 'This is a reminder that you have been invited' - body_html = ( - f'
    ' - f'
    ' - f'
    ' - f'

    {company_name}

    ' - f'

    Portal Invitation

    ' - f'

    ' - f'Dear {partner_name}, {invite_text} to access the {company_name} Portal.

    ' - f'

    ' - f'With the portal you can:

    ' - f'
      ' - f'
    • View and manage your assigned cases
    • ' - f'
    • Complete assessments online
    • ' - f'
    • Track application status and progress
    • ' - f'
    • Access important documents
    ' - f'

    ' - f'' - f'Accept Invitation & Set Password

    ' - f'

    ' - f'If the button does not work, copy this link: ' - f'{signup_url}

    ' - f'
    ' - f'

    ' - f'After setting your password, access the portal anytime at: ' - f'{base_url}/my

    ' - f'

    ' - f'Best regards,
    {company_name} Team

    ' - f'
    ' - f'
    ' - f'

    ' - f'This is an automated message from {company_name}.

    ' - ) - - mail_values = { - 'subject': subject, - 'body_html': body_html, - 'email_to': self.email, - 'email_from': company.email or self.env.user.email or 'noreply@example.com', - 'auto_delete': True, - } - - try: - mail = self.env['mail.mail'].sudo().create(mail_values) - mail.send() - _logger.info(f"Portal invitation email sent to {self.email}") - return True - except Exception as e: - _logger.error(f"Failed to send portal invitation email to {self.email}: {e}") - return False - - def action_resend_portal_invitation(self): - """Resend portal invitation email to an existing portal user.""" - self.ensure_one() - - if not self.authorizer_portal_user_id: - raise UserError(_('No portal user found for this contact. Use "Send Portal Invitation" instead.')) - - portal_user = self.authorizer_portal_user_id - - # Send professional portal invitation email - email_sent = False - try: - email_sent = self._send_portal_invitation_email(portal_user, is_resend=True) - except Exception as mail_error: - _logger.warning(f"Could not send portal invitation email: {mail_error}") - - # Post in chatter - from datetime import datetime - sent_by = self.env.user.name - sent_at = datetime.now().strftime('%Y-%m-%d %H:%M:%S') - - if email_sent: - chatter_msg = Markup( - '
    ' - '
    ' - ' Portal Invitation Resent' - '
    ' - '
    ' - '' - f'' - f'' - f'' - f'' - '' - '' - '
    Email:{self.email}
    Sent by:{sent_by}
    Sent at:{sent_at}
    User ID:{portal_user.id}
    Status:Invitation email resent successfully
    ' - '
    ' - '
    ' - ) - else: - chatter_msg = Markup( - '
    ' - '
    ' - ' Portal Invitation Resend Attempted' - '
    ' - '
    ' - '' - f'' - f'' - f'' - '' - '' - '
    Email:{self.email}
    Sent by:{sent_by}
    Sent at:{sent_at}
    Status:Email could not be sent - check mail configuration
    ' - '
    ' - '
    ' - ) - - self.message_post(body=chatter_msg, message_type='notification', subtype_xmlid='mail.mt_note') - - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': _('Portal Invitation Resent') if email_sent else _('Email Failed'), - 'message': _('Portal invitation resent to %s.') % self.email if email_sent else _('Could not send email. Check mail configuration.'), - 'type': 'success' if email_sent else 'warning', - 'sticky': False, - } - } - - def action_view_assigned_cases(self): - """Open the list of assigned sale orders""" - self.ensure_one() - return { - 'type': 'ir.actions.act_window', - 'name': _('Assigned Cases'), - 'res_model': 'sale.order', - 'view_mode': 'list,form', - 'domain': [('x_fc_authorizer_id', '=', self.id)], - 'context': {'default_x_fc_authorizer_id': self.id}, - } - - def action_view_assessments(self): - """Open the list of assessments for this partner""" - self.ensure_one() - domain = [] - if self.is_authorizer: - domain = [('authorizer_id', '=', self.id)] - elif self.is_sales_rep_portal and self.authorizer_portal_user_id: - domain = [('sales_rep_id', '=', self.authorizer_portal_user_id.id)] - - return { - 'type': 'ir.actions.act_window', - 'name': _('Assessments'), - 'res_model': 'fusion.assessment', - 'view_mode': 'list,form', - 'domain': domain, - } - - # ==================== BATCH ACTIONS ==================== - - def action_mark_as_authorizer(self): - """Batch action to mark selected contacts as authorizers""" - self.write({'is_authorizer': True}) - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': _('Authorizers Updated'), - 'message': _('%d contact(s) marked as authorizer.') % len(self), - 'type': 'success', - 'sticky': False, - } - } - - def action_batch_send_portal_invitation(self): - """Batch action to send portal invitations to selected authorizers""" - sent_count = 0 - skipped_no_email = 0 - skipped_not_authorizer = 0 - skipped_has_access = 0 - errors = [] - - for partner in self: - if not partner.is_authorizer: - skipped_not_authorizer += 1 - continue - if not partner.email: - skipped_no_email += 1 - continue - if partner.authorizer_portal_user_id: - skipped_has_access += 1 - continue - - try: - partner.action_grant_portal_access() - sent_count += 1 - except Exception as e: - errors.append(f"{partner.name}: {str(e)}") - - # Build result message - messages = [] - if sent_count: - messages.append(_('%d invitation(s) sent successfully.') % sent_count) - if skipped_not_authorizer: - messages.append(_('%d skipped (not marked as authorizer).') % skipped_not_authorizer) - if skipped_no_email: - messages.append(_('%d skipped (no email).') % skipped_no_email) - if skipped_has_access: - messages.append(_('%d skipped (already has portal access).') % skipped_has_access) - if errors: - messages.append(_('%d error(s) occurred.') % len(errors)) - - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': _('Portal Invitations'), - 'message': ' '.join(messages), - 'type': 'success' if sent_count and not errors else 'warning' if not errors else 'danger', - 'sticky': True if errors else False, - } - } - - def action_mark_and_send_invitation(self): - """Combined action: mark as authorizer and send invitation""" - self.action_mark_as_authorizer() - return self.action_batch_send_portal_invitation() - - def action_view_assigned_deliveries(self): - """Open the list of assigned deliveries for technician""" - self.ensure_one() - if not self.authorizer_portal_user_id: - raise UserError(_('This partner does not have a portal user account.')) - return { - 'type': 'ir.actions.act_window', - 'name': _('Assigned Deliveries'), - 'res_model': 'sale.order', - 'view_mode': 'list,form', - 'domain': [('x_fc_delivery_technician_ids', 'in', [self.authorizer_portal_user_id.id])], - } - - def action_mark_as_technician(self): - """Batch action to mark selected contacts as technicians""" - self.write({'is_technician_portal': True}) - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': _('Technicians Updated'), - 'message': _('%d contact(s) marked as technician.') % len(self), - 'type': 'success', - 'sticky': False, - } - } - - # ------------------------------------------------------------------ - # GEOCODING - # ------------------------------------------------------------------ - - def _geocode_address(self): - """Geocode partner address using Google Geocoding API and cache lat/lng.""" - import requests as http_requests - api_key = self.env['ir.config_parameter'].sudo().get_param( - 'fusion_claims.google_maps_api_key', '' - ) - if not api_key: - return - - for partner in self: - parts = [partner.street, partner.city, - partner.state_id.name if partner.state_id else '', - partner.zip] - address = ', '.join([p for p in parts if p]) - if not address: - continue - try: - resp = http_requests.get( - 'https://maps.googleapis.com/maps/api/geocode/json', - params={'address': address, 'key': api_key, 'region': 'ca'}, - timeout=10, - ) - data = resp.json() - if data.get('status') == 'OK' and data.get('results'): - loc = data['results'][0]['geometry']['location'] - partner.write({ - 'x_fc_latitude': loc['lat'], - 'x_fc_longitude': loc['lng'], - }) - except Exception as e: - _logger.warning(f"Geocoding failed for partner {partner.id}: {e}") - - def write(self, vals): - """Override write to auto-geocode when address changes.""" - res = super().write(vals) - address_fields = {'street', 'city', 'state_id', 'zip', 'country_id'} - if address_fields & set(vals.keys()): - # Check if distance matrix is enabled before geocoding - enabled = self.env['ir.config_parameter'].sudo().get_param( - 'fusion_claims.google_distance_matrix_enabled', False - ) - if enabled: - self._geocode_address() - return res diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/models/res_users.py b/fusion_authorizer_portal/fusion_authorizer_portal/models/res_users.py deleted file mode 100644 index 0e09d01..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/models/res_users.py +++ /dev/null @@ -1,119 +0,0 @@ -# -*- coding: utf-8 -*- - -from odoo import api, models, _ -from odoo.exceptions import UserError -import logging - -_logger = logging.getLogger(__name__) - - -class PortalWizardUser(models.TransientModel): - """Override standard portal wizard to handle internal users with Fusion roles.""" - _inherit = 'portal.wizard.user' - - def action_grant_access(self): - """Override: Handle Fusion portal roles when granting portal access. - - Internal users with Fusion roles: assign backend groups, skip portal. - - Portal users with Fusion roles: standard flow + assign role groups. - """ - self.ensure_one() - partner = self.partner_id - - # Check if the partner has any Fusion portal flags - has_fusion_role = getattr(partner, 'is_technician_portal', False) or \ - getattr(partner, 'is_authorizer', False) or \ - getattr(partner, 'is_sales_rep_portal', False) - - # Find the linked user - user = self.user_id - if user and user._is_internal() and has_fusion_role: - # Internal user with Fusion roles -- assign backend groups, no portal - partner._assign_internal_role_groups(user) - partner.authorizer_portal_user_id = user - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': _('Internal User Updated'), - 'message': _('%s is an internal user. Backend permissions updated (no portal access needed).') % partner.name, - 'type': 'info', - 'sticky': True, - } - } - - # Standard Odoo portal flow (creates user, sends email, etc.) - result = super().action_grant_access() - - # After standard flow, assign Fusion portal role groups - if has_fusion_role: - portal_user = self.user_id - if not portal_user: - # Fallback: find the user that was just created - portal_user = self.env['res.users'].sudo().search([ - ('partner_id', '=', partner.id), - ('share', '=', True), - ('active', '=', True), - ], limit=1) - if portal_user: - partner._assign_portal_role_groups(portal_user) - if not partner.authorizer_portal_user_id: - partner.authorizer_portal_user_id = portal_user - _logger.info("Assigned Fusion portal role groups to user %s (partner: %s)", - portal_user.login, partner.name) - - return result - - -class ResUsers(models.Model): - _inherit = 'res.users' - - def _generate_tutorial_articles(self): - """Override to create custom welcome articles for internal staff - instead of the default Odoo Knowledge onboarding article. - """ - if 'knowledge.article' not in self.env: - return super()._generate_tutorial_articles() - - for user in self: - company = user.company_id or self.env.company - render_ctx = { - 'user_name': user.name or 'Team Member', - 'company_name': company.name or 'Our Company', - 'company_email': company.email or '', - 'company_phone': company.phone or '', - } - - try: - body = self.env['ir.qweb']._render( - 'fusion_authorizer_portal.welcome_article_internal', - render_ctx, - minimal_qcontext=True, - raise_if_not_found=False, - ) - - if not body: - _logger.warning("Internal staff welcome template not found, using default") - return super()._generate_tutorial_articles() - - self.env['knowledge.article'].sudo().create({ - 'name': f"Welcome {user.name} - {company.name}", - 'icon': '🏢', - 'body': body, - 'internal_permission': 'none', - 'is_article_visible_by_everyone': False, - 'article_member_ids': [(0, 0, { - 'partner_id': user.partner_id.id, - 'permission': 'write', - })], - 'favorite_ids': [(0, 0, { - 'sequence': 0, - 'user_id': user.id, - })], - }) - - _logger.info(f"Created custom welcome article for internal user {user.name}") - - except Exception as e: - _logger.warning(f"Failed to create custom welcome article for {user.name}: {e}") - # Fall back to default - super(ResUsers, user)._generate_tutorial_articles() diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/models/sale_order.py b/fusion_authorizer_portal/fusion_authorizer_portal/models/sale_order.py deleted file mode 100644 index a216c6a..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/models/sale_order.py +++ /dev/null @@ -1,250 +0,0 @@ -# -*- coding: utf-8 -*- - -from odoo import api, fields, models, _ -import logging - -_logger = logging.getLogger(__name__) - - -class SaleOrder(models.Model): - _inherit = 'sale.order' - - # Comments from portal users - portal_comment_ids = fields.One2many( - 'fusion.authorizer.comment', - 'sale_order_id', - string='Portal Comments', - ) - - portal_comment_count = fields.Integer( - string='Comment Count', - compute='_compute_portal_comment_count', - ) - - # Documents uploaded via portal - portal_document_ids = fields.One2many( - 'fusion.adp.document', - 'sale_order_id', - string='Portal Documents', - ) - - portal_document_count = fields.Integer( - string='Document Count', - compute='_compute_portal_document_count', - ) - - # Link to assessment - assessment_id = fields.Many2one( - 'fusion.assessment', - string='Source Assessment', - readonly=True, - help='The assessment that created this sale order', - ) - - # Authorizer helper field (consolidates multiple possible fields) - portal_authorizer_id = fields.Many2one( - 'res.partner', - string='Authorizer (Portal)', - compute='_compute_portal_authorizer_id', - store=True, - help='Consolidated authorizer field for portal access', - ) - - @api.depends('portal_comment_ids') - def _compute_portal_comment_count(self): - for order in self: - order.portal_comment_count = len(order.portal_comment_ids) - - @api.depends('portal_document_ids') - def _compute_portal_document_count(self): - for order in self: - order.portal_document_count = len(order.portal_document_ids) - - @api.depends('x_fc_authorizer_id') - def _compute_portal_authorizer_id(self): - """Get authorizer from x_fc_authorizer_id field""" - for order in self: - order.portal_authorizer_id = order.x_fc_authorizer_id - - def write(self, vals): - """Override write to send notification when authorizer is assigned.""" - old_authorizers = { - order.id: order.x_fc_authorizer_id.id if order.x_fc_authorizer_id else False - for order in self - } - - result = super().write(vals) - - # Check for authorizer changes - if 'x_fc_authorizer_id' in vals: - for order in self: - old_auth = old_authorizers.get(order.id) - new_auth = vals.get('x_fc_authorizer_id') - if new_auth and new_auth != old_auth: - order._send_authorizer_assignment_notification() - - # NOTE: Generic status change notifications removed. - # Each status transition already sends its own detailed email - # from fusion_claims (approval, denial, submission, billed, etc.) - # A generic "status changed" email on top was redundant and lacked detail. - - return result - - def action_message_authorizer(self): - """Open composer to send message to authorizer only""" - self.ensure_one() - if not self.x_fc_authorizer_id: - return {'type': 'ir.actions.act_window_close'} - - return { - 'type': 'ir.actions.act_window', - 'name': 'Message Authorizer', - 'res_model': 'mail.compose.message', - 'view_mode': 'form', - 'target': 'new', - 'context': { - 'default_model': 'sale.order', - 'default_res_ids': [self.id], - 'default_partner_ids': [self.x_fc_authorizer_id.id], - 'default_composition_mode': 'comment', - 'default_subtype_xmlid': 'mail.mt_note', - }, - } - - def _send_authorizer_assignment_notification(self): - """Send email when an authorizer is assigned to the order""" - self.ensure_one() - - if not self.x_fc_authorizer_id or not self.x_fc_authorizer_id.email: - return - - try: - template = self.env.ref('fusion_authorizer_portal.mail_template_case_assigned', raise_if_not_found=False) - if template: - template.send_mail(self.id, force_send=False) - _logger.info(f"Sent case assignment notification to {self.x_fc_authorizer_id.email} for {self.name}") - except Exception as e: - _logger.error(f"Failed to send authorizer assignment notification: {e}") - - # _send_status_change_notification removed -- redundant. - # Each workflow transition in fusion_claims sends its own detailed email. - - def action_view_portal_comments(self): - """View portal comments""" - self.ensure_one() - return { - 'type': 'ir.actions.act_window', - 'name': _('Portal Comments'), - 'res_model': 'fusion.authorizer.comment', - 'view_mode': 'list,form', - 'domain': [('sale_order_id', '=', self.id)], - 'context': {'default_sale_order_id': self.id}, - } - - def action_view_portal_documents(self): - """View portal documents""" - self.ensure_one() - return { - 'type': 'ir.actions.act_window', - 'name': _('Portal Documents'), - 'res_model': 'fusion.adp.document', - 'view_mode': 'list,form', - 'domain': [('sale_order_id', '=', self.id)], - 'context': {'default_sale_order_id': self.id}, - } - - def get_portal_display_data(self): - """Get data for portal display, excluding sensitive information""" - self.ensure_one() - - return { - 'id': self.id, - 'name': self.name, - 'date_order': self.date_order, - 'state': self.state, - 'state_display': dict(self._fields['state'].selection).get(self.state, self.state), - 'partner_name': self.partner_id.name if self.partner_id else '', - 'partner_address': self._get_partner_address_display(), - 'client_reference_1': self.x_fc_client_ref_1 or '', - 'client_reference_2': self.x_fc_client_ref_2 or '', - 'claim_number': self.x_fc_claim_number or '', - 'authorizer_name': self.x_fc_authorizer_id.name if self.x_fc_authorizer_id else '', - 'sales_rep_name': self.user_id.name if self.user_id else '', - 'product_lines': self._get_product_lines_for_portal(), - 'comment_count': self.portal_comment_count, - 'document_count': self.portal_document_count, - } - - def _get_partner_address_display(self): - """Get formatted partner address for display""" - if not self.partner_id: - return '' - - parts = [] - if self.partner_id.street: - parts.append(self.partner_id.street) - if self.partner_id.city: - city_part = self.partner_id.city - if self.partner_id.state_id: - city_part += f", {self.partner_id.state_id.name}" - if self.partner_id.zip: - city_part += f" {self.partner_id.zip}" - parts.append(city_part) - - return ', '.join(parts) - - def _get_product_lines_for_portal(self): - """Get product lines for portal display (excluding costs)""" - lines = [] - for line in self.order_line: - lines.append({ - 'id': line.id, - 'product_name': line.product_id.name if line.product_id else line.name, - 'quantity': line.product_uom_qty, - 'uom': line.product_uom_id.name if line.product_uom_id else '', - 'adp_code': line.x_fc_adp_device_code or '' if hasattr(line, 'x_fc_adp_device_code') else '', - 'device_type': '', - 'serial_number': line.x_fc_serial_number or '' if hasattr(line, 'x_fc_serial_number') else '', - }) - return lines - - @api.model - def get_authorizer_portal_cases(self, partner_id, search_query=None, limit=100, offset=0): - """Get cases for authorizer portal with optional search""" - domain = [('x_fc_authorizer_id', '=', partner_id)] - - # Add search if provided - if search_query: - search_domain = self._build_search_domain(search_query) - domain = ['&'] + domain + search_domain - - orders = self.sudo().search(domain, limit=limit, offset=offset, order='date_order desc, id desc') - return orders - - @api.model - def get_sales_rep_portal_cases(self, user_id, search_query=None, limit=100, offset=0): - """Get cases for sales rep portal with optional search""" - domain = [('user_id', '=', user_id)] - - # Add search if provided - if search_query: - search_domain = self._build_search_domain(search_query) - domain = domain + search_domain - - orders = self.sudo().search(domain, limit=limit, offset=offset, order='date_order desc, id desc') - return orders - - def _build_search_domain(self, query): - """Build search domain for portal search""" - if not query or len(query) < 2: - return [] - - search_domain = [ - '|', '|', '|', '|', - ('partner_id.name', 'ilike', query), - ('x_fc_claim_number', 'ilike', query), - ('x_fc_client_ref_1', 'ilike', query), - ('x_fc_client_ref_2', 'ilike', query), - ] - - return search_domain diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/security/ir.model.access.csv b/fusion_authorizer_portal/fusion_authorizer_portal/security/ir.model.access.csv deleted file mode 100644 index 10c6658..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/security/ir.model.access.csv +++ /dev/null @@ -1,12 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_fusion_authorizer_comment_user,fusion.authorizer.comment.user,model_fusion_authorizer_comment,base.group_user,1,1,1,1 -access_fusion_authorizer_comment_portal,fusion.authorizer.comment.portal,model_fusion_authorizer_comment,base.group_portal,1,1,1,0 -access_fusion_adp_document_user,fusion.adp.document.user,model_fusion_adp_document,base.group_user,1,1,1,1 -access_fusion_adp_document_portal,fusion.adp.document.portal,model_fusion_adp_document,base.group_portal,1,0,1,0 -access_fusion_assessment_user,fusion.assessment.user,model_fusion_assessment,base.group_user,1,1,1,1 -access_fusion_assessment_portal,fusion.assessment.portal,model_fusion_assessment,base.group_portal,1,1,1,0 -access_fusion_accessibility_assessment_user,fusion.accessibility.assessment.user,model_fusion_accessibility_assessment,base.group_user,1,1,1,1 -access_fusion_accessibility_assessment_portal,fusion.accessibility.assessment.portal,model_fusion_accessibility_assessment,base.group_portal,1,1,1,0 -access_fusion_pdf_template_user,fusion.pdf.template.user,model_fusion_pdf_template,base.group_user,1,1,1,1 -access_fusion_pdf_template_preview_user,fusion.pdf.template.preview.user,model_fusion_pdf_template_preview,base.group_user,1,1,1,1 -access_fusion_pdf_template_field_user,fusion.pdf.template.field.user,model_fusion_pdf_template_field,base.group_user,1,1,1,1 \ No newline at end of file diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/security/portal_security.xml b/fusion_authorizer_portal/fusion_authorizer_portal/security/portal_security.xml deleted file mode 100644 index 5b0228a..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/security/portal_security.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - - Authorizer Portal User - - Portal users who are Authorizers (OTs/Therapists) - - - - Sales Rep Portal User - - Portal users who are Sales Representatives - - - - Technician Portal User - - Portal users who are Field Technicians for deliveries - - - - - Authorizer: Own Comments - - [('author_id', '=', user.partner_id.id)] - - - - - - - - - Portal: View Comments on Assigned Orders - - [ - '|', - ('sale_order_id.x_fc_authorizer_id', '=', user.partner_id.id), - ('sale_order_id.user_id', '=', user.id), - ('is_internal', '=', False) - ] - - - - - - - - - - Portal: Read Documents on Assigned Orders - - [ - '|', - ('sale_order_id.x_fc_authorizer_id', '=', user.partner_id.id), - ('sale_order_id.user_id', '=', user.id) - ] - - - - - - - - - Authorizer: Create Documents on Assigned Orders - - [ - ('sale_order_id.x_fc_authorizer_id', '=', user.partner_id.id), - ('document_type', '!=', 'submitted_final') - ] - - - - - - - - - - Authorizer: Own Assessments - - [('authorizer_id', '=', user.partner_id.id)] - - - - - - - - - Sales Rep: Own Assessments - - [('sales_rep_id', '=', user.id)] - - - - - - - - - - Authorizer Portal: Assigned Orders - - [('x_fc_authorizer_id', '=', user.partner_id.id)] - - - - - - - - - - Technician Portal: Assigned Deliveries - - [('x_fc_delivery_technician_ids', 'in', [user.id])] - - - - - - - - - - Sales Rep Portal: Own Orders - - [('user_id', '=', user.id)] - - - - - - - - diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/static/description/icon.png b/fusion_authorizer_portal/fusion_authorizer_portal/static/description/icon.png deleted file mode 100644 index 796bac9bace4061b7c78d4849a49437c96d22379..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54735 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

      U`9_pb);5=(f>LCv_j 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 diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/css/portal_style.css b/fusion_authorizer_portal/fusion_authorizer_portal/static/src/css/portal_style.css deleted file mode 100644 index 3fb49d7..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/css/portal_style.css +++ /dev/null @@ -1,864 +0,0 @@ -/* Fusion Authorizer Portal - Custom Styles */ -/* Color Scheme: Dark Blue (#1a365d, #2c5282) with Green accents (#38a169) */ - -:root { - --portal-primary: #1a365d; - --portal-primary-light: #2c5282; - --portal-accent: #38a169; - --portal-accent-light: #48bb78; - --portal-dark: #1a202c; - --portal-gray: #718096; - --portal-light: #f7fafc; -} - -/* Portal Header Styling - Only for Fusion Portal pages */ -/* Removed global navbar styling to prevent affecting other portal pages */ - -/* Card Headers with Portal Theme */ -.card-header.bg-dark { - background: linear-gradient(135deg, var(--portal-primary) 0%, var(--portal-primary-light) 100%) !important; -} - -.card-header.bg-primary { - background: var(--portal-primary-light) !important; -} - -.card-header.bg-success { - background: var(--portal-accent) !important; -} - -/* Stat Cards */ -.card.bg-primary { - background: linear-gradient(135deg, var(--portal-primary) 0%, var(--portal-primary-light) 100%) !important; -} - -.card.bg-success { - background: linear-gradient(135deg, var(--portal-accent) 0%, var(--portal-accent-light) 100%) !important; -} - -/* Table Styling */ -.table-dark th { - background: var(--portal-primary) !important; -} - -.table-success th { - background: var(--portal-accent) !important; - color: white !important; -} - -.table-info th { - background: var(--portal-primary-light) !important; - color: white !important; -} - -/* Badges */ -.badge.bg-primary { - background: var(--portal-primary-light) !important; -} - -.badge.bg-success { - background: var(--portal-accent) !important; -} - -/* Buttons */ -.btn-primary { - background: var(--portal-primary-light) !important; - border-color: var(--portal-primary-light) !important; -} - -.btn-primary:hover { - background: var(--portal-primary) !important; - border-color: var(--portal-primary) !important; -} - -.btn-success { - background: var(--portal-accent) !important; - border-color: var(--portal-accent) !important; -} - -.btn-success:hover { - background: var(--portal-accent-light) !important; - border-color: var(--portal-accent-light) !important; -} - -.btn-outline-primary { - color: var(--portal-primary-light) !important; - border-color: var(--portal-primary-light) !important; -} - -.btn-outline-primary:hover { - background: var(--portal-primary-light) !important; - color: white !important; -} - -/* Search Box Styling */ -#portal-search-input { - border-radius: 25px 0 0 25px; - padding-left: 20px; -} - -#portal-search-input:focus { - border-color: var(--portal-primary-light); - box-shadow: 0 0 0 0.2rem rgba(44, 82, 130, 0.25); -} - -/* Case List Row Hover */ -.table-hover tbody tr:hover { - background-color: rgba(44, 82, 130, 0.1); -} - -/* Document Upload Area */ -.document-upload-area { - border: 2px dashed var(--portal-gray); - border-radius: 10px; - padding: 20px; - text-align: center; - background: var(--portal-light); - transition: all 0.3s ease; -} - -.document-upload-area:hover { - border-color: var(--portal-primary-light); - background: rgba(44, 82, 130, 0.05); -} - -/* Comment Section */ -.comment-item { - border-left: 4px solid var(--portal-primary-light); - padding-left: 15px; - margin-bottom: 15px; -} - -.comment-item .comment-author { - font-weight: 600; - color: var(--portal-primary); -} - -.comment-item .comment-date { - font-size: 0.85em; - color: var(--portal-gray); -} - -/* Signature Pad */ -.signature-pad-container { - border: 2px solid var(--portal-gray); - border-radius: 8px; - padding: 10px; - background: white; - touch-action: none; -} - -.signature-pad-container canvas { - cursor: crosshair; - width: 100%; - height: 200px; -} - -/* Progress Bar */ -.progress { - border-radius: 15px; - overflow: hidden; -} - -.progress-bar { - font-size: 0.75rem; - font-weight: 600; -} - -/* Assessment Form Cards */ -.assessment-section-card { - transition: all 0.3s ease; -} - -.assessment-section-card:hover { - box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); -} - -/* Status Badges */ -.status-badge { - padding: 0.5em 1em; - border-radius: 20px; - font-weight: 500; -} - -.status-draft { - background: #e2e8f0; - color: #4a5568; -} - -.status-pending { - background: #faf089; - color: #744210; -} - -.status-completed { - background: #c6f6d5; - color: #276749; -} - -.status-cancelled { - background: #fed7d7; - color: #9b2c2c; -} - -/* Quick Action Buttons */ -.quick-action-btn { - min-width: 150px; - margin-bottom: 10px; -} - -/* Loading Spinner */ -.search-loading { - display: none; - position: absolute; - right: 50px; - top: 50%; - transform: translateY(-50%); -} - -.search-loading.active { - display: block; -} - -/* Mobile Responsiveness */ -@media (max-width: 768px) { - .card-header { - font-size: 0.9rem; - } - - .btn-lg { - font-size: 1rem; - padding: 0.5rem 1rem; - } - - .table-responsive { - font-size: 0.85rem; - } - - .signature-pad-container canvas { - height: 150px; - } -} - -/* Animation for Search Results */ -@keyframes fadeIn { - from { - opacity: 0; - transform: translateY(-10px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -.search-result-row { - animation: fadeIn 0.3s ease; -} - -/* Highlight matching text */ -.search-highlight { - background-color: #faf089; - padding: 0 2px; - border-radius: 2px; -} - -/* ======================================== - EXPRESS ASSESSMENT FORM STYLES - ======================================== */ - -.assessment-express-form .form-label { - color: #333; - font-size: 0.95rem; -} - -.assessment-express-form .form-label.fw-bold { - font-weight: 600 !important; -} - -.assessment-express-form .form-control, -.assessment-express-form .form-select { - border-radius: 6px; - border-color: #dee2e6; - padding: 0.625rem 0.875rem; -} - -.assessment-express-form .form-control:focus, -.assessment-express-form .form-select:focus { - border-color: #2e7aad; - box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.15); -} - -.assessment-express-form .form-select-lg { - padding: 0.75rem 1rem; - font-size: 1.1rem; -} - -/* Input Group with Inch suffix */ -.assessment-express-form .input-group-text { - background-color: #f8f9fa; - border-color: #dee2e6; - color: #6c757d; - font-weight: 500; -} - -/* Checkbox and Radio Styling */ -.assessment-express-form .form-check { - padding-left: 1.75rem; - margin-bottom: 0.5rem; -} - -.assessment-express-form .form-check-input { - width: 1.15rem; - height: 1.15rem; - margin-top: 0.15rem; - margin-left: -1.75rem; -} - -.assessment-express-form .form-check-input:checked { - background-color: #2e7aad; - border-color: #2e7aad; -} - -.assessment-express-form .form-check-label { - color: #333; - cursor: pointer; -} - -/* Equipment Form Sections */ -.assessment-express-form .equipment-form h2 { - color: #1a1a1a; - font-size: 1.5rem; - letter-spacing: 1px; -} - -/* Card Styling */ -.assessment-express-form .card { - border: none; - border-radius: 12px; -} - -.assessment-express-form .card-header.bg-primary { - background: linear-gradient(135deg, #5ba848 0%, #3a8fb7 60%, #2e7aad 100%) !important; - border-radius: 12px 12px 0 0; -} - -.assessment-express-form .card-body { - padding: 2rem; -} - -.assessment-express-form .card-footer { - border-top: 1px solid #e9ecef; - padding: 1.25rem 2rem; -} - -/* Button Styling */ -.assessment-express-form .btn-primary { - background: #2e7aad !important; - border-color: #4361ee !important; - padding: 0.75rem 2rem; - font-weight: 600; - border-radius: 6px; -} - -.assessment-express-form .btn-primary:hover { - background: #3451d1 !important; - border-color: #3451d1 !important; -} - -.assessment-express-form .btn-success { - background: #10b981 !important; - border-color: #10b981 !important; - padding: 0.75rem 2rem; - font-weight: 600; - border-radius: 6px; -} - -.assessment-express-form .btn-success:hover { - background: #059669 !important; - border-color: #059669 !important; -} - -.assessment-express-form .btn-outline-secondary { - border-width: 2px; - font-weight: 500; -} - -/* Progress Bar */ -.assessment-express-form .progress { - height: 8px; - background-color: #e9ecef; -} - -.assessment-express-form .progress-bar { - background: linear-gradient(90deg, #5ba848 0%, #3a8fb7 60%, #2e7aad 100%); -} - -/* Section Separators */ -.assessment-express-form hr { - border-color: #e9ecef; - opacity: 1; -} - -/* Required Field Indicator */ -.assessment-express-form .text-danger { - color: #dc3545 !important; -} - -/* Section Headers within form */ -.assessment-express-form h5.fw-bold { - color: #374151; - border-bottom: 2px solid #2e7aad; - padding-bottom: 0.5rem; - display: inline-block; -} - -/* New Assessment Card on Portal Home */ -.portal-new-assessment-card { - background: linear-gradient(135deg, #5ba848 0%, #3a8fb7 60%, #2e7aad 100%) !important; - transition: transform 0.2s ease, box-shadow 0.2s ease; -} - -.portal-new-assessment-card:hover { - transform: translateY(-5px); - box-shadow: 0 10px 30px rgba(102, 126, 234, 0.3) !important; -} - -.portal-new-assessment-card .card-body { - background: transparent !important; -} - -.portal-new-assessment-card h5, -.portal-new-assessment-card small { - color: #fff !important; -} - -.portal-new-assessment-card .icon-circle { - width: 50px; - height: 50px; - background: rgba(255,255,255,0.25) !important; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; -} - -.portal-new-assessment-card .icon-circle i { - color: #fff !important; - font-size: 1.25rem; -} - -/* Authorizer Portal Card on Portal Home */ -.portal-authorizer-card { - background: linear-gradient(135deg, #5ba848 0%, #3a8fb7 60%, #2e7aad 100%) !important; - transition: transform 0.2s ease, box-shadow 0.2s ease; -} - -.portal-authorizer-card:hover { - transform: translateY(-5px); - box-shadow: 0 10px 30px rgba(46, 122, 173, 0.3) !important; -} - -.portal-authorizer-card .card-body { - background: transparent !important; -} - -.portal-authorizer-card h5, -.portal-authorizer-card small { - color: #fff !important; -} - -.portal-authorizer-card .icon-circle { - width: 50px; - height: 50px; - background: rgba(255,255,255,0.25) !important; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; -} - -.portal-authorizer-card .icon-circle i { - color: #fff !important; - font-size: 1.25rem; -} - -/* Responsive adjustments */ -@media (max-width: 768px) { - .assessment-express-form .card-body { - padding: 1.25rem; - } - - .assessment-express-form .d-flex.flex-wrap.gap-4 { - gap: 0.5rem !important; - } - - .assessment-express-form .row { - margin-left: -0.5rem; - margin-right: -0.5rem; - } - - .assessment-express-form .col-md-4, - .assessment-express-form .col-md-6 { - padding-left: 0.5rem; - padding-right: 0.5rem; - } -} - -/* ================================================================== */ -/* AUTHORIZER DASHBOARD - MOBILE-FIRST REDESIGN */ -/* ================================================================== */ - -.auth-dash { - background: #f8f9fb; - min-height: 80vh; -} - -/* Content Area */ -.auth-dash-content { - padding-top: 24px; - padding-bottom: 40px; -} - -/* Welcome Header */ -.auth-dash-header { - background: linear-gradient(135deg, #5ba848 0%, #3a8fb7 60%, #2e7aad 100%); - border-radius: 16px; - margin-bottom: 24px; - overflow: hidden; -} - -.auth-dash-header-inner { - padding: 28px 30px 24px; -} - -.auth-dash-greeting { - color: #fff; - font-size: 24px; - font-weight: 700; - margin: 0 0 4px 0; - letter-spacing: -0.3px; -} - -.auth-dash-subtitle { - color: rgba(255,255,255,0.85); - font-size: 14px; - margin: 0; - font-weight: 400; -} - -/* ---- Action Tiles ---- */ -.auth-dash-tiles { - display: flex; - flex-direction: column; - gap: 12px; - margin-bottom: 28px; -} - -.auth-tile { - display: flex; - align-items: center; - background: #fff; - border-radius: 14px; - padding: 18px 20px; - text-decoration: none !important; - color: #333 !important; - border: 1px solid #e8ecf1; - box-shadow: 0 1px 4px rgba(0,0,0,0.04); - transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease; - min-height: 72px; -} - -.auth-tile:hover { - transform: translateY(-2px); - box-shadow: 0 6px 20px rgba(0,0,0,0.08); - border-color: #d0d5dd; -} - -.auth-tile:active { - transform: scale(0.98); -} - -.auth-tile-icon { - width: 48px; - height: 48px; - border-radius: 14px; - display: flex; - align-items: center; - justify-content: center; - flex-shrink: 0; - font-size: 20px; - color: #fff; - margin-right: 16px; -} - -.auth-tile-cases .auth-tile-icon { - background: linear-gradient(135deg, #2e7aad, #1a6b9a); -} - -.auth-tile-assessments .auth-tile-icon { - background: linear-gradient(135deg, #5ba848, #4a9e3f); -} - -.auth-tile-new .auth-tile-icon { - background: linear-gradient(135deg, #3a8fb7, #2e7aad); -} - -.auth-tile-info { - flex: 1; - min-width: 0; -} - -.auth-tile-title { - font-size: 16px; - font-weight: 600; - color: #1a1a2e; - line-height: 1.3; -} - -.auth-tile-desc { - font-size: 13px; - color: #8b95a5; - line-height: 1.3; - margin-top: 3px; -} - -.auth-tile-badge .badge { - background: #eef1f7; - color: #3949ab; - font-size: 15px; - font-weight: 700; - padding: 5px 14px; - border-radius: 20px; - margin-right: 10px; -} - -.auth-tile-arrow { - color: #c5ccd6; - font-size: 14px; - flex-shrink: 0; -} - -/* ---- Sections ---- */ -.auth-dash-section { - background: #fff; - border-radius: 14px; - overflow: hidden; - margin-bottom: 20px; - border: 1px solid #e8ecf1; - box-shadow: 0 1px 4px rgba(0,0,0,0.04); -} - -.auth-section-header { - padding: 16px 20px; - font-size: 15px; - font-weight: 600; - color: #444; - border-bottom: 1px solid #f0f2f5; - display: flex; - align-items: center; -} - -.auth-section-attention { - color: #c0392b; - background: #fef5f5; - border-bottom-color: #fce4e4; -} - -.auth-section-pending { - color: #d97706; - background: #fef9f0; - border-bottom-color: #fdecd0; -} - -/* ---- Case List Items ---- */ -.auth-case-list { - padding: 0; -} - -.auth-case-item { - display: flex; - align-items: center; - padding: 16px 20px; - text-decoration: none !important; - color: inherit !important; - border-bottom: 1px solid #f3f4f6; - transition: background 0.1s ease; - cursor: pointer; -} - -.auth-case-item:last-child { - border-bottom: none; -} - -.auth-case-item:hover { - background: #f9fafb; -} - -.auth-case-item:active { - background: #f0f2f5; -} - -.auth-case-attention { - border-left: 3px solid #e74c3c; -} - -.auth-case-main { - flex: 1; - min-width: 0; -} - -.auth-case-client { - font-size: 15px; - font-weight: 600; - color: #1a1a2e; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.auth-case-meta { - display: flex; - flex-wrap: wrap; - gap: 8px; - margin-top: 5px; - align-items: center; -} - -.auth-case-ref { - font-size: 12px; - color: #9ca3af; - font-weight: 500; -} - -.auth-case-type { - font-size: 11px; - background: #e3f2fd; - color: #1565c0; - padding: 2px 10px; - border-radius: 10px; - font-weight: 500; - text-transform: uppercase; -} - -.auth-case-status { - font-size: 11px; - background: #f3e5f5; - color: #7b1fa2; - padding: 2px 10px; - border-radius: 10px; - font-weight: 500; -} - -.badge-attention { - font-size: 11px; - background: #fce4ec; - color: #c62828; - padding: 2px 10px; - border-radius: 10px; - font-weight: 600; -} - -.auth-case-date { - font-size: 12px; - color: #9ca3af; -} - -.auth-case-arrow { - color: #c5ccd6; - font-size: 14px; - flex-shrink: 0; - margin-left: 12px; -} - -/* ---- Empty State ---- */ -.auth-empty-state { - text-align: center; - padding: 60px 20px; - color: #aaa; -} - -.auth-empty-state i { - font-size: 48px; - margin-bottom: 16px; - display: block; -} - -.auth-empty-state h5 { - color: #666; - margin-bottom: 8px; -} - -/* ---- Desktop Enhancements ---- */ -@media (min-width: 768px) { - .auth-dash-header-inner { - padding: 32px 36px 28px; - } - - .auth-dash-greeting { - font-size: 28px; - } - - .auth-dash-tiles { - flex-direction: row; - gap: 16px; - } - - .auth-tile { - flex: 1; - padding: 20px 22px; - } - - .auth-dash-content { - padding-top: 28px; - } -} - -/* ---- Mobile Optimizations ---- */ -@media (max-width: 767px) { - .auth-dash-content { - padding-left: 12px; - padding-right: 12px; - padding-top: 16px; - } - - .auth-dash-header { - border-radius: 0; - margin-left: -12px; - margin-right: -12px; - margin-top: -24px; - margin-bottom: 20px; - } - - .auth-dash-header-inner { - padding: 22px 20px 20px; - } - - .auth-dash-greeting { - font-size: 20px; - } - - .auth-dash-subtitle { - font-size: 13px; - } - - .auth-tile { - padding: 16px 18px; - min-height: 66px; - } - - .auth-tile-icon { - width: 44px; - height: 44px; - font-size: 18px; - margin-right: 14px; - } - - .auth-case-item { - padding: 14px 18px; - } - - .auth-section-header { - padding: 14px 18px; - } -} diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/css/technician_portal.css b/fusion_authorizer_portal/fusion_authorizer_portal/static/src/css/technician_portal.css deleted file mode 100644 index 18139f2..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/css/technician_portal.css +++ /dev/null @@ -1,540 +0,0 @@ -/* ========================================================================== - Fusion Technician Portal - Mobile-First Styles (v2) - ========================================================================== */ - -/* ---- Base & Mobile First ---- */ -.tech-portal { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; - -webkit-font-smoothing: antialiased; - max-width: 640px; - margin: 0 auto; -} - -/* ---- Quick Stats Bar (Dashboard) ---- */ -.tech-stats-bar { - display: flex; - gap: 0.5rem; - overflow-x: auto; - padding-bottom: 0.5rem; - scrollbar-width: none; -} -.tech-stats-bar::-webkit-scrollbar { display: none; } - -.tech-stat-card { - flex: 0 0 auto; - min-width: 100px; - padding: 0.75rem 1rem; - border-radius: 12px; - text-align: center; - color: #fff; - font-weight: 600; -} -.tech-stat-card .stat-number { - font-size: 1.5rem; - line-height: 1.2; -} -.tech-stat-card .stat-label { - font-size: 0.7rem; - text-transform: uppercase; - letter-spacing: 0.05em; - opacity: 0.9; -} -.tech-stat-total { background: linear-gradient(135deg, #5ba848, #3a8fb7); } -.tech-stat-remaining { background: linear-gradient(135deg, #3498db, #2980b9); } -.tech-stat-completed { background: linear-gradient(135deg, #27ae60, #219a52); } -.tech-stat-travel { background: linear-gradient(135deg, #8e44ad, #7d3c98); } - -/* ---- Hero Card (Dashboard Current Task) ---- */ -.tech-hero-card { - border: none; - border-radius: 16px; - overflow: hidden; - box-shadow: 0 4px 20px rgba(0,0,0,0.08); - margin-bottom: 1.5rem; -} -.tech-hero-card .card-header { - background: linear-gradient(135deg, #5ba848 0%, #3a8fb7 60%, #2e7aad 100%); - color: #fff; - padding: 1rem 1.25rem; - border: none; -} -.tech-hero-card .card-header h5 { - color: #fff; - margin: 0; -} -.tech-hero-card .card-body { - padding: 1.25rem; -} -.tech-hero-label { - font-size: 0.7rem; - text-transform: uppercase; - letter-spacing: 0.06em; - opacity: 0.85; - margin-bottom: 0.15rem; -} - -/* ---- Timeline (Dashboard) ---- */ -.tech-timeline { - position: relative; - padding-left: 2rem; -} -.tech-timeline::before { - content: ''; - position: absolute; - left: 0.75rem; - top: 0; - bottom: 0; - width: 2px; - background: #dee2e6; -} - -.tech-timeline-item { - position: relative; - margin-bottom: 1rem; - padding-bottom: 0.5rem; -} -.tech-timeline-dot { - position: absolute; - left: -1.55rem; - top: 0.35rem; - width: 14px; - height: 14px; - border-radius: 50%; - border: 2px solid #fff; - box-shadow: 0 0 0 2px #dee2e6; - z-index: 1; -} -.tech-timeline-dot.status-scheduled { background: #6c757d; box-shadow: 0 0 0 2px #6c757d; } -.tech-timeline-dot.status-en_route { background: #3498db; box-shadow: 0 0 0 2px #3498db; } -.tech-timeline-dot.status-in_progress { background: #f39c12; box-shadow: 0 0 0 2px #f39c12; animation: pulse-dot 1.5s infinite; } -.tech-timeline-dot.status-completed { background: #27ae60; box-shadow: 0 0 0 2px #27ae60; } -.tech-timeline-dot.status-cancelled { background: #e74c3c; box-shadow: 0 0 0 2px #e74c3c; } - -@keyframes pulse-dot { - 0%, 100% { box-shadow: 0 0 0 2px #f39c12; } - 50% { box-shadow: 0 0 0 6px rgba(243, 156, 18, 0.3); } -} - -.tech-timeline-card { - border: 1px solid #e9ecef; - border-radius: 12px; - padding: 0.875rem 1rem; - background: #fff; - transition: box-shadow 0.2s, transform 0.15s; - text-decoration: none !important; - color: inherit !important; - display: block; -} -.tech-timeline-card:hover { - box-shadow: 0 4px 12px rgba(0,0,0,0.08); - transform: translateY(-1px); -} -.tech-timeline-card.active { - border-color: #f39c12; - border-width: 2px; - box-shadow: 0 4px 16px rgba(243, 156, 18, 0.15); -} - -.tech-timeline-time { - font-size: 0.85rem; - font-weight: 600; - color: #495057; -} -.tech-timeline-title { - font-size: 0.95rem; - font-weight: 600; - color: #212529; - margin: 0.15rem 0; -} -.tech-timeline-meta { - font-size: 0.8rem; - color: #6c757d; -} - -/* Travel indicator between tasks */ -.tech-travel-indicator { - padding: 0.35rem 0 0.35rem 0; - margin-left: -0.2rem; - font-size: 0.75rem; - color: #8e44ad; -} - -/* ---- Task Type Badges ---- */ -.tech-badge { - display: inline-block; - padding: 0.2rem 0.5rem; - border-radius: 6px; - font-size: 0.7rem; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.04em; -} -.tech-badge-delivery { background: #d4edda; color: #155724; } -.tech-badge-repair { background: #fff3cd; color: #856404; } -.tech-badge-pickup { background: #cce5ff; color: #004085; } -.tech-badge-troubleshoot { background: #f8d7da; color: #721c24; } -.tech-badge-assessment { background: #e2e3e5; color: #383d41; } -.tech-badge-installation { background: #d1ecf1; color: #0c5460; } -.tech-badge-maintenance { background: #e8daef; color: #6c3483; } -.tech-badge-other { background: #e9ecef; color: #495057; } - -/* Status badges */ -.tech-status-badge { - display: inline-block; - padding: 0.25rem 0.6rem; - border-radius: 20px; - font-size: 0.75rem; - font-weight: 600; -} -.tech-status-scheduled { background: #e9ecef; color: #495057; } -.tech-status-en_route { background: #cce5ff; color: #004085; } -.tech-status-in_progress { background: #fff3cd; color: #856404; } -.tech-status-completed { background: #d4edda; color: #155724; } -.tech-status-cancelled { background: #f8d7da; color: #721c24; } - -/* ========================================================================== - Task Detail Page - v2 Redesign - ========================================================================== */ - -/* ---- Back button ---- */ -.tech-back-btn { - display: inline-flex; - align-items: center; - justify-content: center; - width: 36px; - height: 36px; - border-radius: 10px; - background: var(--o-main-bg-color, #f8f9fa); - color: var(--o-main-text-color, #495057); - text-decoration: none !important; - transition: background 0.15s; - border: 1px solid var(--o-main-border-color, #dee2e6); -} -.tech-back-btn:hover { - background: var(--o-main-border-color, #dee2e6); -} - -/* ---- Task Hero Header ---- */ -.tech-task-hero { - padding-bottom: 0.75rem; - border-bottom: 1px solid var(--o-main-border-color, #eee); -} - -/* ---- Quick Actions Row ---- */ -.tech-quick-actions { - display: flex; - gap: 0.75rem; - overflow-x: auto; - scrollbar-width: none; - -webkit-overflow-scrolling: touch; - padding: 0.25rem 0; -} -.tech-quick-actions::-webkit-scrollbar { display: none; } - -.tech-quick-btn { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: 0.25rem; - min-width: 68px; - padding: 0.6rem 0.5rem; - border-radius: 14px; - background: var(--o-main-bg-color, #f8f9fa); - border: 1px solid var(--o-main-border-color, #e9ecef); - color: var(--o-main-text-color, #495057) !important; - text-decoration: none !important; - font-size: 0.72rem; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.02em; - transition: all 0.15s; - flex-shrink: 0; -} -.tech-quick-btn i { - font-size: 1.15rem; - color: #3498db; -} -.tech-quick-btn:hover { - background: #e3f2fd; - border-color: #90caf9; -} -.tech-quick-btn:active { - transform: scale(0.95); -} - -/* ---- Card (unified style for all sections) ---- */ -.tech-card { - background: var(--o-main-card-bg, #fff); - border: 1px solid var(--o-main-border-color, #e9ecef); - border-radius: 14px; - padding: 1rem; -} -.tech-card-success { - border-color: #c3e6cb; - background: color-mix(in srgb, #d4edda 30%, var(--o-main-card-bg, #fff)); -} - -/* ---- Card icon (left gutter icon) ---- */ -.tech-card-icon { - display: flex; - align-items: center; - justify-content: center; - width: 40px; - height: 40px; - border-radius: 12px; - font-size: 1rem; - margin-right: 0.75rem; - flex-shrink: 0; -} - -/* ---- Equipment highlight tag ---- */ -.tech-equipment-tag { - background: color-mix(in srgb, #ffeeba 25%, var(--o-main-card-bg, #fff)); - border: 1px solid #ffeeba; - border-radius: 10px; - padding: 0.75rem; -} - -/* ---- Action Buttons (Large Touch Targets) ---- */ -.tech-action-btn { - display: inline-flex; - align-items: center; - justify-content: center; - gap: 0.5rem; - min-height: 48px; - padding: 0.75rem 1.5rem; - border-radius: 14px; - font-weight: 600; - font-size: 0.95rem; - border: none; - cursor: pointer; - transition: all 0.15s; - text-decoration: none !important; -} -.tech-action-btn:active { transform: scale(0.97); } - -.tech-btn-navigate { - background: #3498db; - color: #fff !important; -} -.tech-btn-navigate:hover { background: #2980b9; color: #fff !important; } - -.tech-btn-start { - background: #27ae60; - color: #fff !important; -} -.tech-btn-start:hover { background: #219a52; color: #fff !important; } - -.tech-btn-complete { - background: #f39c12; - color: #fff !important; -} -.tech-btn-complete:hover { background: #e67e22; color: #fff !important; } - -.tech-btn-call { - background: #9b59b6; - color: #fff !important; -} -.tech-btn-call:hover { background: #8e44ad; color: #fff !important; } - -.tech-btn-enroute { - background: #2980b9; - color: #fff !important; -} -.tech-btn-enroute:hover { background: #2471a3; color: #fff !important; } - -/* ---- Bottom Action Bar (Fixed on mobile) ---- */ -.tech-bottom-bar { - position: fixed; - bottom: 0; - left: 0; - right: 0; - background: var(--o-main-card-bg, #fff); - border-top: 1px solid var(--o-main-border-color, #dee2e6); - padding: 0.75rem 1rem; - padding-bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px)); - z-index: 1050; - display: flex; - gap: 0.5rem; - box-shadow: 0 -4px 20px rgba(0,0,0,0.08); -} -.tech-bottom-bar .tech-action-btn { - flex: 1; -} - -/* Padding to prevent content being hidden behind fixed bar */ -.has-bottom-bar { - padding-bottom: 5rem; -} - -/* ---- Completion Overlay ---- */ -.tech-overlay { - display: none; - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(0,0,0,0.7); - backdrop-filter: blur(4px); - -webkit-backdrop-filter: blur(4px); - z-index: 9999; - align-items: center; - justify-content: center; -} -.tech-overlay-card { - background: var(--o-main-card-bg, #fff); - border-radius: 20px; - padding: 2rem; - max-width: 400px; - width: 90%; - text-align: center; - animation: slideUp 0.3s ease; -} -.tech-overlay-icon { - font-size: 3rem; - margin-bottom: 1rem; -} -@keyframes slideUp { - from { opacity: 0; transform: translateY(30px); } - to { opacity: 1; transform: translateY(0); } -} - -/* ---- Voice Recording UI ---- */ -.tech-voice-recorder { - border: 2px dashed var(--o-main-border-color, #dee2e6); - border-radius: 16px; - padding: 1.5rem 1rem; - text-align: center; - transition: all 0.3s; -} -.tech-voice-recorder.recording { - border-color: #e74c3c; - background: rgba(231, 76, 60, 0.04); -} - -.tech-record-btn { - width: 64px; - height: 64px; - border-radius: 50%; - border: none; - background: #e74c3c; - color: #fff; - font-size: 1.3rem; - cursor: pointer; - transition: all 0.2s; - display: inline-flex; - align-items: center; - justify-content: center; -} -.tech-record-btn:hover { transform: scale(1.05); } -.tech-record-btn:active { transform: scale(0.95); } -.tech-record-btn.recording { - animation: pulse-record 1.5s infinite; -} - -@keyframes pulse-record { - 0%, 100% { box-shadow: 0 0 0 0 rgba(231, 76, 60, 0.4); } - 50% { box-shadow: 0 0 0 15px rgba(231, 76, 60, 0); } -} - -.tech-record-timer { - font-size: 1.25rem; - font-weight: 700; - font-variant-numeric: tabular-nums; - margin-top: 0.5rem; - color: #e74c3c; -} - -/* ---- Tomorrow Prep ---- */ -.tech-prep-card { - border: 1px solid #e9ecef; - border-radius: 12px; - padding: 1rem; - margin-bottom: 0.75rem; - background: #fff; -} -.tech-prep-card .prep-time { - font-weight: 700; - font-size: 0.9rem; -} -.tech-prep-card .prep-type { - margin-left: 0.5rem; -} -.tech-prep-equipment { - background: #fff9e6; - border: 1px solid #ffeeba; - border-radius: 12px; - padding: 1rem; -} - -/* ---- Responsive: Desktop enhancements ---- */ -@media (min-width: 768px) { - .tech-stats-bar { - gap: 1rem; - } - .tech-stat-card { - min-width: 130px; - padding: 1rem 1.5rem; - } - .tech-stat-card .stat-number { - font-size: 2rem; - } - .tech-bottom-bar { - position: static; - box-shadow: none; - border: none; - padding: 0; - margin-top: 1rem; - } - .has-bottom-bar { - padding-bottom: 0; - } - .tech-timeline { - padding-left: 3rem; - } - .tech-timeline::before { - left: 1.25rem; - } - .tech-timeline-dot { - left: -2.05rem; - } - .tech-quick-btn { - min-width: 80px; - padding: 0.75rem 0.75rem; - } -} - -/* ---- Legacy detail section support ---- */ -.tech-detail-section { - background: var(--o-main-card-bg, #fff); - border: 1px solid var(--o-main-border-color, #e9ecef); - border-radius: 14px; - padding: 1rem; - margin-bottom: 1rem; -} -.tech-detail-section h6 { - font-size: 0.75rem; - text-transform: uppercase; - letter-spacing: 0.06em; - color: #6c757d; - margin-bottom: 0.75rem; - padding-bottom: 0.5rem; - border-bottom: 1px solid var(--o-main-border-color, #f1f3f5); -} -.tech-detail-row { - display: flex; - justify-content: space-between; - padding: 0.3rem 0; -} -.tech-detail-label { - font-weight: 500; - color: var(--o-main-text-color, #495057); - font-size: 0.9rem; -} -.tech-detail-value { - color: var(--o-main-text-color, #212529); - font-size: 0.9rem; - text-align: right; -} diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/assessment_form.js b/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/assessment_form.js deleted file mode 100644 index cd72cb1..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/assessment_form.js +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Fusion Authorizer Portal - Assessment Form - */ - -odoo.define('fusion_authorizer_portal.assessment_form', function (require) { - 'use strict'; - - var publicWidget = require('web.public.widget'); - - publicWidget.registry.AssessmentForm = publicWidget.Widget.extend({ - selector: '#assessment-form', - events: { - 'change input, change select, change textarea': '_onFieldChange', - 'submit': '_onSubmit', - }, - - init: function () { - this._super.apply(this, arguments); - this.hasUnsavedChanges = false; - }, - - start: function () { - this._super.apply(this, arguments); - this._initializeForm(); - return Promise.resolve(); - }, - - _initializeForm: function () { - var self = this; - - // Warn before leaving with unsaved changes - window.addEventListener('beforeunload', function (e) { - if (self.hasUnsavedChanges) { - e.preventDefault(); - e.returnValue = ''; - return ''; - } - }); - - // Auto-fill full name from first + last name - var firstNameInput = this.el.querySelector('[name="client_first_name"]'); - var lastNameInput = this.el.querySelector('[name="client_last_name"]'); - var fullNameInput = this.el.querySelector('[name="client_name"]'); - - if (firstNameInput && lastNameInput && fullNameInput) { - var updateFullName = function () { - var first = firstNameInput.value.trim(); - var last = lastNameInput.value.trim(); - if (first || last) { - fullNameInput.value = (first + ' ' + last).trim(); - } - }; - - firstNameInput.addEventListener('blur', updateFullName); - lastNameInput.addEventListener('blur', updateFullName); - } - - // Number input validation - var numberInputs = this.el.querySelectorAll('input[type="number"]'); - numberInputs.forEach(function (input) { - input.addEventListener('input', function () { - var value = parseFloat(this.value); - var min = parseFloat(this.min) || 0; - var max = parseFloat(this.max) || 9999; - - if (value < min) this.value = min; - if (value > max) this.value = max; - }); - }); - }, - - _onFieldChange: function (ev) { - this.hasUnsavedChanges = true; - - // Visual feedback that form has changes - var saveBtn = this.el.querySelector('button[value="save"]'); - if (saveBtn) { - saveBtn.classList.add('btn-warning'); - saveBtn.classList.remove('btn-primary'); - } - }, - - _onSubmit: function (ev) { - // Validate required fields - var requiredFields = this.el.querySelectorAll('[required]'); - var isValid = true; - - requiredFields.forEach(function (field) { - if (!field.value.trim()) { - field.classList.add('is-invalid'); - isValid = false; - } else { - field.classList.remove('is-invalid'); - } - }); - - if (!isValid) { - ev.preventDefault(); - alert('Please fill in all required fields.'); - return false; - } - - this.hasUnsavedChanges = false; - return true; - } - }); - - return publicWidget.registry.AssessmentForm; -}); diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/chatter_message_authorizer.js b/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/chatter_message_authorizer.js deleted file mode 100644 index 6802395..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/chatter_message_authorizer.js +++ /dev/null @@ -1,37 +0,0 @@ -/** @odoo-module **/ -// Fusion Authorizer Portal - Message Authorizer Chatter Button -// Copyright 2026 Nexa Systems Inc. -// License OPL-1 -// -// Patches the Chatter component to add a "Message Authorizer" button -// that opens the mail composer targeted at the assigned authorizer. - -import { Chatter } from "@mail/chatter/web_portal/chatter"; -import { patch } from "@web/core/utils/patch"; -import { useService } from "@web/core/utils/hooks"; - -patch(Chatter.prototype, { - setup() { - super.setup(...arguments); - this._fapActionService = useService("action"); - this._fapOrm = useService("orm"); - }, - - async onClickMessageAuthorizer() { - const thread = this.state.thread; - if (!thread || thread.model !== "sale.order") return; - - try { - const result = await this._fapOrm.call( - "sale.order", - "action_message_authorizer", - [thread.id], - ); - if (result && result.type === "ir.actions.act_window") { - this._fapActionService.doAction(result); - } - } catch (e) { - console.warn("Message Authorizer action failed:", e); - } - }, -}); diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/loaner_portal.js b/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/loaner_portal.js deleted file mode 100644 index 3c25a84..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/loaner_portal.js +++ /dev/null @@ -1,478 +0,0 @@ -/** @odoo-module **/ - -import publicWidget from "@web/legacy/js/public/public_widget"; - -publicWidget.registry.LoanerPortal = publicWidget.Widget.extend({ - selector: '#loanerSection, #btn_checkout_loaner, .btn-loaner-return', - - start: function () { - this._super.apply(this, arguments); - this._allProducts = []; - this._initLoanerSection(); - this._initCheckoutButton(); - this._initReturnButtons(); - this._initModal(); - }, - - // ===================================================================== - // MODAL: Initialize and wire up the loaner checkout modal - // ===================================================================== - _initModal: function () { - var self = this; - var modal = document.getElementById('loanerCheckoutModal'); - if (!modal) return; - - var categorySelect = document.getElementById('modal_category_id'); - var productSelect = document.getElementById('modal_product_id'); - var lotSelect = document.getElementById('modal_lot_id'); - var loanDays = document.getElementById('modal_loan_days'); - var btnCheckout = document.getElementById('modal_btn_checkout'); - var btnCreateProduct = document.getElementById('modal_btn_create_product'); - var newCategorySelect = document.getElementById('modal_new_category_id'); - var createResult = document.getElementById('modal_create_result'); - - // Load categories when modal opens - modal.addEventListener('show.bs.modal', function () { - self._loadCategories(categorySelect, newCategorySelect); - self._loadProducts(null, productSelect, lotSelect); - }); - - // Category change -> filter products - if (categorySelect) { - categorySelect.addEventListener('change', function () { - var catId = this.value ? parseInt(this.value) : null; - self._filterProducts(catId, productSelect, lotSelect); - }); - } - - // Product change -> filter lots - if (productSelect) { - productSelect.addEventListener('change', function () { - var prodId = this.value ? parseInt(this.value) : null; - self._filterLots(prodId, lotSelect, loanDays); - }); - } - - // Quick Create Product - if (btnCreateProduct) { - btnCreateProduct.addEventListener('click', function () { - var name = document.getElementById('modal_new_product_name').value.trim(); - var serial = document.getElementById('modal_new_serial').value.trim(); - var catId = newCategorySelect ? newCategorySelect.value : ''; - - if (!name || !serial) { - alert('Please enter both product name and serial number.'); - return; - } - - btnCreateProduct.disabled = true; - btnCreateProduct.innerHTML = ' Creating...'; - - self._rpc('/my/loaner/create-product', { - product_name: name, - serial_number: serial, - category_id: catId || null, - }).then(function (result) { - if (result.success) { - // Add to product dropdown - var opt = document.createElement('option'); - opt.value = result.product_id; - opt.text = result.product_name; - opt.selected = true; - productSelect.appendChild(opt); - - // Add to lots - lotSelect.innerHTML = ''; - var lotOpt = document.createElement('option'); - lotOpt.value = result.lot_id; - lotOpt.text = result.lot_name; - lotOpt.selected = true; - lotSelect.appendChild(lotOpt); - - // Add to internal data - self._allProducts.push({ - id: result.product_id, - name: result.product_name, - category_id: catId ? parseInt(catId) : null, - period_days: 7, - lots: [{ id: result.lot_id, name: result.lot_name }], - }); - - if (createResult) { - createResult.style.display = ''; - createResult.innerHTML = '

      "' + result.product_name + '" (S/N: ' + result.lot_name + ') created!
      '; - } - - // Clear fields - document.getElementById('modal_new_product_name').value = ''; - document.getElementById('modal_new_serial').value = ''; - } else { - if (createResult) { - createResult.style.display = ''; - createResult.innerHTML = '
      ' + (result.error || 'Error') + '
      '; - } - } - btnCreateProduct.disabled = false; - btnCreateProduct.innerHTML = ' Create Product'; - }); - }); - } - - // Checkout button - if (btnCheckout) { - btnCheckout.addEventListener('click', function () { - var productId = productSelect.value ? parseInt(productSelect.value) : null; - var lotId = lotSelect.value ? parseInt(lotSelect.value) : null; - var days = parseInt(loanDays.value) || 7; - var orderId = document.getElementById('modal_order_id').value; - var clientId = document.getElementById('modal_client_id').value; - - if (!productId) { - alert('Please select a product.'); - return; - } - - btnCheckout.disabled = true; - btnCheckout.innerHTML = ' Processing...'; - - self._rpc('/my/loaner/checkout', { - product_id: productId, - lot_id: lotId, - sale_order_id: orderId ? parseInt(orderId) : null, - client_id: clientId ? parseInt(clientId) : null, - loaner_period_days: days, - checkout_condition: 'good', - checkout_notes: '', - }).then(function (result) { - if (result.success) { - self._hideModal(modal); - alert(result.message); - location.reload(); - } else { - alert('Error: ' + (result.error || 'Unknown')); - btnCheckout.disabled = false; - btnCheckout.innerHTML = ' Checkout Loaner'; - } - }); - }); - } - }, - - _loadCategories: function (categorySelect, newCategorySelect) { - this._rpc('/my/loaner/categories', {}).then(function (categories) { - categories = categories || []; - // Main category dropdown - if (categorySelect) { - categorySelect.innerHTML = ''; - categories.forEach(function (c) { - var opt = document.createElement('option'); - opt.value = c.id; - opt.text = c.name; - categorySelect.appendChild(opt); - }); - } - // Quick create category dropdown - if (newCategorySelect) { - newCategorySelect.innerHTML = ''; - categories.forEach(function (c) { - var opt = document.createElement('option'); - opt.value = c.id; - opt.text = c.name; - newCategorySelect.appendChild(opt); - }); - } - }); - }, - - _loadProducts: function (categoryId, productSelect, lotSelect) { - var self = this; - var params = {}; - if (categoryId) params.category_id = categoryId; - - this._rpc('/my/loaner/products', params).then(function (products) { - self._allProducts = products || []; - self._renderProducts(self._allProducts, productSelect); - if (lotSelect) lotSelect.innerHTML = ''; - }); - }, - - _filterProducts: function (categoryId, productSelect, lotSelect) { - var filtered = this._allProducts; - if (categoryId) { - filtered = this._allProducts.filter(function (p) { return p.category_id === categoryId; }); - } - this._renderProducts(filtered, productSelect); - if (lotSelect) lotSelect.innerHTML = ''; - }, - - _renderProducts: function (products, productSelect) { - if (!productSelect) return; - productSelect.innerHTML = ''; - products.forEach(function (p) { - var opt = document.createElement('option'); - opt.value = p.id; - opt.text = p.name + ' (' + p.lots.length + ' avail)'; - productSelect.appendChild(opt); - }); - }, - - _filterLots: function (productId, lotSelect, loanDays) { - if (!lotSelect) return; - lotSelect.innerHTML = ''; - if (!productId) return; - var product = this._allProducts.find(function (p) { return p.id === productId; }); - if (product) { - product.lots.forEach(function (lot) { - var opt = document.createElement('option'); - opt.value = lot.id; - opt.text = lot.name; - lotSelect.appendChild(opt); - }); - if (loanDays && product.period_days) { - loanDays.value = product.period_days; - } - } - }, - - // ===================================================================== - // CHECKOUT BUTTON: Opens the modal - // ===================================================================== - _initCheckoutButton: function () { - var self = this; - var btns = document.querySelectorAll('#btn_checkout_loaner'); - btns.forEach(function (btn) { - btn.addEventListener('click', function () { - var orderId = btn.dataset.orderId || ''; - var clientId = btn.dataset.clientId || ''; - - // Set context in modal - var modalOrderId = document.getElementById('modal_order_id'); - var modalClientId = document.getElementById('modal_client_id'); - if (modalOrderId) modalOrderId.value = orderId; - if (modalClientId) modalClientId.value = clientId; - - // Show modal - var modal = document.getElementById('loanerCheckoutModal'); - self._showModal(modal); - }); - }); - }, - - // ===================================================================== - // RETURN BUTTONS - // ===================================================================== - _initReturnButtons: function () { - var self = this; - var returnModal = document.getElementById('loanerReturnModal'); - if (!returnModal) return; - - var btnSubmitReturn = document.getElementById('return_modal_btn_submit'); - - document.querySelectorAll('.btn-loaner-return').forEach(function (btn) { - btn.addEventListener('click', function () { - var checkoutId = parseInt(btn.dataset.checkoutId); - var productName = btn.dataset.productName || 'Loaner'; - - // Set modal values - document.getElementById('return_modal_checkout_id').value = checkoutId; - document.getElementById('return_modal_product_name').textContent = productName; - document.getElementById('return_modal_condition').value = 'good'; - document.getElementById('return_modal_notes').value = ''; - - // Load locations - var locSelect = document.getElementById('return_modal_location_id'); - locSelect.innerHTML = ''; - self._rpc('/my/loaner/locations', {}).then(function (locations) { - locations = locations || []; - locSelect.innerHTML = ''; - locations.forEach(function (l) { - var opt = document.createElement('option'); - opt.value = l.id; - opt.text = l.name; - locSelect.appendChild(opt); - }); - }); - - // Show modal - self._showModal(returnModal); - }); - }); - - // Submit return - if (btnSubmitReturn) { - btnSubmitReturn.addEventListener('click', function () { - var checkoutId = parseInt(document.getElementById('return_modal_checkout_id').value); - var condition = document.getElementById('return_modal_condition').value; - var notes = document.getElementById('return_modal_notes').value; - var locationId = document.getElementById('return_modal_location_id').value; - - btnSubmitReturn.disabled = true; - btnSubmitReturn.innerHTML = ' Processing...'; - - self._rpc('/my/loaner/return', { - checkout_id: checkoutId, - return_condition: condition, - return_notes: notes, - return_location_id: locationId ? parseInt(locationId) : null, - }).then(function (result) { - if (result.success) { - self._hideModal(returnModal); - alert(result.message); - location.reload(); - } else { - alert('Error: ' + (result.error || 'Unknown')); - btnSubmitReturn.disabled = false; - btnSubmitReturn.innerHTML = ' Confirm Return'; - } - }); - }); - } - }, - - // ===================================================================== - // EXPRESS ASSESSMENT: Loaner Section - // ===================================================================== - _initLoanerSection: function () { - var self = this; - var loanerSection = document.getElementById('loanerSection'); - if (!loanerSection) return; - - var productSelect = document.getElementById('loaner_product_id'); - var lotSelect = document.getElementById('loaner_lot_id'); - var periodInput = document.getElementById('loaner_period_days'); - var checkoutFlag = document.getElementById('loaner_checkout'); - var existingFields = document.getElementById('loaner_existing_fields'); - var newFields = document.getElementById('loaner_new_fields'); - var modeRadios = document.querySelectorAll('input[name="loaner_mode"]'); - var btnCreate = document.getElementById('btn_create_loaner_product'); - var createResult = document.getElementById('loaner_create_result'); - var productsData = []; - - loanerSection.addEventListener('show.bs.collapse', function () { - if (productSelect && productSelect.options.length <= 1) { - self._rpc('/my/loaner/products', {}).then(function (data) { - productsData = data || []; - productSelect.innerHTML = ''; - productsData.forEach(function (p) { - var opt = document.createElement('option'); - opt.value = p.id; - opt.text = p.name + ' (' + p.lots.length + ' avail)'; - productSelect.appendChild(opt); - }); - }); - } - }); - - loanerSection.addEventListener('shown.bs.collapse', function () { - if (checkoutFlag) checkoutFlag.value = '1'; - }); - loanerSection.addEventListener('hidden.bs.collapse', function () { - if (checkoutFlag) checkoutFlag.value = '0'; - }); - - modeRadios.forEach(function (radio) { - radio.addEventListener('change', function () { - if (this.value === 'existing') { - if (existingFields) existingFields.style.display = ''; - if (newFields) newFields.style.display = 'none'; - } else { - if (existingFields) existingFields.style.display = 'none'; - if (newFields) newFields.style.display = ''; - } - }); - }); - - if (productSelect) { - productSelect.addEventListener('change', function () { - lotSelect.innerHTML = ''; - var product = productsData.find(function (p) { return p.id === parseInt(productSelect.value); }); - if (product) { - product.lots.forEach(function (lot) { - var opt = document.createElement('option'); - opt.value = lot.id; - opt.text = lot.name; - lotSelect.appendChild(opt); - }); - if (periodInput && product.period_days) periodInput.value = product.period_days; - } - }); - } - - if (btnCreate) { - btnCreate.addEventListener('click', function () { - var name = document.getElementById('loaner_new_product_name').value.trim(); - var serial = document.getElementById('loaner_new_serial').value.trim(); - if (!name || !serial) { alert('Enter both name and serial.'); return; } - btnCreate.disabled = true; - btnCreate.innerHTML = ' Creating...'; - - self._rpc('/my/loaner/create-product', { - product_name: name, serial_number: serial, - }).then(function (result) { - if (result.success) { - var opt = document.createElement('option'); - opt.value = result.product_id; - opt.text = result.product_name; - opt.selected = true; - productSelect.appendChild(opt); - lotSelect.innerHTML = ''; - var lotOpt = document.createElement('option'); - lotOpt.value = result.lot_id; - lotOpt.text = result.lot_name; - lotOpt.selected = true; - lotSelect.appendChild(lotOpt); - document.getElementById('loaner_existing').checked = true; - if (existingFields) existingFields.style.display = ''; - if (newFields) newFields.style.display = 'none'; - if (createResult) { - createResult.style.display = ''; - createResult.innerHTML = '
      Created "' + result.product_name + '" (S/N: ' + result.lot_name + ')
      '; - } - } else { - if (createResult) { - createResult.style.display = ''; - createResult.innerHTML = '
      ' + (result.error || 'Error') + '
      '; - } - } - btnCreate.disabled = false; - btnCreate.innerHTML = ' Create Product'; - }); - }); - } - }, - - // ===================================================================== - // HELPERS - // ===================================================================== - _rpc: function (url, params) { - return fetch(url, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ jsonrpc: '2.0', method: 'call', id: 1, params: params }), - }).then(function (r) { return r.json(); }).then(function (d) { return d.result; }); - }, - - _showModal: function (modalEl) { - if (!modalEl) return; - var Modal = window.bootstrap ? window.bootstrap.Modal : null; - if (Modal) { - var inst = Modal.getOrCreateInstance ? Modal.getOrCreateInstance(modalEl) : new Modal(modalEl); - inst.show(); - } else if (window.$ || window.jQuery) { - (window.$ || window.jQuery)(modalEl).modal('show'); - } - }, - - _hideModal: function (modalEl) { - if (!modalEl) return; - try { - var Modal = window.bootstrap ? window.bootstrap.Modal : null; - if (Modal && Modal.getInstance) { - var inst = Modal.getInstance(modalEl); - if (inst) inst.hide(); - } else if (window.$ || window.jQuery) { - (window.$ || window.jQuery)(modalEl).modal('hide'); - } - } catch (e) { /* non-blocking */ } - }, -}); diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/pdf_field_editor.js b/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/pdf_field_editor.js deleted file mode 100644 index b8855e9..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/pdf_field_editor.js +++ /dev/null @@ -1,716 +0,0 @@ -/** - * Fusion PDF Field Position Editor - * - * Features: - * - Drag field types from sidebar palette onto PDF to create new fields - * - Drag existing fields to reposition them - * - Resize handles on each field (bottom-right corner) - * - Click to select and edit properties in right panel - * - Percentage-based positions (0.0-1.0), same as Odoo Sign module - * - Auto-save on every drag/resize - */ - -document.addEventListener('DOMContentLoaded', function () { - 'use strict'; - - var editor = document.getElementById('pdf_field_editor'); - if (!editor) return; - - var templateId = parseInt(editor.dataset.templateId); - var pageCount = parseInt(editor.dataset.pageCount) || 1; - var templateCategory = editor.dataset.category || 'other'; - var currentPage = 1; - var fields = {}; - var selectedFieldId = null; - var fieldCounter = 0; - var container = document.getElementById('pdf_canvas_container'); - var pageImage = document.getElementById('pdf_page_image'); - - // ================================================================ - // Colors per field type - // ================================================================ - - // ================================================================ - // Available data keys, organized by template category - // ================================================================ - - var COMMON_KEYS = [ - { group: 'Client Info', keys: [ - { key: 'client_last_name', label: 'Last Name' }, - { key: 'client_first_name', label: 'First Name' }, - { key: 'client_middle_name', label: 'Middle Name' }, - { key: 'client_name', label: 'Full Name' }, - { key: 'client_street', label: 'Street' }, - { key: 'client_unit', label: 'Unit/Apt' }, - { key: 'client_city', label: 'City' }, - { key: 'client_state', label: 'Province' }, - { key: 'client_postal_code', label: 'Postal Code' }, - { key: 'client_phone', label: 'Phone' }, - { key: 'client_email', label: 'Email' }, - ]}, - ]; - - var CATEGORY_KEYS = { - adp: [ - { group: 'ADP - Client Details', keys: [ - { key: 'client_health_card', label: 'Health Card Number' }, - { key: 'client_health_card_version', label: 'Health Card Version' }, - { key: 'client_weight', label: 'Weight (lbs)' }, - ]}, - { group: 'ADP - Client Type', keys: [ - { key: 'client_type_reg', label: 'REG Checkbox' }, - { key: 'client_type_ods', label: 'ODS Checkbox' }, - { key: 'client_type_acs', label: 'ACS Checkbox' }, - { key: 'client_type_owp', label: 'OWP Checkbox' }, - ]}, - { group: 'ADP - Consent', keys: [ - { key: 'consent_applicant', label: 'Applicant Checkbox' }, - { key: 'consent_agent', label: 'Agent Checkbox' }, - { key: 'consent_date', label: 'Consent Date' }, - ]}, - { group: 'ADP - Agent Relationship', keys: [ - { key: 'agent_rel_spouse', label: 'Spouse Checkbox' }, - { key: 'agent_rel_parent', label: 'Parent Checkbox' }, - { key: 'agent_rel_child', label: 'Child Checkbox' }, - { key: 'agent_rel_poa', label: 'POA Checkbox' }, - { key: 'agent_rel_guardian', label: 'Guardian Checkbox' }, - ]}, - { group: 'ADP - Agent Info', keys: [ - { key: 'agent_last_name', label: 'Agent Last Name' }, - { key: 'agent_first_name', label: 'Agent First Name' }, - { key: 'agent_middle_initial', label: 'Agent Middle Initial' }, - { key: 'agent_unit', label: 'Agent Unit' }, - { key: 'agent_street_number', label: 'Agent Street No.' }, - { key: 'agent_street_name', label: 'Agent Street Name' }, - { key: 'agent_city', label: 'Agent City' }, - { key: 'agent_province', label: 'Agent Province' }, - { key: 'agent_postal_code', label: 'Agent Postal Code' }, - { key: 'agent_home_phone', label: 'Agent Home Phone' }, - { key: 'agent_business_phone', label: 'Agent Business Phone' }, - { key: 'agent_phone_ext', label: 'Agent Phone Ext' }, - ]}, - { group: 'ADP - Equipment', keys: [ - { key: 'equipment_type', label: 'Equipment Type' }, - { key: 'seat_width', label: 'Seat Width' }, - { key: 'seat_depth', label: 'Seat Depth' }, - { key: 'seat_to_floor_height', label: 'Seat to Floor Height' }, - { key: 'back_height', label: 'Back Height' }, - { key: 'legrest_length', label: 'Legrest Length' }, - { key: 'cane_height', label: 'Cane Height' }, - ]}, - { group: 'ADP - Dates', keys: [ - { key: 'assessment_start_date', label: 'Assessment Start Date' }, - { key: 'assessment_end_date', label: 'Assessment End Date' }, - { key: 'claim_authorization_date', label: 'Authorization Date' }, - ]}, - { group: 'ADP - Authorizer', keys: [ - { key: 'authorizer_name', label: 'Authorizer Name' }, - { key: 'authorizer_phone', label: 'Authorizer Phone' }, - { key: 'authorizer_email', label: 'Authorizer Email' }, - ]}, - { group: 'ADP - Signatures', keys: [ - { key: 'signature_page_11', label: 'Page 11 Signature' }, - { key: 'signature_page_12', label: 'Page 12 Signature' }, - ]}, - { group: 'ADP - Other', keys: [ - { key: 'reference', label: 'Assessment Reference' }, - { key: 'reason_for_application', label: 'Reason for Application' }, - ]}, - ], - - odsp: [ - { group: 'ODSP - Signing Fields', keys: [ - { key: 'sa_client_name', label: 'Client Name (signing)' }, - { key: 'sa_sign_date', label: 'Signing Date' }, - { key: 'sa_signature', label: 'Client Signature' }, - ]}, - { group: 'ODSP - Client Details', keys: [ - { key: 'client_health_card', label: 'Health Card Number' }, - { key: 'client_health_card_version', label: 'Health Card Version' }, - { key: 'client_weight', label: 'Weight (lbs)' }, - ]}, - { group: 'ODSP - Dates', keys: [ - { key: 'assessment_start_date', label: 'Assessment Start Date' }, - { key: 'assessment_end_date', label: 'Assessment End Date' }, - ]}, - { group: 'ODSP - Authorizer', keys: [ - { key: 'authorizer_name', label: 'Authorizer Name' }, - { key: 'authorizer_phone', label: 'Authorizer Phone' }, - { key: 'authorizer_email', label: 'Authorizer Email' }, - ]}, - ], - - mod: [ - { group: 'MOD - Dates', keys: [ - { key: 'assessment_start_date', label: 'Assessment Start Date' }, - { key: 'assessment_end_date', label: 'Assessment End Date' }, - ]}, - { group: 'MOD - Authorizer', keys: [ - { key: 'authorizer_name', label: 'Authorizer Name' }, - { key: 'authorizer_phone', label: 'Authorizer Phone' }, - { key: 'authorizer_email', label: 'Authorizer Email' }, - ]}, - ], - - hardship: [ - { group: 'Hardship - Dates', keys: [ - { key: 'assessment_start_date', label: 'Assessment Start Date' }, - { key: 'assessment_end_date', label: 'Assessment End Date' }, - ]}, - { group: 'Hardship - Authorizer', keys: [ - { key: 'authorizer_name', label: 'Authorizer Name' }, - { key: 'authorizer_phone', label: 'Authorizer Phone' }, - { key: 'authorizer_email', label: 'Authorizer Email' }, - ]}, - ], - }; - - var DATA_KEYS = COMMON_KEYS.concat(CATEGORY_KEYS[templateCategory] || []); - - // Build a flat lookup: key -> label - var KEY_LABELS = {}; - DATA_KEYS.forEach(function (g) { - g.keys.forEach(function (k) { KEY_LABELS[k.key] = k.label; }); - }); - - // Build '; - DATA_KEYS.forEach(function (g) { - html += ''; - g.keys.forEach(function (k) { - html += ''; - }); - html += ''; - }); - return html; - } - - var COLORS = { - text: { bg: 'rgba(52,152,219,0.25)', border: '#3498db' }, - checkbox: { bg: 'rgba(46,204,113,0.25)', border: '#2ecc71' }, - date: { bg: 'rgba(230,126,34,0.25)', border: '#e67e22' }, - signature: { bg: 'rgba(155,89,182,0.25)', border: '#9b59b6' }, - }; - - var DEFAULT_SIZES = { - text: { w: 0.150, h: 0.018 }, - checkbox: { w: 0.018, h: 0.018 }, - date: { w: 0.120, h: 0.018 }, - signature: { w: 0.200, h: 0.050 }, - }; - - // ================================================================ - // JSONRPC helper - // ================================================================ - - function jsonrpc(url, params) { - return fetch(url, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ jsonrpc: '2.0', method: 'call', id: 1, params: params || {} }) - }).then(function (r) { return r.json(); }) - .then(function (d) { - if (d.error) { console.error('RPC error', d.error); return null; } - return d.result; - }); - } - - // ================================================================ - // Init - // ================================================================ - - function init() { - loadFields(); - setupPageNavigation(); - setupPaletteDrag(); - setupContainerDrop(); - setupPreviewButton(); - buildDataKeysSidebar(); - - // Prevent the image from intercepting drag events - if (pageImage) { - pageImage.style.pointerEvents = 'none'; - } - // Also prevent any child (except field markers) from blocking drops - container.querySelectorAll('#no_preview_placeholder').forEach(function (el) { - el.style.pointerEvents = 'none'; - }); - } - - function buildDataKeysSidebar() { - var list = document.getElementById('dataKeysList'); - if (!list) return; - var html = ''; - DATA_KEYS.forEach(function (g) { - html += '
      ' + g.group + ':
      '; - g.keys.forEach(function (k) { - html += '' + k.key + ''; - }); - }); - list.innerHTML = html; - } - - // ================================================================ - // Load fields - // ================================================================ - - function loadFields() { - jsonrpc('/fusion/pdf-editor/fields', { template_id: templateId }).then(function (result) { - if (!result) return; - fields = {}; - result.forEach(function (f) { fields[f.id] = f; fieldCounter++; }); - renderFieldsForPage(currentPage); - }); - } - - // ================================================================ - // Render fields on current page - // ================================================================ - - function renderFieldsForPage(page) { - container.querySelectorAll('.pdf-field-marker').forEach(function (el) { el.remove(); }); - Object.values(fields).forEach(function (f) { - if (f.page === page) renderFieldMarker(f); - }); - updateFieldCount(); - } - - function renderFieldMarker(field) { - var c = COLORS[field.field_type] || COLORS.text; - - var marker = document.createElement('div'); - marker.className = 'pdf-field-marker'; - marker.dataset.fieldId = field.id; - marker.setAttribute('draggable', 'true'); - - Object.assign(marker.style, { - position: 'absolute', - left: (field.pos_x * 100) + '%', - top: (field.pos_y * 100) + '%', - width: (field.width * 100) + '%', - height: Math.max(field.height * 100, 1.5) + '%', - backgroundColor: c.bg, - border: '2px solid ' + c.border, - borderRadius: '3px', - cursor: 'move', - display: 'flex', - alignItems: 'center', - fontSize: '10px', - color: '#333', - fontWeight: '600', - overflow: 'hidden', - whiteSpace: 'nowrap', - textOverflow: 'ellipsis', - padding: '0 4px', - zIndex: 10, - boxSizing: 'border-box', - userSelect: 'none', - }); - - // Label text - var label = document.createElement('span'); - label.style.pointerEvents = 'none'; - label.style.flex = '1'; - label.style.overflow = 'hidden'; - label.style.textOverflow = 'ellipsis'; - label.textContent = field.label || field.name; - marker.appendChild(label); - - // Resize handle (bottom-right corner) - var handle = document.createElement('div'); - Object.assign(handle.style, { - position: 'absolute', - right: '0', - bottom: '0', - width: '10px', - height: '10px', - backgroundColor: c.border, - cursor: 'nwse-resize', - borderRadius: '2px 0 2px 0', - opacity: '0.7', - }); - handle.className = 'resize-handle'; - handle.addEventListener('mousedown', function (e) { - e.preventDefault(); - e.stopPropagation(); - startResize(field.id, e); - }); - marker.appendChild(handle); - - // Tooltip - marker.title = (field.label || field.name) + '\nKey: ' + (field.field_key || 'unmapped') + '\nType: ' + field.field_type; - - // Drag to reposition - marker.addEventListener('dragstart', function (e) { onFieldDragStart(e, field.id); }); - marker.addEventListener('dragend', function (e) { e.target.style.opacity = ''; }); - - // Click to select - marker.addEventListener('click', function (e) { - e.stopPropagation(); - selectField(field.id); - }); - - container.appendChild(marker); - - // Highlight if selected - if (field.id === selectedFieldId) { - marker.style.boxShadow = '0 0 0 3px #007bff'; - marker.style.zIndex = '20'; - } - } - - // ================================================================ - // Drag existing fields to reposition - // ================================================================ - - var dragOffsetX = 0, dragOffsetY = 0; - var dragFieldId = null; - var dragSource = null; // 'field' or 'palette' - var dragFieldType = null; - - function onFieldDragStart(e, fieldId) { - dragSource = 'field'; - dragFieldId = fieldId; - var rect = e.target.getBoundingClientRect(); - dragOffsetX = e.clientX - rect.left; - dragOffsetY = e.clientY - rect.top; - e.dataTransfer.effectAllowed = 'move'; - e.dataTransfer.setData('text/plain', 'field'); - requestAnimationFrame(function () { e.target.style.opacity = '0.4'; }); - } - - // ================================================================ - // Drag from palette to create new field - // ================================================================ - - function setupPaletteDrag() { - document.querySelectorAll('.pdf-palette-item').forEach(function (item) { - item.addEventListener('dragstart', function (e) { - dragSource = 'palette'; - dragFieldType = e.currentTarget.dataset.fieldType; - dragFieldId = null; - e.dataTransfer.effectAllowed = 'copy'; - e.dataTransfer.setData('text/plain', 'palette'); - e.currentTarget.style.opacity = '0.5'; - }); - item.addEventListener('dragend', function (e) { - e.currentTarget.style.opacity = ''; - }); - }); - } - - // ================================================================ - // Drop handler on PDF container - // ================================================================ - - function setupContainerDrop() { - // Must preventDefault on dragover for drop to fire - container.addEventListener('dragover', function (e) { - e.preventDefault(); - e.stopPropagation(); - e.dataTransfer.dropEffect = (dragSource === 'palette') ? 'copy' : 'move'; - }); - - container.addEventListener('dragenter', function (e) { - e.preventDefault(); - e.stopPropagation(); - }); - - container.addEventListener('drop', function (e) { - e.preventDefault(); - e.stopPropagation(); - - // Use the container rect as the reference area - // (the image has pointer-events:none, so we use the container which matches its size) - var rect = container.getBoundingClientRect(); - - if (dragSource === 'palette' && dragFieldType) { - // ---- CREATE new field at drop position ---- - var defaults = DEFAULT_SIZES[dragFieldType] || DEFAULT_SIZES.text; - var posX = (e.clientX - rect.left) / rect.width; - var posY = (e.clientY - rect.top) / rect.height; - posX = normalize(posX, defaults.w); - posY = normalize(posY, defaults.h); - posX = round3(posX); - posY = round3(posY); - - fieldCounter++; - var autoName = dragFieldType + '_' + fieldCounter; - - var newField = { - template_id: templateId, - name: autoName, - label: autoName, - field_type: dragFieldType, - field_key: autoName, - page: currentPage, - pos_x: posX, - pos_y: posY, - width: defaults.w, - height: defaults.h, - font_size: 10, - }; - - jsonrpc('/fusion/pdf-editor/create-field', newField).then(function (res) { - if (res && res.id) { - newField.id = res.id; - fields[res.id] = newField; - renderFieldsForPage(currentPage); - selectField(res.id); - } - }); - - } else if (dragSource === 'field' && dragFieldId && fields[dragFieldId]) { - // ---- MOVE existing field ---- - var field = fields[dragFieldId]; - var posX = (e.clientX - rect.left - dragOffsetX) / rect.width; - var posY = (e.clientY - rect.top - dragOffsetY) / rect.height; - posX = normalize(posX, field.width); - posY = normalize(posY, field.height); - posX = round3(posX); - posY = round3(posY); - - field.pos_x = posX; - field.pos_y = posY; - saveField(field.id, { pos_x: posX, pos_y: posY }); - renderFieldsForPage(currentPage); - selectField(field.id); - } - - dragSource = null; - dragFieldId = null; - dragFieldType = null; - }); - } - - // ================================================================ - // Resize handles - // ================================================================ - - function startResize(fieldId, startEvent) { - var field = fields[fieldId]; - if (!field) return; - - var imgRect = container.getBoundingClientRect(); - var startX = startEvent.clientX; - var startY = startEvent.clientY; - var startW = field.width; - var startH = field.height; - var marker = container.querySelector('[data-field-id="' + fieldId + '"]'); - - function onMove(e) { - var dx = (e.clientX - startX) / imgRect.width; - var dy = (e.clientY - startY) / imgRect.height; - var newW = Math.max(startW + dx, 0.010); - var newH = Math.max(startH + dy, 0.005); - - // Clamp to page bounds - if (field.pos_x + newW > 1.0) newW = 1.0 - field.pos_x; - if (field.pos_y + newH > 1.0) newH = 1.0 - field.pos_y; - - field.width = round3(newW); - field.height = round3(newH); - - if (marker) { - marker.style.width = (field.width * 100) + '%'; - marker.style.height = Math.max(field.height * 100, 1.5) + '%'; - } - } - - function onUp() { - document.removeEventListener('mousemove', onMove); - document.removeEventListener('mouseup', onUp); - saveField(fieldId, { width: field.width, height: field.height }); - renderFieldsForPage(currentPage); - selectField(fieldId); - } - - document.addEventListener('mousemove', onMove); - document.addEventListener('mouseup', onUp); - } - - // ================================================================ - // Select field and show properties - // ================================================================ - - function selectField(fieldId) { - selectedFieldId = fieldId; - var field = fields[fieldId]; - if (!field) return; - - // Re-render to update highlights - renderFieldsForPage(currentPage); - - var panel = document.getElementById('field_props_body'); - panel.innerHTML = '' - + '
      ' - + ' ' - + ' ' - + '
      ' - + row('Name', 'text', 'prop_name', field.name || '') - + row('Label', 'text', 'prop_label', field.label || '') - + '
      ' - + ' ' - + ' ' - + '
      ' - + '
      ' - + '
      ' + row('Font Size', 'number', 'prop_font_size', field.font_size || 10, '0.5') + '
      ' - + '
      ' + row('Page', 'number', 'prop_page', field.page || 1) + '
      ' - + '
      ' - + '
      ' - + '
      ' + row('Width', 'number', 'prop_width', field.width || 0.15, '0.005') + '
      ' - + '
      ' + row('Height', 'number', 'prop_height', field.height || 0.015, '0.005') + '
      ' - + '
      ' - + '
      ' - + '
      ' - + '
      ' - + '
      ' - + '
      ' - + '
      ' - + '
      ' - + ' ' - + '
      ' - + ' ' - + ' ' - + ' ' - + '
      ' - + '
      ' - + '
      ' - + ' ' - + ' ' - + '
      '; - - // Auto-fill name and label when data key is selected - document.getElementById('prop_field_key').addEventListener('change', function () { - var selectedKey = this.value; - if (selectedKey && KEY_LABELS[selectedKey]) { - document.getElementById('prop_name').value = selectedKey; - document.getElementById('prop_label').value = KEY_LABELS[selectedKey]; - } - }); - - var alignBtns = panel.querySelectorAll('[data-align]'); - alignBtns.forEach(function (btn) { - btn.addEventListener('click', function () { - alignBtns.forEach(function (b) { b.classList.remove('active'); }); - btn.classList.add('active'); - }); - }); - - document.getElementById('btn_save_props').addEventListener('click', function () { - var keySelect = document.getElementById('prop_field_key'); - var selectedKey = keySelect ? keySelect.value : ''; - var activeAlign = panel.querySelector('[data-align].active'); - var vals = { - name: val('prop_name'), - label: val('prop_label'), - field_key: selectedKey, - field_type: val('prop_type'), - font_size: parseFloat(val('prop_font_size')) || 10, - page: parseInt(val('prop_page')) || 1, - width: parseFloat(val('prop_width')) || 0.15, - height: parseFloat(val('prop_height')) || 0.015, - text_align: activeAlign ? activeAlign.dataset.align : 'left', - }; - Object.assign(field, vals); - saveField(fieldId, vals); - renderFieldsForPage(currentPage); - selectField(fieldId); - }); - - document.getElementById('btn_delete_field').addEventListener('click', function () { - if (!confirm('Delete "' + (field.label || field.name) + '"?')) return; - jsonrpc('/fusion/pdf-editor/delete-field', { field_id: fieldId }).then(function () { - delete fields[fieldId]; - selectedFieldId = null; - renderFieldsForPage(currentPage); - panel.innerHTML = '

      Field deleted.

      '; - }); - }); - } - - // ================================================================ - // Save field to server - // ================================================================ - - function saveField(fieldId, values) { - jsonrpc('/fusion/pdf-editor/update-field', { field_id: fieldId, values: values }); - } - - // ================================================================ - // Page navigation - // ================================================================ - - function setupPageNavigation() { - var prev = document.getElementById('btn_prev_page'); - var next = document.getElementById('btn_next_page'); - if (prev) prev.addEventListener('click', function () { if (currentPage > 1) switchPage(--currentPage); }); - if (next) next.addEventListener('click', function () { if (currentPage < pageCount) switchPage(++currentPage); }); - } - - function switchPage(page) { - currentPage = page; - var d = document.getElementById('current_page_display'); - if (d) d.textContent = page; - jsonrpc('/fusion/pdf-editor/page-image', { template_id: templateId, page: page }).then(function (r) { - if (r && r.image_url && pageImage) pageImage.src = r.image_url; - renderFieldsForPage(page); - }); - } - - // ================================================================ - // Preview - // ================================================================ - - function setupPreviewButton() { - var btn = document.getElementById('btn_preview'); - if (btn) btn.addEventListener('click', function () { - window.open('/fusion/pdf-editor/preview/' + templateId, '_blank'); - }); - } - - // ================================================================ - // Helpers - // ================================================================ - - function normalize(pos, dim) { - if (pos < 0) return 0; - if (pos + dim > 1.0) return 1.0 - dim; - return pos; - } - - function round3(n) { return Math.round((n || 0) * 1000) / 1000; } - - function val(id) { var el = document.getElementById(id); return el ? el.value : ''; } - - function sel(current, option) { return current === option ? ' selected' : ''; } - - function row(label, type, id, value, step) { - return '
      ' - + '
      '; - } - - function updateFieldCount() { - var el = document.getElementById('field_count'); - if (el) el.textContent = Object.keys(fields).length; - } - - // ================================================================ - // Start - // ================================================================ - - init(); -}); diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/portal_search.js b/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/portal_search.js deleted file mode 100644 index 7961773..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/portal_search.js +++ /dev/null @@ -1,161 +0,0 @@ -/** - * Fusion Authorizer Portal - Real-time Search - */ - -odoo.define('fusion_authorizer_portal.portal_search', function (require) { - 'use strict'; - - var publicWidget = require('web.public.widget'); - var ajax = require('web.ajax'); - - publicWidget.registry.PortalSearch = publicWidget.Widget.extend({ - selector: '#portal-search-input', - events: { - 'input': '_onSearchInput', - 'keydown': '_onKeyDown', - }, - - init: function () { - this._super.apply(this, arguments); - this.debounceTimer = null; - this.searchEndpoint = this._getSearchEndpoint(); - this.resultsContainer = null; - }, - - start: function () { - this._super.apply(this, arguments); - this.resultsContainer = document.getElementById('cases-table-body'); - return Promise.resolve(); - }, - - _getSearchEndpoint: function () { - // Determine which portal we're on - var path = window.location.pathname; - if (path.includes('/my/authorizer')) { - return '/my/authorizer/cases/search'; - } else if (path.includes('/my/sales')) { - return '/my/sales/cases/search'; - } - return null; - }, - - _onSearchInput: function (ev) { - var self = this; - var query = ev.target.value.trim(); - - clearTimeout(this.debounceTimer); - - if (query.length < 2) { - // If query is too short, reload original page - return; - } - - // Debounce - wait 250ms before searching - this.debounceTimer = setTimeout(function () { - self._performSearch(query); - }, 250); - }, - - _onKeyDown: function (ev) { - if (ev.key === 'Enter') { - ev.preventDefault(); - var query = ev.target.value.trim(); - if (query.length >= 2) { - this._performSearch(query); - } - } else if (ev.key === 'Escape') { - ev.target.value = ''; - window.location.reload(); - } - }, - - _performSearch: function (query) { - var self = this; - - if (!this.searchEndpoint) { - console.error('Search endpoint not found'); - return; - } - - // Show loading indicator - this._showLoading(true); - - ajax.jsonRpc(this.searchEndpoint, 'call', { - query: query - }).then(function (response) { - self._showLoading(false); - - if (response.error) { - console.error('Search error:', response.error); - return; - } - - self._renderResults(response.results, query); - }).catch(function (error) { - self._showLoading(false); - console.error('Search failed:', error); - }); - }, - - _showLoading: function (show) { - var spinner = document.querySelector('.search-loading'); - if (spinner) { - spinner.classList.toggle('active', show); - } - }, - - _renderResults: function (results, query) { - if (!this.resultsContainer) { - return; - } - - if (!results || results.length === 0) { - this.resultsContainer.innerHTML = ` - - - -

      No results found for "${query}"

      - - - `; - return; - } - - var html = ''; - var isAuthorizer = window.location.pathname.includes('/my/authorizer'); - var baseUrl = isAuthorizer ? '/my/authorizer/case/' : '/my/sales/case/'; - - results.forEach(function (order) { - var stateClass = 'bg-secondary'; - if (order.state === 'sent') stateClass = 'bg-primary'; - else if (order.state === 'sale') stateClass = 'bg-success'; - - html += ` - - ${self._highlightMatch(order.name, query)} - ${self._highlightMatch(order.partner_name, query)} - ${order.date_order} - ${self._highlightMatch(order.claim_number || '-', query)} - ${order.state_display} - - - View - - - - `; - }); - - this.resultsContainer.innerHTML = html; - }, - - _highlightMatch: function (text, query) { - if (!text || !query) return text || ''; - - var regex = new RegExp('(' + query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + ')', 'gi'); - return text.replace(regex, '$1'); - } - }); - - return publicWidget.registry.PortalSearch; -}); diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/signature_pad.js b/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/signature_pad.js deleted file mode 100644 index d12bc22..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/signature_pad.js +++ /dev/null @@ -1,167 +0,0 @@ -/** - * Fusion Authorizer Portal - Signature Pad - * Touch-enabled digital signature capture - */ - -odoo.define('fusion_authorizer_portal.signature_pad', function (require) { - 'use strict'; - - var publicWidget = require('web.public.widget'); - var ajax = require('web.ajax'); - - // Signature Pad Class - var SignaturePad = function (canvas, options) { - this.canvas = canvas; - this.ctx = canvas.getContext('2d'); - this.options = Object.assign({ - strokeColor: '#000000', - strokeWidth: 2, - backgroundColor: '#ffffff' - }, options || {}); - - this.isDrawing = false; - this.lastX = 0; - this.lastY = 0; - this.points = []; - - this._initialize(); - }; - - SignaturePad.prototype = { - _initialize: function () { - var self = this; - - // Set canvas size - this._resizeCanvas(); - - // Set drawing style - this.ctx.strokeStyle = this.options.strokeColor; - this.ctx.lineWidth = this.options.strokeWidth; - this.ctx.lineCap = 'round'; - this.ctx.lineJoin = 'round'; - - // Clear with background color - this.clear(); - - // Event listeners - this.canvas.addEventListener('mousedown', this._startDrawing.bind(this)); - this.canvas.addEventListener('mousemove', this._draw.bind(this)); - this.canvas.addEventListener('mouseup', this._stopDrawing.bind(this)); - this.canvas.addEventListener('mouseout', this._stopDrawing.bind(this)); - - // Touch events - this.canvas.addEventListener('touchstart', this._startDrawing.bind(this), { passive: false }); - this.canvas.addEventListener('touchmove', this._draw.bind(this), { passive: false }); - this.canvas.addEventListener('touchend', this._stopDrawing.bind(this), { passive: false }); - this.canvas.addEventListener('touchcancel', this._stopDrawing.bind(this), { passive: false }); - - // Resize handler - window.addEventListener('resize', this._resizeCanvas.bind(this)); - }, - - _resizeCanvas: function () { - var rect = this.canvas.getBoundingClientRect(); - var ratio = window.devicePixelRatio || 1; - - this.canvas.width = rect.width * ratio; - this.canvas.height = rect.height * ratio; - - this.ctx.scale(ratio, ratio); - this.canvas.style.width = rect.width + 'px'; - this.canvas.style.height = rect.height + 'px'; - - // Restore drawing style after resize - this.ctx.strokeStyle = this.options.strokeColor; - this.ctx.lineWidth = this.options.strokeWidth; - this.ctx.lineCap = 'round'; - this.ctx.lineJoin = 'round'; - }, - - _getPos: function (e) { - var rect = this.canvas.getBoundingClientRect(); - var x, y; - - if (e.touches && e.touches.length > 0) { - x = e.touches[0].clientX - rect.left; - y = e.touches[0].clientY - rect.top; - } else { - x = e.clientX - rect.left; - y = e.clientY - rect.top; - } - - return { x: x, y: y }; - }, - - _startDrawing: function (e) { - e.preventDefault(); - this.isDrawing = true; - var pos = this._getPos(e); - this.lastX = pos.x; - this.lastY = pos.y; - this.points.push({ x: pos.x, y: pos.y, start: true }); - }, - - _draw: function (e) { - e.preventDefault(); - if (!this.isDrawing) return; - - var pos = this._getPos(e); - - this.ctx.beginPath(); - this.ctx.moveTo(this.lastX, this.lastY); - this.ctx.lineTo(pos.x, pos.y); - this.ctx.stroke(); - - this.lastX = pos.x; - this.lastY = pos.y; - this.points.push({ x: pos.x, y: pos.y }); - }, - - _stopDrawing: function (e) { - e.preventDefault(); - this.isDrawing = false; - }, - - clear: function () { - this.ctx.fillStyle = this.options.backgroundColor; - this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); - this.points = []; - }, - - isEmpty: function () { - return this.points.length === 0; - }, - - toDataURL: function (type, quality) { - return this.canvas.toDataURL(type || 'image/png', quality || 1.0); - } - }; - - // Make SignaturePad available globally for inline scripts - window.SignaturePad = SignaturePad; - - // Widget for signature pads in portal - publicWidget.registry.SignaturePadWidget = publicWidget.Widget.extend({ - selector: '.signature-pad-container', - - start: function () { - this._super.apply(this, arguments); - - var canvas = this.el.querySelector('canvas'); - if (canvas) { - this.signaturePad = new SignaturePad(canvas); - } - - return Promise.resolve(); - }, - - getSignaturePad: function () { - return this.signaturePad; - } - }); - - return { - SignaturePad: SignaturePad, - Widget: publicWidget.registry.SignaturePadWidget - }; -}); diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/technician_location.js b/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/technician_location.js deleted file mode 100644 index 25b6e82..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/technician_location.js +++ /dev/null @@ -1,97 +0,0 @@ -/** - * Technician Location Logger - * Logs GPS location every 5 minutes during working hours (9 AM - 6 PM) - * Only logs while the browser tab is visible. - */ -(function () { - 'use strict'; - - var INTERVAL_MS = 5 * 60 * 1000; // 5 minutes - var STORE_OPEN_HOUR = 9; - var STORE_CLOSE_HOUR = 18; - var locationTimer = null; - - function isWorkingHours() { - var now = new Date(); - var hour = now.getHours(); - return hour >= STORE_OPEN_HOUR && hour < STORE_CLOSE_HOUR; - } - - function isTechnicianPortal() { - // Check if we're on a technician portal page - return window.location.pathname.indexOf('/my/technician') !== -1; - } - - function logLocation() { - if (!isWorkingHours()) { - return; - } - if (document.hidden) { - return; - } - if (!navigator.geolocation) { - return; - } - - navigator.geolocation.getCurrentPosition( - function (position) { - var data = { - jsonrpc: '2.0', - method: 'call', - params: { - latitude: position.coords.latitude, - longitude: position.coords.longitude, - accuracy: position.coords.accuracy || 0, - } - }; - fetch('/my/technician/location/log', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(data), - }).catch(function () { - // Silently fail - location logging is best-effort - }); - }, - function () { - // Geolocation permission denied or error - silently ignore - }, - { enableHighAccuracy: true, timeout: 10000, maximumAge: 60000 } - ); - } - - function startLocationLogging() { - if (!isTechnicianPortal()) { - return; - } - - // Log immediately on page load - logLocation(); - - // Set interval for periodic logging - locationTimer = setInterval(logLocation, INTERVAL_MS); - - // Pause/resume on tab visibility change - document.addEventListener('visibilitychange', function () { - if (document.hidden) { - // Tab hidden - clear interval to save battery - if (locationTimer) { - clearInterval(locationTimer); - locationTimer = null; - } - } else { - // Tab visible again - log immediately and restart interval - logLocation(); - if (!locationTimer) { - locationTimer = setInterval(logLocation, INTERVAL_MS); - } - } - }); - } - - // Start when DOM is ready - if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', startLocationLogging); - } else { - startLocationLogging(); - } -})(); diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/technician_push.js b/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/technician_push.js deleted file mode 100644 index b4ae92d..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/technician_push.js +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Fusion Technician Portal - Push Notification Registration - * Registers service worker and subscribes to push notifications. - * Include this script on technician portal pages. - */ - -(function() { - 'use strict'; - - // Only run on technician portal pages - if (!document.querySelector('.tech-portal') && !window.location.pathname.startsWith('/my/technician')) { - return; - } - - // Get VAPID public key from meta tag or page data - var vapidMeta = document.querySelector('meta[name="vapid-public-key"]'); - var vapidPublicKey = vapidMeta ? vapidMeta.content : null; - - if (!vapidPublicKey || !('serviceWorker' in navigator) || !('PushManager' in window)) { - return; - } - - function urlBase64ToUint8Array(base64String) { - var padding = '='.repeat((4 - base64String.length % 4) % 4); - var base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/'); - var rawData = window.atob(base64); - var outputArray = new Uint8Array(rawData.length); - for (var i = 0; i < rawData.length; ++i) { - outputArray[i] = rawData.charCodeAt(i); - } - return outputArray; - } - - async function registerPushSubscription() { - try { - // Register service worker - var registration = await navigator.serviceWorker.register( - '/fusion_authorizer_portal/static/src/js/technician_sw.js', - {scope: '/my/technician/'} - ); - - // Wait for service worker to be ready - await navigator.serviceWorker.ready; - - // Check existing subscription - var subscription = await registration.pushManager.getSubscription(); - - if (!subscription) { - // Request permission - var permission = await Notification.requestPermission(); - if (permission !== 'granted') { - console.log('[TechPush] Notification permission denied'); - return; - } - - // Subscribe - subscription = await registration.pushManager.subscribe({ - userVisibleOnly: true, - applicationServerKey: urlBase64ToUint8Array(vapidPublicKey), - }); - } - - // Send subscription to server - var key = subscription.getKey('p256dh'); - var auth = subscription.getKey('auth'); - - var response = await fetch('/my/technician/push/subscribe', { - method: 'POST', - headers: {'Content-Type': 'application/json'}, - body: JSON.stringify({ - jsonrpc: '2.0', - method: 'call', - params: { - endpoint: subscription.endpoint, - p256dh: btoa(String.fromCharCode.apply(null, new Uint8Array(key))), - auth: btoa(String.fromCharCode.apply(null, new Uint8Array(auth))), - } - }), - }); - - var data = await response.json(); - if (data.result && data.result.success) { - console.log('[TechPush] Push subscription registered successfully'); - } - } catch (error) { - console.warn('[TechPush] Push registration failed:', error); - } - } - - // Register after page load - if (document.readyState === 'complete') { - registerPushSubscription(); - } else { - window.addEventListener('load', registerPushSubscription); - } -})(); diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/technician_sw.js b/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/technician_sw.js deleted file mode 100644 index d18a7a5..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/js/technician_sw.js +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Fusion Technician Portal - Service Worker for Push Notifications - * Handles push events and notification clicks. - */ - -self.addEventListener('push', function(event) { - if (!event.data) return; - - var data; - try { - data = event.data.json(); - } catch (e) { - data = {title: 'New Notification', body: event.data.text()}; - } - - var options = { - body: data.body || '', - icon: '/fusion_authorizer_portal/static/description/icon.png', - badge: '/fusion_authorizer_portal/static/description/icon.png', - tag: 'tech-task-' + (data.task_id || 'general'), - renotify: true, - data: { - url: data.url || '/my/technician', - taskId: data.task_id, - taskType: data.task_type, - }, - actions: [], - }; - - // Add contextual actions based on task type - if (data.url) { - options.actions.push({action: 'view', title: 'View Task'}); - } - if (data.task_type === 'delivery' || data.task_type === 'repair') { - options.actions.push({action: 'navigate', title: 'Navigate'}); - } - - event.waitUntil( - self.registration.showNotification(data.title || 'Fusion Technician', options) - ); -}); - -self.addEventListener('notificationclick', function(event) { - event.notification.close(); - - var url = '/my/technician'; - if (event.notification.data && event.notification.data.url) { - url = event.notification.data.url; - } - - if (event.action === 'navigate' && event.notification.data && event.notification.data.taskId) { - // Open Google Maps for the task (will redirect through portal) - url = '/my/technician/task/' + event.notification.data.taskId; - } - - event.waitUntil( - clients.matchAll({type: 'window', includeUncontrolled: true}).then(function(clientList) { - // Focus existing window if open - for (var i = 0; i < clientList.length; i++) { - var client = clientList[i]; - if (client.url.indexOf('/my/technician') !== -1 && 'focus' in client) { - client.navigate(url); - return client.focus(); - } - } - // Open new window - if (clients.openWindow) { - return clients.openWindow(url); - } - }) - ); -}); - -// Keep service worker alive -self.addEventListener('activate', function(event) { - event.waitUntil(self.clients.claim()); -}); diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/xml/chatter_message_authorizer.xml b/fusion_authorizer_portal/fusion_authorizer_portal/static/src/xml/chatter_message_authorizer.xml deleted file mode 100644 index 953e437..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/static/src/xml/chatter_message_authorizer.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/utils/__init__.py b/fusion_authorizer_portal/fusion_authorizer_portal/utils/__init__.py deleted file mode 100644 index e01b420..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/utils/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- - -from . import pdf_filler diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/utils/pdf_filler.py b/fusion_authorizer_portal/fusion_authorizer_portal/utils/pdf_filler.py deleted file mode 100644 index feaca15..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/utils/pdf_filler.py +++ /dev/null @@ -1,146 +0,0 @@ -# -*- coding: utf-8 -*- -# Fusion PDF Template Filler -# Generic utility for filling any PDF template with data overlays. -# Uses the same pattern as Odoo Enterprise Sign module (sign/utils/pdf_handling.py): -# - Read original PDF page dimensions from mediaBox -# - Create reportlab Canvas overlay at the same page size -# - Convert percentage positions (0.0-1.0) to absolute PDF coordinates -# - Merge overlay onto original page via mergePage() - -import logging -from io import BytesIO - -from reportlab.pdfgen import canvas -from reportlab.lib.utils import ImageReader - -from odoo.tools.pdf import PdfFileReader, PdfFileWriter - -_logger = logging.getLogger(__name__) - - -class PDFTemplateFiller: - """Generic PDF template filler. Works with any template, any number of pages.""" - - @staticmethod - def fill_template(template_pdf_bytes, fields_by_page, context, signatures=None): - """Fill a PDF template by overlaying text/checkmarks/signatures at configured positions. - - Args: - template_pdf_bytes: bytes of the original PDF - fields_by_page: {page_num: [field_dicts]} where page_num is 1-based - Each field_dict has: field_key, pos_x, pos_y, width, height, - field_type, font_size, font_name - context: flat dict of {field_key: value} with all available data - signatures: dict of {field_key: binary_png} for signature image fields - - Returns: - bytes of the filled PDF (all pages preserved) - """ - if signatures is None: - signatures = {} - - try: - original = PdfFileReader(BytesIO(template_pdf_bytes)) - except Exception as e: - _logger.error("Failed to read template PDF: %s", e) - raise - - output = PdfFileWriter() - num_pages = original.getNumPages() - - for page_idx in range(num_pages): - page = original.getPage(page_idx) - page_num = page_idx + 1 # 1-based page number - page_w = float(page.mediaBox.getWidth()) - page_h = float(page.mediaBox.getHeight()) - - fields = fields_by_page.get(page_num, []) - - if fields: - # Create a transparent overlay for this page - overlay_buf = BytesIO() - c = canvas.Canvas(overlay_buf, pagesize=(page_w, page_h)) - - for field in fields: - PDFTemplateFiller._draw_field( - c, field, context, signatures, page_w, page_h - ) - - c.save() - overlay_buf.seek(0) - - # Merge overlay onto original page (same as sign module) - overlay_pdf = PdfFileReader(overlay_buf) - page.mergePage(overlay_pdf.getPage(0)) - - output.addPage(page) - - result = BytesIO() - output.write(result) - return result.getvalue() - - @staticmethod - def _draw_field(c, field, context, signatures, page_w, page_h): - """Draw a single field onto the reportlab canvas. - - Args: - c: reportlab Canvas - field: dict with field_key, pos_x, pos_y, width, height, field_type, etc. - context: data context dict - signatures: dict of {field_key: binary} for signature fields - page_w: page width in PDF points - page_h: page height in PDF points - """ - field_key = field.get('field_key') or field.get('field_name', '') - field_type = field.get('field_type', 'text') - value = context.get(field_key, field.get('default_value', '')) - - if not value and field_type != 'signature': - return - - # Convert percentage positions to absolute PDF coordinates - # pos_x/pos_y are 0.0-1.0 ratios from top-left - # PDF coordinate system: origin at bottom-left, Y goes up - abs_x = field['pos_x'] * page_w - abs_y = page_h - (field['pos_y'] * page_h) # flip Y axis - - font_name = field.get('font_name', 'Helvetica') - font_size = field.get('font_size', 10.0) - - if field_type in ('text', 'date'): - c.setFont(font_name, font_size) - text_val = str(value) - field_h = field.get('height', 0.018) * page_h - text_y = abs_y - field_h + (field_h - font_size) / 2 - align = field.get('text_align', 'left') - if align == 'center': - center_x = abs_x + (field.get('width', 0.15) * page_w) / 2 - c.drawCentredString(center_x, text_y, text_val) - elif align == 'right': - right_x = abs_x + field.get('width', 0.15) * page_w - c.drawRightString(right_x, text_y, text_val) - else: - c.drawString(abs_x, text_y, text_val) - - elif field_type == 'checkbox': - if value: - c.setFont('ZapfDingbats', font_size) - cb_h = field.get('height', 0.018) * page_h - cb_y = abs_y - cb_h + (cb_h - font_size) / 2 - c.drawString(abs_x, cb_y, '4') - - elif field_type == 'signature': - sig_data = signatures.get(field_key) - if sig_data: - try: - img = ImageReader(BytesIO(sig_data)) - sig_w = field.get('width', 0.15) * page_w - sig_h = field.get('height', 0.05) * page_h - # Draw signature image (position from top, so adjust Y) - c.drawImage( - img, abs_x, abs_y - sig_h, - width=sig_w, height=sig_h, - mask='auto', - ) - except Exception as e: - _logger.warning("Failed to draw signature for %s: %s", field_key, e) diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/views/assessment_views.xml b/fusion_authorizer_portal/fusion_authorizer_portal/views/assessment_views.xml deleted file mode 100644 index afcf13f..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/views/assessment_views.xml +++ /dev/null @@ -1,258 +0,0 @@ - - - - - - fusion.assessment.tree - fusion.assessment - - - - - - - - - - - - - - - - - fusion.assessment.form - fusion.assessment - -
      -
      -
      - -
      - - -
      - -
      -

      - -

      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      -
      - - - -
      -
      -
      -
      - - - - fusion.assessment.search - fusion.assessment - - - - - - - - - - - - - - - - - - - - - - - - - - Assessments - fusion.assessment - list,form - - {'search_default_my_assessments': 1} - -

      - Create your first assessment -

      -

      - Assessments are used to record wheelchair specifications and client needs. - Once completed, they will create a draft sale order for review. -

      -
      -
      - - - - - - -
      diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/views/pdf_template_views.xml b/fusion_authorizer_portal/fusion_authorizer_portal/views/pdf_template_views.xml deleted file mode 100644 index b387c01..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/views/pdf_template_views.xml +++ /dev/null @@ -1,171 +0,0 @@ - - - - - - - - fusion.pdf.template.form - fusion.pdf.template - -
      -
      -
      - -
      -

      - -

      -
      - - - - - - - - - - - - - - - -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      -
      -
      -
      - - - - - - fusion.pdf.template.list - fusion.pdf.template - - - - - - - - - - - - - - - - - fusion.pdf.template.search - fusion.pdf.template - - - - - - - - - - - - - - - - - - PDF Templates - fusion.pdf.template - list,form - - {'search_default_active_templates': 1} - -

      - Create your first PDF template -

      -

      - Upload a funding agency's PDF form, position fields on it using the - visual editor, and generate filled PDFs automatically from assessment data. -

      -
      -
      - - - - - - - -
      diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/views/portal_accessibility_forms.xml b/fusion_authorizer_portal/fusion_authorizer_portal/views/portal_accessibility_forms.xml deleted file mode 100644 index 6e389ae..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/views/portal_accessibility_forms.xml +++ /dev/null @@ -1,1222 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/views/portal_accessibility_templates.xml b/fusion_authorizer_portal/fusion_authorizer_portal/views/portal_accessibility_templates.xml deleted file mode 100644 index 89de1c1..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/views/portal_accessibility_templates.xml +++ /dev/null @@ -1,712 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/views/portal_assessment_express.xml b/fusion_authorizer_portal/fusion_authorizer_portal/views/portal_assessment_express.xml deleted file mode 100644 index d2a625d..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/views/portal_assessment_express.xml +++ /dev/null @@ -1,1622 +0,0 @@ - - - - - - diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/views/portal_book_assessment.xml b/fusion_authorizer_portal/fusion_authorizer_portal/views/portal_book_assessment.xml deleted file mode 100644 index c3cdef0..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/views/portal_book_assessment.xml +++ /dev/null @@ -1,153 +0,0 @@ - - - - - diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/views/portal_pdf_editor.xml b/fusion_authorizer_portal/fusion_authorizer_portal/views/portal_pdf_editor.xml deleted file mode 100644 index 4988196..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/views/portal_pdf_editor.xml +++ /dev/null @@ -1,184 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/fusion_authorizer_portal/fusion_authorizer_portal/views/res_partner_views.xml b/fusion_authorizer_portal/fusion_authorizer_portal/views/res_partner_views.xml deleted file mode 100644 index be9835a..0000000 --- a/fusion_authorizer_portal/fusion_authorizer_portal/views/res_partner_views.xml +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - res.partner.form.portal.roles - res.partner - - 50 - - - - ' - + ''; + + '
      ' + + ' ' + + '
      ' + + ' ' + + ' ' + + ' ' + + '
      ' + + '
      ' + + '
      ' + + ' ' + + ' ' + + '
      '; // Auto-fill name and label when data key is selected document.getElementById('prop_field_key').addEventListener('change', function () { @@ -521,9 +601,18 @@ document.addEventListener('DOMContentLoaded', function () { } }); + var alignBtns = panel.querySelectorAll('[data-align]'); + alignBtns.forEach(function (btn) { + btn.addEventListener('click', function () { + alignBtns.forEach(function (b) { b.classList.remove('active'); }); + btn.classList.add('active'); + }); + }); + document.getElementById('btn_save_props').addEventListener('click', function () { var keySelect = document.getElementById('prop_field_key'); var selectedKey = keySelect ? keySelect.value : ''; + var activeAlign = panel.querySelector('[data-align].active'); var vals = { name: val('prop_name'), label: val('prop_label'), @@ -533,6 +622,7 @@ document.addEventListener('DOMContentLoaded', function () { page: parseInt(val('prop_page')) || 1, width: parseFloat(val('prop_width')) || 0.15, height: parseFloat(val('prop_height')) || 0.015, + text_align: activeAlign ? activeAlign.dataset.align : 'left', }; Object.assign(field, vals); saveField(fieldId, vals); diff --git a/fusion_authorizer_portal/utils/pdf_filler.py b/fusion_authorizer_portal/utils/pdf_filler.py index b737e2e..feaca15 100644 --- a/fusion_authorizer_portal/utils/pdf_filler.py +++ b/fusion_authorizer_portal/utils/pdf_filler.py @@ -109,13 +109,25 @@ class PDFTemplateFiller: if field_type in ('text', 'date'): c.setFont(font_name, font_size) - c.drawString(abs_x, abs_y, str(value)) + text_val = str(value) + field_h = field.get('height', 0.018) * page_h + text_y = abs_y - field_h + (field_h - font_size) / 2 + align = field.get('text_align', 'left') + if align == 'center': + center_x = abs_x + (field.get('width', 0.15) * page_w) / 2 + c.drawCentredString(center_x, text_y, text_val) + elif align == 'right': + right_x = abs_x + field.get('width', 0.15) * page_w + c.drawRightString(right_x, text_y, text_val) + else: + c.drawString(abs_x, text_y, text_val) elif field_type == 'checkbox': - if value: # Only draw if truthy - # Checkmark using ZapfDingbats (same as sign module) + if value: c.setFont('ZapfDingbats', font_size) - c.drawString(abs_x, abs_y, '4') # checkmark character + cb_h = field.get('height', 0.018) * page_h + cb_y = abs_y - cb_h + (cb_h - font_size) / 2 + c.drawString(abs_x, cb_y, '4') elif field_type == 'signature': sig_data = signatures.get(field_key) diff --git a/fusion_authorizer_portal/views/portal_assessment_express.xml b/fusion_authorizer_portal/views/portal_assessment_express.xml index 078f35a..d2a625d 100644 --- a/fusion_authorizer_portal/views/portal_assessment_express.xml +++ b/fusion_authorizer_portal/views/portal_assessment_express.xml @@ -1310,48 +1310,42 @@ handleReasonChange(); } + function disableFormInputs(form) { + if (!form) return; + form.style.display = 'none'; + form.querySelectorAll('input, select, textarea').forEach(function(el) { + el.disabled = true; + if (el.hasAttribute('required')) { + el.removeAttribute('required'); + el.dataset.wasRequired = 'true'; + } + }); + } + + function enableFormInputs(form) { + if (!form) return; + form.style.display = 'block'; + form.querySelectorAll('input, select, textarea').forEach(function(el) { + el.disabled = false; + if (el.dataset.wasRequired === 'true') { + el.setAttribute('required', 'required'); + } + }); + } + function showEquipmentForm() { var value = equipmentSelect ? equipmentSelect.value : ''; - // Hide all forms and disable required on hidden fields - if (rollatorForm) { - rollatorForm.style.display = 'none'; - rollatorForm.querySelectorAll('[required]').forEach(function(el) { - el.removeAttribute('required'); - el.dataset.wasRequired = 'true'; - }); - } - if (wheelchairForm) { - wheelchairForm.style.display = 'none'; - wheelchairForm.querySelectorAll('[required]').forEach(function(el) { - el.removeAttribute('required'); - el.dataset.wasRequired = 'true'; - }); - } - if (powerchairForm) { - powerchairForm.style.display = 'none'; - powerchairForm.querySelectorAll('[required]').forEach(function(el) { - el.removeAttribute('required'); - el.dataset.wasRequired = 'true'; - }); - } + disableFormInputs(rollatorForm); + disableFormInputs(wheelchairForm); + disableFormInputs(powerchairForm); - // Show selected form and restore required - if (value === 'rollator' && rollatorForm) { - rollatorForm.style.display = 'block'; - rollatorForm.querySelectorAll('[data-was-required]').forEach(function(el) { - el.setAttribute('required', 'required'); - }); - } else if (value === 'wheelchair' && wheelchairForm) { - wheelchairForm.style.display = 'block'; - wheelchairForm.querySelectorAll('[data-was-required]').forEach(function(el) { - el.setAttribute('required', 'required'); - }); - } else if (value === 'powerchair' && powerchairForm) { - powerchairForm.style.display = 'block'; - powerchairForm.querySelectorAll('[data-was-required]').forEach(function(el) { - el.setAttribute('required', 'required'); - }); + if (value === 'rollator') { + enableFormInputs(rollatorForm); + } else if (value === 'wheelchair') { + enableFormInputs(wheelchairForm); + } else if (value === 'powerchair') { + enableFormInputs(powerchairForm); } } diff --git a/fusion_authorizer_portal/views/portal_pdf_editor.xml b/fusion_authorizer_portal/views/portal_pdf_editor.xml index 2920cc6..4988196 100644 --- a/fusion_authorizer_portal/views/portal_pdf_editor.xml +++ b/fusion_authorizer_portal/views/portal_pdf_editor.xml @@ -12,7 +12,8 @@
      + t-att-data-current-page="1" + t-att-data-category="template.category or 'other'">
      @@ -96,7 +97,7 @@
      - +
      @@ -106,36 +107,8 @@
      -
      -
      Client:
      - client_last_name - client_first_name - client_middle_name - client_health_card - client_health_card_version - client_street - client_unit - client_city - client_state - client_postal_code - client_phone - client_email - client_weight -
      Consent:
      - consent_applicant - consent_agent - consent_date - agent_rel_spouse - agent_rel_parent - agent_rel_child - agent_rel_poa - agent_rel_guardian - agent_last_name - agent_first_name - agent_middle_initial -
      Signatures:
      - signature_page_11 - signature_page_12 +
      diff --git a/fusion_claims/__manifest__.py b/fusion_claims/__manifest__.py index 497f81f..a690e49 100644 --- a/fusion_claims/__manifest__.py +++ b/fusion_claims/__manifest__.py @@ -5,7 +5,7 @@ { 'name': 'Fusion Claims', - 'version': '19.0.5.0.0', + 'version': '19.0.5.1.0', 'category': 'Sales', 'summary': 'Complete ADP Claims Management with Dashboard, Sales Integration, Billing Automation, and Two-Stage Verification.', 'description': """ @@ -77,13 +77,17 @@ 'sale', 'sale_management', 'sale_margin', + 'purchase', 'account', 'sales_team', 'stock', 'calendar', 'ai', - 'fusion_faxes', + 'fusion_ringcentral', ], + 'external_dependencies': { + 'python': ['pdf2image', 'PIL'], + }, 'data': [ 'security/security.xml', 'security/ir.model.access.csv', @@ -132,6 +136,7 @@ 'views/submission_history_views.xml', 'views/fusion_loaner_views.xml', 'views/technician_task_views.xml', + 'views/task_sync_views.xml', 'views/technician_location_views.xml', 'report/report_actions.xml', 'report/report_templates.xml', diff --git a/fusion_claims/data/ir_config_parameter_data.xml b/fusion_claims/data/ir_config_parameter_data.xml index 0ce0242..3229971 100644 --- a/fusion_claims/data/ir_config_parameter_data.xml +++ b/fusion_claims/data/ir_config_parameter_data.xml @@ -147,5 +147,11 @@ 1-888-222-5099 + + + fusion_claims.sync_instance_id + + + diff --git a/fusion_claims/data/ir_cron_data.xml b/fusion_claims/data/ir_cron_data.xml index c384d17..8beb2ef 100644 --- a/fusion_claims/data/ir_cron_data.xml +++ b/fusion_claims/data/ir_cron_data.xml @@ -156,5 +156,28 @@ minutes True + + + + Fusion Claims: Sync Remote Tasks (Pull) + + code + model._cron_pull_remote_tasks() + 5 + minutes + True + + + + + Fusion Claims: Cleanup Old Shadow Tasks + + code + model._cron_cleanup_old_shadows() + 1 + days + True + + diff --git a/fusion_claims/data/mail_template_data.xml b/fusion_claims/data/mail_template_data.xml index 2e75b38..572b87d 100644 --- a/fusion_claims/data/mail_template_data.xml +++ b/fusion_claims/data/mail_template_data.xml @@ -49,19 +49,9 @@

      Please review the attached quotation. If you have any questions or need assistance, do not hesitate to contact us.

      -

      - Best regards,
      -
      - -

      -
      -
      -

      - - · - ·
      - This is an automated notification from the ADP Claims Management System. -

      + +
      --
      +
      @@ -109,19 +99,9 @@

      Your order is being processed. We will keep you updated on the delivery status and any updates from the Assistive Devices Program.

      -

      - Best regards,
      -
      - -

      - -
      -

      - - · - ·
      - This is an automated notification from the ADP Claims Management System. -

      + +
      --
      +
      @@ -178,19 +158,10 @@

      Please review the attached invoice and process payment at your earliest convenience. Contact us if you have any questions.

      -

      - Best regards,
      -
      - -

      - -
      -

      - - · - ·
      - This is an automated notification from the ADP Claims Management System. -

      + + +
      --
      +
      diff --git a/fusion_claims/data/pdf_template_data.xml b/fusion_claims/data/pdf_template_data.xml index d1023ab..48f8e2b 100644 --- a/fusion_claims/data/pdf_template_data.xml +++ b/fusion_claims/data/pdf_template_data.xml @@ -1,18 +1,7 @@ - - - SA Mobility Standard - Default signature positions for SA Mobility approval forms from ODSP. - 2 - 105 - 97 - 430 - 97 - 72 - 72 - 190 - 25 - - + diff --git a/fusion_claims/fusion_claims/LICENSE b/fusion_claims/fusion_claims/LICENSE deleted file mode 100644 index 62c8c76..0000000 --- a/fusion_claims/fusion_claims/LICENSE +++ /dev/null @@ -1,30 +0,0 @@ -Odoo Proprietary License v1.0 - -This software and associated files (the "Software") may only be used (executed, -modified, executed after modifications) if you have purchased a valid license -from the authors, typically via Odoo Apps, or if you have received a written -agreement from the authors of the Software. - -You may develop Odoo modules that use the Software as a library (typically -by depending on it, importing it and using its resources), but without copying -any source code or material from the Software. You may distribute those -modules under the license of your choice, provided that this license is -compatible with the terms of the Odoo Proprietary License (For example: -LGPL, MIT, or proprietary licenses similar to this one). - -It is forbidden to publish, distribute, sublicense, or sell copies of the Software -or modified copies of the Software. - -The above copyright notice and this permission notice must be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -Copyright 2024-2025 Nexa Systems Inc. - diff --git a/fusion_claims/fusion_claims/README.md b/fusion_claims/fusion_claims/README.md deleted file mode 100644 index 1241105..0000000 --- a/fusion_claims/fusion_claims/README.md +++ /dev/null @@ -1,199 +0,0 @@ -# Fusion Central - -**Complete ADP Billing Solution for Odoo 19** - -Part of the Fusion Claim Assistant product family by Nexa Systems Inc. - -## Overview - -Fusion Central is a comprehensive solution for managing ADP (Assistive Devices Program) billing in Odoo. It provides automatic calculation of ADP and client portions, professional PDF reports, and seamless integration with your existing workflow. - -## Features - -### Automatic Portion Calculations -- **Per-line calculations** on sale orders and invoices -- **Client type based rules:** - - REG: 75% ADP / 25% Client - - ODS, OWP, ACS, LTC, SEN, CCA: 100% ADP / 0% Client -- Automatic recalculation on quantity or price changes -- Totals displayed on document headers - -### Professional PDF Reports -- **Portrait and Landscape** orientations available -- Quotation, Sale Order, and Invoice reports -- Uses Odoo's default company header/footer via `web.external_layout` -- Includes: - - Company logo and address (from company settings) - - Billing and delivery address boxes with borders - - ADP device codes from products (`x_adp_code`) - - Per-line ADP and client portions with color coding - - Serial number column - - Authorizer and sales rep information - - Payment terms - - Signature section (if signed) - -### Report Templates - -| Report | Template ID | Model | Description | -|--------|-------------|-------|-------------| -| Quotation/Order (Portrait) | `fusion_claims.report_saleorder_portrait` | sale.order | Standard portrait layout | -| Quotation/Order (Landscape - ADP) | `fusion_claims.report_saleorder_landscape` | sale.order | Landscape with full ADP columns | -| Invoice (Portrait) | `fusion_claims.report_invoice_portrait` | account.move | Standard portrait layout | -| Invoice (Landscape) | `fusion_claims.report_invoice_landscape` | account.move | Landscape with full ADP columns | - -### Report Styling - -All reports follow a consistent style: -- **Font**: Arial, 10-12pt depending on section -- **Headers**: Blue background (#0066a1) with white text -- **ADP Portion Column**: Blue header (#1976d2), light blue rows (#e3f2fd) -- **Client Portion Column**: Orange header (#e65100), light orange rows (#fff3e0) -- **Bordered Tables**: All tables have 1px solid black borders -- **Totals**: Right-aligned with proper borders - -### Configurable Settings -- Field mappings for existing Odoo Studio fields -- One-click field creation for new installations -- HTML editors for payment terms and refund policy -- Store address configuration -- Field mapping configuration - -### ADP Claim Export -- Export invoices to comma-separated TXT format -- Compatible with ADP submission systems -- Automatic file naming with submission numbers -- Optional Documents app integration - -## Installation - -1. Copy the `fusion_claims` folder to your Odoo addons directory -2. Update the apps list in Odoo -3. Install "Fusion Central" from the Apps menu - -## Configuration - -### Quick Setup (Settings → Sales → Fusion Central) - -1. **Create Fields:** - - Click "Create Sale Order Fields" - - Click "Create Invoice Fields" - - Click "Create Product Fields" - -2. **Or Detect Existing Fields:** - - Click "Detect Existing Fields" if you have existing custom fields - -3. **Configure Company Info:** - - Store Address Line 1 & 2 - - Company Tagline - - E-Transfer Email - - Cheque Payable To - -4. **Add Payment Terms:** - - Use the HTML editor to format your payment terms - -5. **Add Refund Policy:** - - Enable "Include Refund Policy Page" - - Paste your refund policy HTML - -### Field Mappings - -The module uses the following fields: - -#### Sale Order Fields -| Field | Technical Name | Description | -|-------|---------------|-------------| -| Sale Type | x_fc_sale_type | ADP, ADP/ODSP, REG, etc. | -| Client Type | x_fc_client_type | REG, ODS, OWP, ACS, LTC, SEN, CCA | -| Authorizer | x_fc_authorizer_id | Many2one to res.partner | -| Claim Number | x_fc_claim_number | ADP claim reference | -| Delivery Date | x_fc_adp_delivery_date | Device delivery date | -| Client Ref 1 | x_fc_client_ref_1 | Client reference 1 | -| Client Ref 2 | x_fc_client_ref_2 | Client reference 2 | -| Service Start | x_fc_service_start_date | Service start date | -| Service End | x_fc_service_end_date | Service end date | - -#### Sale Order Line Fields -| Field | Technical Name | Description | -|-------|---------------|-------------| -| Serial Number | x_fc_serial_number | Device serial number | -| ADP Portion | x_fc_adp_portion | Calculated ADP amount | -| Client Portion | x_fc_client_portion | Calculated client amount | -| Device Placement | x_fc_device_placement | L/R/N/A placement | - -#### Invoice Fields -| Field | Technical Name | Description | -|-------|---------------|-------------| -| Invoice Type | x_fc_invoice_type | ADP, ADP Client Portion, ODSP, WSIB, etc. | -| Claim Number | x_fc_claim_number | ADP claim reference | -| Authorizer | x_fc_authorizer_id | Many2one to res.partner | -| Delivery Date | x_fc_adp_delivery_date | Device delivery date | - -#### Product Fields -| Field | Technical Name | Description | -|-------|---------------|-------------| -| ADP Code | x_adp_code | ADP device code for billing | - -## Usage - -### Sale Orders -1. Create a sale order -2. Set Sale Type to "ADP" or "ADP/ODSP" -3. Set Client Type (REG, ODS, etc.) -4. Add products - ADP and Client portions calculate automatically -5. Print using Portrait or Landscape report - -### Invoices -1. Create invoice (or generate from sale order) -2. Set Invoice Type to "ADP" or "ADP/ODSP" -3. Portions display automatically -4. Use "Export ADP" button to generate claim file -5. Print using Portrait or Landscape report - -## Odoo 19 Compatibility Notes - -This module has been updated for Odoo 19 with the following changes: - -1. **QWeb Templates**: - - Removed `hasattr` calls (not supported in Odoo 19 QWeb) - - Changed `product_uom` to `product_uom_id` - - Changed `tax_id` to `tax_ids` - - Use `t-else=""` instead of checking for `display_type == False` - -2. **Report Templates**: - - Use only `web.external_layout` for headers/footers - - Removed duplicate header/footer template calls - - Added explicit CSS borders (Bootstrap border classes don't render in PDF) - -3. **Field Names**: - - All fields use the `x_fc_*` naming convention - -## Requirements - -- Odoo 19.0 -- Dependencies: base, sale, sale_management, account - -## Changelog - -### Version 19.0.1.0.0 (December 2025) -- Updated for Odoo 19 compatibility -- Rewrote all report templates with consistent styling -- Fixed QWeb template issues (hasattr, field names) -- Added explicit CSS borders for PDF rendering -- Improved authorizer field display (Many2one handling) -- Removed duplicate header/footer calls -- Standardized all field mappings to x_fc_* fields - -### Version 18.0.1.0.0 -- Initial release for Odoo 18 - -## Support - -**Developer:** Nexa Systems Inc. -**Website:** https://www.nexasystems.ca -**Email:** support@nexasystems.ca - -## License - -Odoo Proprietary License v1.0 (OPL-1) - -Copyright © 2024-2025 Nexa Systems Inc. All rights reserved. diff --git a/fusion_claims/fusion_claims/__init__.py b/fusion_claims/fusion_claims/__init__.py deleted file mode 100644 index 5795da1..0000000 --- a/fusion_claims/fusion_claims/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2025 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) -# Part of the Fusion Claim Assistant product family. - -from . import models -from . import wizard - - -def _load_adp_device_codes(env): - """ - Post-init hook to load ADP Mobility Manual device codes. - Called on module install AND upgrade. - """ - env['fusion.adp.device.code']._load_packaged_device_codes() diff --git a/fusion_claims/fusion_claims/__manifest__.py b/fusion_claims/fusion_claims/__manifest__.py deleted file mode 100644 index db402cf..0000000 --- a/fusion_claims/fusion_claims/__manifest__.py +++ /dev/null @@ -1,180 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2025 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) -# Part of the Fusion Claim Assistant product family. - -{ - 'name': 'Fusion Claims', - 'version': '19.0.5.0.0', - 'category': 'Sales', - 'summary': 'Complete ADP Claims Management with Dashboard, Sales Integration, Billing Automation, and Two-Stage Verification.', - 'description': """ - Fusion Claims - ============= - - Part of the Fusion Claim Assistant product family by Nexa Systems Inc. - - Fusion Claims is a comprehensive standalone application for managing ADP (Assistive Devices Program) - claims in Odoo. It provides its own sales management views, dashboard, claim workflow management, - automatic calculation of ADP and client portions, and professional PDF reports. - - Key Features: - ------------- - • Standalone application with its own menu and views - • Dashboard for claims overview and KPIs - • Integrated sales management (custom views separate from standard Sales app) - • Complete ADP claim workflow (Quotation → Ready for Submission → Application Submitted → - Application Approved → Ready to Bill → Billed to ADP → Case Closed) - • Automatic ADP/Client portion calculations with deductions (PCT/AMT) - • Support for multiple client types (REG=75%/25%, ODS/OWP/ACS=100%/0%) - • Split invoicing (Client Invoice + ADP Invoice) - • ADP Device Codes reference from Mobility Manual (JSON/CSV import) - • Device Approval Verification wizard - confirm which devices were approved by ADP - • Approval status tracking on order lines and invoices with visual indicators - • Professional PDF reports in Portrait and Landscape orientations - • ADP claim export to TXT format for billing - • Kanban board for ADP claim status tracking - • Field mapping for existing Odoo Studio fields - • Data persistence - fields survive module uninstall - - Sales Management: - ----------------- - • Custom quotation and order views with ADP fields - • ADP portion and client portion columns - • Serial number tracking per line item - • Device placement (Left/Right/N/A) - • Client type selection and automatic calculations - - Claim Fields: - ------------- - • Claim Number, Client Reference 1 & 2 - • ADP Delivery Date, Service Start/End Dates - • Authorizer tracking - • Deduction Type (Percentage or Amount) - - Report Features: - ---------------- - • Company logo and multi-store addresses - • Billing and delivery address boxes - • Authorizer and sales rep information - • Per-line ADP portion, client portion, taxes, and totals - • ADP device codes from products - • Serial numbers section - • Customizable payment terms - • Optional refund policy page - - Copyright © 2024-2025 Nexa Systems Inc. All rights reserved. - """, - 'author': 'Nexa Systems Inc.', - 'website': 'https://www.nexasystems.ca', - 'maintainer': 'Nexa Systems Inc.', - 'support': 'support@nexasystems.ca', - 'license': 'OPL-1', - 'price': 0.00, - 'currency': 'CAD', - 'depends': [ - 'base', - 'sale', - 'sale_management', - 'sale_margin', - 'account', - 'sales_team', - 'stock', - 'calendar', - 'ai', - 'fusion_ringcentral', - ], - 'external_dependencies': { - 'python': ['pdf2image', 'PIL'], - }, - 'data': [ - 'security/security.xml', - 'security/ir.model.access.csv', - 'data/ir_config_parameter_data.xml', - 'data/pdf_template_data.xml', - 'data/mail_activity_type_data.xml', - 'data/ir_cron_data.xml', - 'data/ir_actions_server_data.xml', - 'data/stock_location_data.xml', - 'data/product_labor_data.xml', - 'wizard/status_change_reason_wizard_views.xml', - 'views/res_company_views.xml', - 'views/res_config_settings_views.xml', - 'views/sale_order_views.xml', - 'views/account_move_views.xml', - 'views/account_journal_views.xml', - 'wizard/adp_export_wizard_views.xml', - 'wizard/device_import_wizard_views.xml', - 'wizard/device_approval_wizard_views.xml', - 'wizard/submission_verification_wizard_views.xml', - - 'wizard/account_payment_register_views.xml', - 'wizard/case_close_verification_wizard_views.xml', - 'wizard/schedule_assessment_wizard_views.xml', - 'wizard/assessment_completed_wizard_views.xml', - 'wizard/application_received_wizard_views.xml', - 'wizard/ready_for_submission_wizard_views.xml', - 'wizard/ready_to_bill_wizard_views.xml', - 'wizard/field_mapping_config_wizard_views.xml', - 'wizard/ready_for_delivery_wizard_views.xml', - 'wizard/send_to_mod_wizard_views.xml', - 'wizard/mod_awaiting_funding_wizard_views.xml', - 'wizard/mod_funding_approved_wizard_views.xml', - 'wizard/mod_pca_received_wizard_views.xml', - 'wizard/odsp_sa_mobility_wizard_views.xml', - 'wizard/odsp_discretionary_wizard_views.xml', - 'wizard/odsp_submit_to_odsp_wizard_views.xml', - 'wizard/odsp_pre_approved_wizard_views.xml', - 'wizard/odsp_ready_delivery_wizard_views.xml', - 'views/res_partner_views.xml', - 'views/pdf_template_inherit_views.xml', - 'views/dashboard_views.xml', - 'views/client_profile_views.xml', - 'wizard/xml_import_wizard_views.xml', - 'views/adp_claims_views.xml', - 'views/submission_history_views.xml', - 'views/fusion_loaner_views.xml', - 'views/technician_task_views.xml', - 'views/task_sync_views.xml', - 'views/technician_location_views.xml', - 'report/report_actions.xml', - 'report/report_templates.xml', - 'report/sale_report_portrait.xml', - 'report/sale_report_landscape.xml', - 'report/invoice_report_portrait.xml', - 'report/invoice_report_landscape.xml', - 'report/report_proof_of_delivery.xml', - 'report/report_proof_of_delivery_standard.xml', - 'report/report_proof_of_pickup.xml', - 'report/report_rental_agreement.xml', - 'report/report_grab_bar_waiver.xml', - 'report/report_accessibility_contract.xml', - 'report/report_mod_quotation.xml', - 'report/report_mod_invoice.xml', - 'data/mail_template_data.xml', - 'data/ai_agent_data.xml', - ], - 'assets': { - 'web.assets_backend': [ - 'fusion_claims/static/src/scss/fusion_claims.scss', - 'fusion_claims/static/src/css/fusion_task_map_view.scss', - 'fusion_claims/static/src/js/chatter_resize.js', - 'fusion_claims/static/src/js/document_preview.js', - 'fusion_claims/static/src/js/preview_button_widget.js', - 'fusion_claims/static/src/js/status_selection_filter.js', - 'fusion_claims/static/src/js/gallery_preview.js', - 'fusion_claims/static/src/js/tax_totals_patch.js', - 'fusion_claims/static/src/js/google_address_autocomplete.js', - 'fusion_claims/static/src/js/calendar_store_hours.js', - 'fusion_claims/static/src/js/fusion_task_map_view.js', - 'fusion_claims/static/src/js/attachment_image_compress.js', - 'fusion_claims/static/src/xml/document_preview.xml', - 'fusion_claims/static/src/xml/fusion_task_map_view.xml', - ], - }, - 'images': ['static/description/icon.png'], - 'installable': True, - 'auto_install': False, - 'application': True, - 'post_init_hook': '_load_adp_device_codes', -} diff --git a/fusion_claims/fusion_claims/data/ai_agent_data.xml b/fusion_claims/fusion_claims/data/ai_agent_data.xml deleted file mode 100644 index 3a09574..0000000 --- a/fusion_claims/fusion_claims/data/ai_agent_data.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - Fusion: Search Client Profiles - code - - - -ai['result'] = record._fc_tool_search_clients(search_term, city_filter, condition_filter) - - Search for client profiles in Fusion Claims. Can search by name, health card number, city, or medical condition. Returns matching profiles with basic info and financial summaries. - {"type": "object", "properties": {"search_term": {"type": "string", "description": "Search term to match against name, health card number, or city"}, "city_filter": {"type": "string", "description": "Filter by city name"}, "condition_filter": {"type": "string", "description": "Filter by medical condition (e.g., CVA, diabetes)"}}, "required": []} - - - - - Fusion: Get Client Details - code - - - -ai['result'] = record._fc_tool_client_details(profile_id) - - Get detailed information about a specific client profile including personal info, medical status, benefits, claims history, and ADP application history. Requires profile_id from a previous search. - {"type": "object", "properties": {"profile_id": {"type": "number", "description": "ID of the client profile to get details for"}}, "required": ["profile_id"]} - - - - - Fusion: Get Claims Statistics - code - - - -ai['result'] = record._fc_tool_claims_stats() - - Get aggregated statistics about Fusion Claims data: total profiles, total orders, breakdown by sale type, breakdown by workflow status, and top cities by client count. No parameters needed. - {"type": "object", "properties": {}, "required": []} - - - - - - - Fusion Claims Client Intelligence - Query client profiles, ADP claims, funding history, medical conditions, and device information. - You help users find information about ADP clients, claims, medical conditions, devices, and funding history. Use the Fusion search/details/stats tools to query data. - - - - - - - - Fusion Claims Intelligence - Ask about clients, ADP claims, funding history, medical conditions, and devices. - gpt-4.1 - analytical - - You are Fusion Claims Intelligence, an AI assistant for ADP claims management. - -You help staff find information about clients, medical conditions, mobility devices, funding history, and claim status. - -Capabilities: -1. Search client profiles by name, health card number, city, or medical condition -2. Get detailed client information including claims history and ADP applications -3. Provide aggregated statistics about claims, funding types, and demographics - -Response guidelines: -- Be concise and data-driven -- Format monetary values with $ and commas -- Include key identifiers (name, health card, city) when listing clients -- Include order number, status, and amounts when discussing claims -- If asked about a specific client, search first, then get details -- Always provide the profile ID for record lookup - -Key terminology: -- ADP = Assistive Devices Program (Ontario government) -- Client Type REG = Regular (75% ADP / 25% Client), ODS/OWP/ACS = 100% ADP -- Sale Types: ADP, ODSP, WSIB, Insurance, March of Dimes, Muscular Dystrophy, Hardship Funding -- Sections: 2a = Walkers, 2b = Manual Wheelchairs, 2c = Power Bases/Scooters, 2d = Seating - - - diff --git a/fusion_claims/fusion_claims/data/device_codes/adp_mobility_manual.json b/fusion_claims/fusion_claims/data/device_codes/adp_mobility_manual.json deleted file mode 100644 index be7ff25..0000000 --- a/fusion_claims/fusion_claims/data/device_codes/adp_mobility_manual.json +++ /dev/null @@ -1,17057 +0,0 @@ -[ - { - "Device Type": "AA - Custom Modifications", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "AA - Custom Modifications - The MOCM code may be used when custom modifications are required to an ADP listed ambulation aid or paediatric stander, and there is no ADP code with assigned funding available. The following documentation must be submitted: 1. Authorizer must provide clinical rationale to support the request. 2. Vendor must provide a breakdown of the cost of labour (not to exceed $40.00/hour), and parts", - "Device Code": "MOCM", - "Quantity": 1, - "ADP Price": 40.0, - "SN Required": "No" - }, - { - "Device Type": "Adult High Performance Rigid Manual Wheelchair", - "Manufacturer": "TiLite", - "Device Description": "TiLite Z", - "Device Code": "WM0002175", - "Quantity": 1, - "ADP Price": 3098.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Ki Mobility", - "Device Description": "Rogue-2", - "Device Code": "WM0001043", - "Quantity": 1, - "ADP Price": 3098.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Ki Mobility", - "Device Description": "Ethos Adult High Performance Rigid Manual Wheelchair", - "Device Code": "WM0001809", - "Quantity": 1, - "ADP Price": 3098.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Ki Mobility", - "Device Description": "Rogue ALX", - "Device Code": "WMA4KI015", - "Quantity": 1, - "ADP Price": 3098.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "LEVO AG", - "Device Description": "LEVO compact-easy LCEV with battery powered stand-up feature", - "Device Code": "WM0000471", - "Quantity": 1, - "ADP Price": 3098.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Motion Composites", - "Device Description": "Apex", - "Device Code": "WM0001305", - "Quantity": 1, - "ADP Price": 3098.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie QRi", - "Device Code": "WM0000991", - "Quantity": 1, - "ADP Price": 3098.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie Gp/Gpv", - "Device Code": "WMA4QU005", - "Quantity": 1, - "ADP Price": 3098.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie Gt", - "Device Code": "WMA4QU030", - "Quantity": 1, - "ADP Price": 3098.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie Q7, Q7R, Q7RS", - "Device Code": "WMA4QU040", - "Quantity": 1, - "ADP Price": 3098.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Rgk Wheelchairs", - "Device Description": "Maxima", - "Device Code": "WM0000696", - "Quantity": 1, - "ADP Price": 3098.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Rgk Wheelchairs", - "Device Description": "Hi-Lite", - "Device Code": "WMA4RZ005", - "Quantity": 1, - "ADP Price": 3098.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Sunrise Medical", - "Device Description": "Quickie 5R", - "Device Code": "WM0001272", - "Quantity": 1, - "ADP Price": 3098.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Sunrise Medical", - "Device Description": "Quickie Nitrum - Adult High Perf Rigid", - "Device Code": "WM0001837", - "Quantity": 1, - "ADP Price": 3098.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "TiLite", - "Device Description": "Tilite Aero T", - "Device Code": "WM0001252", - "Quantity": 1, - "ADP Price": 3098.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "TiLite", - "Device Description": "Tilite Yr/Tr,Yra/Tra,Trc,Zra/Zr", - "Device Code": "WMA4TZ005", - "Quantity": 1, - "ADP Price": 3098.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "TiLite", - "Device Description": "Tilite Aero Z", - "Device Code": "WMA4TZ010", - "Quantity": 1, - "ADP Price": 3098.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Manual Wheelchair", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "Maverick", - "Device Code": "WM0002144", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Manual Wheelchair", - "Manufacturer": "Sunrise Medical", - "Device Description": "Quickie QS5 X", - "Device Code": "WM0002190", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Manual Wheelchair", - "Manufacturer": "TiLite", - "Device Description": "TiLite X", - "Device Code": "WM0002174", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Future Mobility", - "Device Description": "Northern Lite", - "Device Code": "WMA3FM005", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Future Mobility", - "Device Description": "Galaxy Lite", - "Device Code": "WMA3FM010", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Ki Mobility", - "Device Description": "Catalyst 5, 5ti", - "Device Code": "WMA3KI010", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Ki Mobility", - "Device Description": "Catalyst 5vx", - "Device Code": "WMA3KI015", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "EZ Ride", - "Device Code": "WMA3WM005", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Motion Composites", - "Device Description": "Helio C2", - "Device Code": "WM0000964", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Motion Composites", - "Device Description": "Helio A7", - "Device Code": "WM0001020", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Motion Composites", - "Device Description": "Helio XC2", - "Device Code": "WM0001260", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Motion Composites", - "Device Description": "Helio A6", - "Device Code": "WM0001489", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Physipro", - "Device Description": "XL-5/XL-5 ci", - "Device Code": "WM0001132", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Glyder", - "Device Code": "WM0001061", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Product Design Group", - "Device Description": "Eclipse 600", - "Device Code": "WMA3MV005", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie QXi", - "Device Code": "WM0000562", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie Xenon", - "Device Code": "WM0001156", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie 2 (VIP 2)", - "Device Code": "WMA3QU005", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie 2 Hp", - "Device Code": "WMA3QU010", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie 2 Lite", - "Device Code": "WMA3QU020", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie Gtx", - "Device Code": "WMA3QU040", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie Lxi", - "Device Code": "WMA3QU405", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie Revolution", - "Device Code": "WMA3QU410", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie M6", - "Device Code": "WMA3QU420", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Sunrise Medical", - "Device Description": "Xenon 2 Swing Away", - "Device Code": "WM0001592", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Sunrise Medical", - "Device Description": "Xenon 2 Hybrid", - "Device Code": "WM0001594", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "Sunrise Medical", - "Device Description": "Xenon 2 Fixed Front", - "Device Code": "WM0001595", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "TiLite", - "Device Description": "TiLite AERO X", - "Device Code": "WM0001169", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Performance Type 3 Wheelchair", - "Manufacturer": "TiLite", - "Device Description": "Tilite X, Sx, Tx", - "Device Code": "WMA3TZ005", - "Quantity": 1, - "ADP Price": 2290.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Drive Medical Design & Manufacturing", - "Device Description": "Viper Plus GT", - "Device Code": "WM0000317", - "Quantity": 1, - "ADP Price": 1449.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Future Mobility", - "Device Description": "Stellato II", - "Device Code": "WM0001188", - "Quantity": 1, - "ADP Price": 1449.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Future Mobility", - "Device Description": "Stellato", - "Device Code": "WMA2FM005", - "Quantity": 1, - "ADP Price": 1449.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Invacare", - "Device Description": "9000 Xt", - "Device Code": "WMA2IN025", - "Quantity": 1, - "ADP Price": 1449.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Invacare", - "Device Description": "9000 SL", - "Device Code": "WMA2IN030", - "Quantity": 1, - "ADP Price": 1449.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Invacare", - "Device Description": "9000 Topaz", - "Device Code": "WMA2IN055", - "Quantity": 1, - "ADP Price": 1449.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Ki Mobility", - "Device Description": "Catalyst 4E", - "Device Code": "WM0001928", - "Quantity": 1, - "ADP Price": 1449.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Ki Mobility", - "Device Description": "Catalyst 4, 4c", - "Device Code": "WMA2KI010", - "Quantity": 1, - "ADP Price": 1449.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "NRG+ Gold", - "Device Code": "WM0001134", - "Quantity": 1, - "ADP Price": 1449.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "NRG+", - "Device Code": "WMA2WM005", - "Quantity": 1, - "ADP Price": 1449.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "Swift", - "Device Code": "WMA2WM010", - "Quantity": 1, - "ADP Price": 1449.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Motion Composites", - "Device Description": "Move", - "Device Code": "WM0001196", - "Quantity": 1, - "ADP Price": 1449.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Magic Plus", - "Device Code": "WM0001062", - "Quantity": 1, - "ADP Price": 1449.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Voyager Plus", - "Device Code": "WM0001063", - "Quantity": 1, - "ADP Price": 1449.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Breezy RubiX2", - "Device Code": "WM0000567", - "Quantity": 1, - "ADP Price": 1449.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie Qx", - "Device Code": "WM0001310", - "Quantity": 1, - "ADP Price": 1449.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Breezy 600", - "Device Code": "WMA2QU001", - "Quantity": 1, - "ADP Price": 1449.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Breezy Ultra 4", - "Device Code": "WMA2QU010", - "Quantity": 1, - "ADP Price": 1449.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie Lx", - "Device Code": "WMA2QU105", - "Quantity": 1, - "ADP Price": 1449.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "Ams Itilt2", - "Device Code": "WMA5AO020", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Broda", - "Device Description": "Synthesis Tilt Recliner", - "Device Code": "WM0001668", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Broda", - "Device Description": "Models 48", - "Device Code": "WMA5B-005", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Broda", - "Device Description": "Models 85", - "Device Code": "WMA5B-010", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Broda", - "Device Description": "Elite 785", - "Device Code": "WMA5B-020", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Broda", - "Device Description": "Comfort Tilt 587V3", - "Device Code": "WMA5B-025", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Future Mobility", - "Device Description": "Capella (20), Capella 45", - "Device Code": "WM0000559", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Future Mobility", - "Device Description": "Orion III", - "Device Code": "WM0001195", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Future Mobility", - "Device Description": "Orion Ii", - "Device Code": "WMA5FM005", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Future Mobility", - "Device Description": "Orion 500", - "Device Code": "WMA5FM010", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Invacare", - "Device Description": "Solara 3g", - "Device Code": "WMA5IN040", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Ki Mobility", - "Device Description": "Focus CR", - "Device Code": "WM0001160", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Ki Mobility", - "Device Description": "Liberty FT", - "Device Code": "WM0001569", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Ki Mobility", - "Device Description": "Little Wave Arc Tilt Adult", - "Device Code": "WM0001902", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Ki Mobility", - "Device Description": "CR45", - "Device Code": "WM0001935", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Lpa Medical Inc", - "Device Description": "Optimum Posturo-Pedic", - "Device Code": "WMA5LQ005", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Lpa Medical Inc", - "Device Description": "Comp-Position", - "Device Code": "WMA5LQ010", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Lpa Medical Inc", - "Device Description": "Evolution", - "Device Code": "WMA5LQ015", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Lpa Medical Inc", - "Device Description": "Dyn-Ergo", - "Device Code": "WMA5LQ020", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "Lowrider", - "Device Code": "WM0001080", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "Supertilt Oval Frame (maximum tilt 45 deg)", - "Device Code": "WM0001111", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "Supertilt Square Frame (maximum tilt 35 deg)", - "Device Code": "WM0001166", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "MLTR 500/600", - "Device Code": "WMA5WM010", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "MLT 700 A/B", - "Device Code": "WMA5WM015", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Orthofab", - "Device Description": "Tango", - "Device Code": "WMA5OF005", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Physipro", - "Device Description": "Neox Tilt-in-Space and Neox HD", - "Device Code": "WM0001255", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Supertilt Plus", - "Device Code": "WM0001040", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Extreme", - "Device Code": "WM0001041", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Power Plus Mobility", - "Device Description": "NV Tilt", - "Device Code": "WM0001076", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Product Design Group", - "Device Description": "Stellar LEAP", - "Device Code": "WM0001532", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Product Design Group", - "Device Description": "Stellar Impact", - "Device Code": "WM0001603", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Product Design Group", - "Device Description": "Bentley LT-R", - "Device Code": "WM0001936", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Product Design Group", - "Device Description": "Bentley, Bentley LT", - "Device Code": "WMA5MV005", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Product Design Group", - "Device Description": "Fuze T50", - "Device Code": "WMA5MV020", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Product Design Group", - "Device Description": "Fuze T20", - "Device Code": "WMA5MV025", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Breezy Relax2", - "Device Code": "WM0000454", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie SR-45", - "Device Code": "WM0000474", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie Ts", - "Device Code": "WMA5QU005", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie Iris", - "Device Code": "WMA5QU015", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Tilt Fx", - "Device Code": "WMA5QU020", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Seating Matters Limited", - "Device Description": "Phoenix", - "Device Code": "WM0000974", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Seating Matters Limited", - "Device Description": "Sorrento", - "Device Code": "WM0000975", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Sunrise Medical", - "Device Description": "Ibis", - "Device Code": "WMA5M9005", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Manual Dynamic Tilt Wheelchair", - "Manufacturer": "Product Design Group", - "Device Description": "Stellar GL, Stellar GLT, Stellar HD", - "Device Code": "WMA5MV010", - "Quantity": 1, - "ADP Price": 2110.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 1", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Mp1", - "Device Code": "WPA1WN005", - "Quantity": 1, - "ADP Price": 4392.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 1", - "Manufacturer": "Pride Mobility Products", - "Device Description": "J6 Jazzy", - "Device Code": "WP0000564", - "Quantity": 1, - "ADP Price": 4392.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 1", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Jazzy EVO 613/613 Li", - "Device Code": "WP0001929", - "Quantity": 1, - "ADP Price": 4392.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 2", - "Manufacturer": "Motion Concepts", - "Device Description": "Rovi X3 5.0 mph", - "Device Code": "WP0001539", - "Quantity": 1, - "ADP Price": 5812.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 2", - "Manufacturer": "Permobil", - "Device Description": "M1", - "Device Code": "WP0001577", - "Quantity": 1, - "ADP Price": 5812.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 2", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Mp2", - "Device Code": "WPA2WN005", - "Quantity": 1, - "ADP Price": 5812.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 2", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Quantum Q4", - "Device Code": "WP0001541", - "Quantity": 1, - "ADP Price": 5812.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Amylior Inc.", - "Device Description": "Alltrack HD3", - "Device Code": "WP0001766", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Amylior Inc.", - "Device Description": "Alltrack M3", - "Device Code": "WP0001767", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Amylior Inc.", - "Device Description": "Alltrack M3 (HD)", - "Device Code": "WP0001768", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Amylior Inc.", - "Device Description": "Alltrack R3", - "Device Code": "WP0001769", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Amylior Inc.", - "Device Description": "Alltrack R3 (HD)", - "Device Code": "WP0001770", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Future Mobility", - "Device Description": "Orion Explorer Magellan", - "Device Code": "WPA3FM005", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Future Mobility", - "Device Description": "Orion Explorer Viking", - "Device Code": "WPA3FM010", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Invacare", - "Device Description": "TDXSP2", - "Device Code": "WP0001447", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Invacare", - "Device Description": "Invacare TDX SP2 HD Adult Power Base Type 3 Heavy Duty Wheel Chair", - "Device Code": "WP0001773", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Invacare", - "Device Description": "AVIVA STORM RX", - "Device Code": "WP0001890", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Invacare", - "Device Description": "AVIVA FX - Front Wheel Drive Power Wheelchair", - "Device Code": "WP0001899", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Motion Concepts", - "Device Description": "Rovi X3 5.0 (Modular Maxx), 5.8 or 6.2 mph, Rovi A3 R-Net Adult Power Base,5.8 or 6.2 mph", - "Device Code": "WP0001287", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Permobil", - "Device Description": "M300 Corpus HD R-Net", - "Device Code": "WP0001165", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Permobil", - "Device Description": "F5 / F5 VS Corpus (Adult)", - "Device Code": "WP0001256", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Permobil", - "Device Description": "F3 Corpus (Adult)", - "Device Code": "WP0001258", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Permobil", - "Device Description": "M3 Corpus", - "Device Code": "WP0001401", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Permobil", - "Device Description": "M5 Corpus", - "Device Code": "WP0001449", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Permobil", - "Device Description": "M Corpus VS", - "Device Code": "WP0002128", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Mp5", - "Device Code": "WPA3WM005", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Quantum 1450", - "Device Code": "WP0001021", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Q6 Edge HD", - "Device Code": "WP0001058", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Quantum Q6 Edge 2.0 (Adult)", - "Device Code": "WP0001254", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Quantum Q6 Edge Z (Adult)", - "Device Code": "WP0001269", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Quantum 4Front 2", - "Device Code": "WP0001441", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Quantum Edge 3", - "Device Code": "WP0001575", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Quantum Q6 Edge 3 Stretto", - "Device Code": "WP0001806", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Quantum 4Front 2 HD", - "Device Code": "WP0001900", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Quantum R-Trak (A)", - "Device Code": "WP0001987", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Quickie", - "Device Description": "Quickie 700 M, 710, 715, 720", - "Device Code": "WP0000686", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Quickie", - "Device Description": "Quickie 500 M", - "Device Code": "WP0001630", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Quickie", - "Device Description": "Quickie S-646 (S-626)", - "Device Code": "WPA3QU230", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Quickie", - "Device Description": "Quickie P-222", - "Device Code": "WPA3QU240", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Sunrise Medical", - "Device Description": "Quickie Q500H", - "Device Code": "WP0001815", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Power Base Type 3", - "Manufacturer": "Sunrise Medical", - "Device Description": "Quickie Q300M Mini with Sedeo Lite Seating", - "Device Code": "WP0001891", - "Quantity": 1, - "ADP Price": 6125.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Standard Manual Type 1 Wheelchair", - "Manufacturer": "Drive Medical", - "Device Description": "Airgo", - "Device Code": "WMA1GM005", - "Quantity": 1, - "ADP Price": 1228.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Standard Manual Type 1 Wheelchair", - "Manufacturer": "Everest & Jennings", - "Device Description": "Traveler", - "Device Code": "WMA1EJ005", - "Quantity": 1, - "ADP Price": 1228.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Standard Manual Type 1 Wheelchair", - "Manufacturer": "Invacare", - "Device Description": "Tracer", - "Device Code": "WMA1IN005", - "Quantity": 1, - "ADP Price": 1228.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Standard Manual Type 1 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Easy Care 2000 & 4000", - "Device Code": "WMA1QU015", - "Quantity": 1, - "ADP Price": 1228.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 1", - "Manufacturer": "Airway Surgical", - "Device Description": "5051 & 5052 / Single or Double Release Walker / Traction Grip Tips or Wheels", - "Device Code": "MW1AR0005", - "Quantity": 1, - "ADP Price": 64.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 1", - "Manufacturer": "Drive Medical", - "Device Description": "Deluxe Folding Travel Walker with 5\" Wheels", - "Device Code": "AA0000560", - "Quantity": 1, - "ADP Price": 64.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 1", - "Manufacturer": "Drive Medical", - "Device Description": "One Button Or Dual Trigger Release", - "Device Code": "MW1D50005", - "Quantity": 1, - "ADP Price": 64.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 1", - "Manufacturer": "Drive Medical", - "Device Description": "Deluxe Folding Wheeled Walker", - "Device Code": "MW1GM0010", - "Quantity": 1, - "ADP Price": 64.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 1", - "Manufacturer": "Guardian", - "Device Description": "Red Dot Standard G07755 & G07756", - "Device Code": "MW1GU0015", - "Quantity": 1, - "ADP Price": 64.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 1", - "Manufacturer": "Lumex", - "Device Description": "Lightweight Adult/Junior", - "Device Code": "MW1LU0010", - "Quantity": 1, - "ADP Price": 64.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 1", - "Manufacturer": "Lumex", - "Device Description": "Dual Release Adult/Junior", - "Device Code": "MW1LU0020", - "Quantity": 1, - "ADP Price": 64.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 2", - "Manufacturer": "Airway Surgical", - "Device Description": "5314RD & 5314BK / Rollator with Curved Backrest", - "Device Code": "MW2AR0010", - "Quantity": 1, - "ADP Price": 254.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 2", - "Manufacturer": "Drive Medical", - "Device Description": "Duet Rollator Chair, 8\" Casters", - "Device Code": "MW2D00010", - "Quantity": 1, - "ADP Price": 254.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 2", - "Manufacturer": "Drive Medical", - "Device Description": "Go-Lite Bariatric Steel Rollator", - "Device Code": "MW2D50005", - "Quantity": 1, - "ADP Price": 254.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 2", - "Manufacturer": "Evolution Medical", - "Device Description": "Xpresso Trillium Two", - "Device Code": "AA0001306", - "Quantity": 1, - "ADP Price": 254.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 2", - "Manufacturer": "Evolution Medical", - "Device Description": "Xpresso Companion Two", - "Device Code": "AA0001309", - "Quantity": 1, - "ADP Price": 254.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 2", - "Manufacturer": "Evolution Medical", - "Device Description": "Sprite & Sprite Mini", - "Device Code": "MW2EV0005", - "Quantity": 1, - "ADP Price": 254.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 2", - "Manufacturer": "Evolution Medical", - "Device Description": "Challenger Mini", - "Device Code": "MW2EV0010", - "Quantity": 1, - "ADP Price": 254.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 2", - "Manufacturer": "Evolution Medical", - "Device Description": "Sprite Grande", - "Device Code": "MW2EV0020", - "Quantity": 1, - "ADP Price": 254.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 2", - "Manufacturer": "Evolution Medical", - "Device Description": "Challenger Grande", - "Device Code": "MW2EV0025", - "Quantity": 1, - "ADP Price": 254.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 2", - "Manufacturer": "Human Care Canada Inc.", - "Device Description": "Nexus One Adult Type 2 Rollator", - "Device Code": "AA0001810", - "Quantity": 1, - "ADP Price": 254.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 2", - "Manufacturer": "Nighthawk", - "Device Description": "Ovation Compact 807-6", - "Device Code": "MW2NM1005", - "Quantity": 1, - "ADP Price": 254.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 2", - "Manufacturer": "Parsons Adl", - "Device Description": "4200 Dx", - "Device Code": "MW2DG0010", - "Quantity": 1, - "ADP Price": 254.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Airway Surgical", - "Device Description": "5305 / Lightweight Rollator", - "Device Code": "AA0000315", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Amylior Inc.", - "Device Description": "Stella Rollator (18, 20, 23 & HD)", - "Device Code": "AA0001580", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Drive Medical", - "Device Description": "AIRGO EXCURSION XWD", - "Device Code": "AA0000124", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Drive Medical", - "Device Description": "Airgo Fusion Rollator, F23, Tall", - "Device Code": "AA0000694", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Drive Medical", - "Device Description": "Nitro Aluminum Rollator, 10\" Casters", - "Device Code": "AA0001036", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Drive Medical", - "Device Description": "Nitro Aluminum Rollator, Hemi Height, 10\" Casters", - "Device Code": "AA0001193", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Drive Medical", - "Device Description": "Nitro Aluminum Rollator, Tall Height, 10\" Casters", - "Device Code": "AA0001194", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Drive Medical", - "Device Description": "Nitro HD Rollator", - "Device Code": "AA0001238", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Drive Medical", - "Device Description": "Airgo Vista V20", - "Device Code": "AA0001338", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Drive Medical", - "Device Description": "Nitro HD Hemi Height Rollator", - "Device Code": "AA0001475", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Drive Medical", - "Device Description": "Nitro Sprint Rollator", - "Device Code": "AA0001986", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Drive Medical", - "Device Description": "Airgo Navigator", - "Device Code": "MW3GM0015", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Drive Medical", - "Device Description": "Airgo Excursion, X20", - "Device Code": "MW3GM0065", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Evolution Medical", - "Device Description": "Xpresso Zero, Zero Mini & Zero Tall", - "Device Code": "AA0001282", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Evolution Medical", - "Device Description": "Xpresso Wide & Low Wide", - "Device Code": "AA0001283", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Evolution Medical", - "Device Description": "Xpresso Trillium", - "Device Code": "AA0001307", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Evolution Medical", - "Device Description": "Xpresso Companion", - "Device Code": "AA0001308", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Evolution Medical", - "Device Description": "Sierra Air Walker", - "Device Code": "AA0001836", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Evolution Medical", - "Device Description": "Evolution Dx, Ldx, Wdx, Lwdx", - "Device Code": "MW3EV0005", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Evolution Medical", - "Device Description": "Horizon Dx, Wdx, Lwdx, Tdx", - "Device Code": "MW3EV0010", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Evolution Medical", - "Device Description": "Piper Dx, Mdx, Smdx, Tdx", - "Device Code": "MW3EV0020", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Evolution Medical", - "Device Description": "Challenger Wide", - "Device Code": "MW3EV0030", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Evolution Medical", - "Device Description": "Challenger Low Wide", - "Device Code": "MW3EV0035", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Evolution Medical", - "Device Description": "Xpresso, Xpresso Lite", - "Device Code": "MW3EV0040", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "GF HEALTH PRODUCTS", - "Device Description": "HYBRID LX Rollator", - "Device Code": "AA0000453", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Human Care Canada Inc.", - "Device Description": "Ralon Crossover Standard Rollator", - "Device Code": "AA0001895", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Human Care Canada Inc.", - "Device Description": "Nexus Iii (Cable Free Braking System)", - "Device Code": "MW3DG0045", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Nighthawk", - "Device Description": "Ats 906 0vation", - "Device Code": "MW3NM0015", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Nighthawk", - "Device Description": "Ovation Compact 805-8", - "Device Code": "MW3NM1005", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Nighthawk", - "Device Description": "Ovation Compact 806-8", - "Device Code": "MW3NM1010", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Parsons Adl", - "Device Description": "4200swx", - "Device Code": "MW3DG0035", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Sunrise Medical", - "Device Description": "Gemino", - "Device Code": "AA0001082", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Sunrise Medical", - "Device Description": "Gemino 60", - "Device Code": "AA0001236", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Topro AS", - "Device Description": "Troja", - "Device Code": "MW3TV0010", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Topro AS", - "Device Description": "Olympos", - "Device Code": "MW3TV0020", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Triumph Mobility Inc", - "Device Description": "Escape", - "Device Code": "AA0001084", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Adult Wheeled Walker Type 3", - "Manufacturer": "Triumph Mobility Inc", - "Device Description": "Triumph EscapeHD", - "Device Code": "AA0002366", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "Yes" - }, - { - "Device Type": "Amputee Axle Plates (pair)", - "Manufacturer": "THOMASHILFEN", - "Device Description": "Amputee Axle Plates (pair)", - "Device Code": "WAMT", - "Quantity": 1, - "ADP Price": 89.0, - "SN Required": "No" - }, - { - "Device Type": "Arm Support Hardware", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Non Standard Modular MountingHardwareRequired For Positioning (Maximum 2)", - "Device Code": "SEAND0025", - "Quantity": 2, - "ADP Price": 138.0, - "SN Required": "No" - }, - { - "Device Type": "Arm Support Hardware", - "Manufacturer": "Custom Fabricated", - "Device Description": "Swivel Armrest Hardware (Maximum 2)", - "Device Code": "SEICF301L", - "Quantity": 2, - "ADP Price": 60.0, - "SN Required": "No" - }, - { - "Device Type": "Arm Support Options", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Add Modular Pressure Relief ToArmrest -Specialty Foam/Gel (Maximum 2)", - "Device Code": "SEAND0030", - "Quantity": 2, - "ADP Price": 65.0, - "SN Required": "No" - }, - { - "Device Type": "Arm Support Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Rigid Side Panel For Custom ArmSupport(Maximum 2)", - "Device Code": "SEMCF601L", - "Quantity": 2, - "ADP Price": 52.0, - "SN Required": "No" - }, - { - "Device Type": "Arm Support Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Side Panel Pad For Custom ArmSupport(Maximum 2)", - "Device Code": "SEMCF602L", - "Quantity": 2, - "ADP Price": 35.0, - "SN Required": "No" - }, - { - "Device Type": "Arm Support(s)", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Modular Arm Support - Includes Mounting Hardware (Maximum 2)", - "Device Code": "SEAND0005", - "Quantity": 2, - "ADP Price": 237.0, - "SN Required": "No" - }, - { - "Device Type": "Arm Support(s)", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Extra Wide &/Or Extended Length ForModular Arm Supports - Includes Mounting Hardware (Maximum 2)", - "Device Code": "SEAND0010", - "Quantity": 2, - "ADP Price": 91.0, - "SN Required": "No" - }, - { - "Device Type": "Arm Support(s)", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Modular Hand Support - Flat/Cone - Includes Mounting Hardware (Maximum 2)", - "Device Code": "SEAND0015", - "Quantity": 2, - "ADP Price": 65.0, - "SN Required": "No" - }, - { - "Device Type": "Arm Support(s)", - "Manufacturer": "Custom Fabricated", - "Device Description": "Fixed Arm Support, One Piece, Includes Hardware (Maximum 2)", - "Device Code": "SEACF101L", - "Quantity": 2, - "ADP Price": 129.0, - "SN Required": "No" - }, - { - "Device Type": "Arm Support(s)", - "Manufacturer": "Custom Fabricated", - "Device Description": "Complex Arm Support, MultiComponent,Includes Hardware (Maximum 2)", - "Device Code": "SEACF102L", - "Quantity": 2, - "ADP Price": 216.0, - "SN Required": "No" - }, - { - "Device Type": "Arm Support(s)", - "Manufacturer": "Custom Fabricated", - "Device Description": "Heavy Duty Solid Padded ArmrestSupport,Replaces Padded W/C Armpad,Includes Hardware (Maximum 2)", - "Device Code": "SEACF103L", - "Quantity": 2, - "ADP Price": 65.0, - "SN Required": "No" - }, - { - "Device Type": "Arm Support(s)", - "Manufacturer": "Custom Fabricated", - "Device Description": "Full Sling Arm Support,Includes Hardware (Maximum 2)", - "Device Code": "SEACF104L", - "Quantity": 2, - "ADP Price": 259.0, - "SN Required": "No" - }, - { - "Device Type": "Auto Correction System*", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Auto Correction System*", - "Device Code": "WEPQ", - "Quantity": 1, - "ADP Price": 1181.0, - "SN Required": "No" - }, - { - "Device Type": "Back Cover", - "Manufacturer": "Custom Fabricated", - "Device Description": "Removable Cover For Flat Back", - "Device Code": "SEMCF101L", - "Quantity": 2, - "ADP Price": 104.0, - "SN Required": "No" - }, - { - "Device Type": "Back Cover", - "Manufacturer": "Custom Fabricated", - "Device Description": "Removable Cover For Contoured/Custom Contoured Back", - "Device Code": "SEMCF102L", - "Quantity": 2, - "ADP Price": 155.0, - "SN Required": "No" - }, - { - "Device Type": "Back Cover", - "Manufacturer": "Custom Fabricated", - "Device Description": "Removable Cover For Back With Laterals", - "Device Code": "SEMCF103L", - "Quantity": 2, - "ADP Price": 198.0, - "SN Required": "No" - }, - { - "Device Type": "Back Cover", - "Manufacturer": "Custom Fabricated", - "Device Description": "Removable Cover For Sculptured Or Molded Back", - "Device Code": "SEMCF104L", - "Quantity": 2, - "ADP Price": 233.0, - "SN Required": "No" - }, - { - "Device Type": "Back Hardware", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Complex Specialized Mounting Hardware - Including Hardware For Custom Molded Modular Systems", - "Device Code": "SEBND0010", - "Quantity": 2, - "ADP Price": 345.0, - "SN Required": "No" - }, - { - "Device Type": "Back Hardware", - "Manufacturer": "Custom Fabricated", - "Device Description": "Simple Back Interface Mounts Back To Wheelchair Frame", - "Device Code": "SEICF160L", - "Quantity": 1, - "ADP Price": 168.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Action Products", - "Device Description": "Twister Cb Back 15\"-16\" Width X 11\"-16\" Height", - "Device Code": "SEBAN0005", - "Quantity": 1, - "ADP Price": 388.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Action Products", - "Device Description": "Twister Cb Back 17\"-18\" Width X 11\"-16\" Height", - "Device Code": "SEBAN0010", - "Quantity": 1, - "ADP Price": 388.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Action Products", - "Device Description": "Twister Cb Back 19\"-20\" Width X 11\"-16\" Height", - "Device Code": "SEBAN0015", - "Quantity": 1, - "ADP Price": 457.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Action Products", - "Device Description": "Twister Cb Back 21\"-23\" Width X 11\"-16\" Height", - "Device Code": "SEBAN0020", - "Quantity": 1, - "ADP Price": 457.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Action Products", - "Device Description": "Twister Cb Back 15\"-16\" Width X 17\"-21\" Height", - "Device Code": "SEBAN0025", - "Quantity": 1, - "ADP Price": 388.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Action Products", - "Device Description": "Twister Cb Back 17\"-18\" Width X 17\"-21\" Height", - "Device Code": "SEBAN0030", - "Quantity": 1, - "ADP Price": 388.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Action Products", - "Device Description": "Twister Cb Back 19\"-20\" Width X 17\"-21\" Height", - "Device Code": "SEBAN0035", - "Quantity": 1, - "ADP Price": 457.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Action Products", - "Device Description": "Twister Cb Back 21\"-23\" Width X 17\"-21\" Height", - "Device Code": "SEBAN0040", - "Quantity": 1, - "ADP Price": 457.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Adaptive Equipment Systems", - "Device Description": "Solid Back Insert Package W/UniversalHardware Or E-Z Mount Mount Hardware & Rotating Hold Downs.", - "Device Code": "SEB2L0005", - "Quantity": 1, - "ADP Price": 555.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Adaptive Equipment Systems", - "Device Description": "I Or T Or Curved Syle Solid Back Insert, Includes T-Nuts.", - "Device Code": "SEB2L1015", - "Quantity": 1, - "ADP Price": 236.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Adaptive Equipment Systems", - "Device Description": "Adjustable Bi-Angular Solid BackInsert, Includes T-Nuts& Adjustment Brackets.", - "Device Code": "SEB2L1025", - "Quantity": 1, - "ADP Price": 378.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Adaptive Equipment Systems", - "Device Description": "Quick-Fit Contour/Bi-Angular SolidBack Insert,Incudes T-Nuts.", - "Device Code": "SEB2L1030", - "Quantity": 1, - "ADP Price": 519.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Adaptive Equipment Systems", - "Device Description": "Oversize Upcharge For Backs Over 2o\" But Less Than 28\".", - "Device Code": "SEB2L1040", - "Quantity": 1, - "ADP Price": 69.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Solid Back W/Drop Hooks & Fixed Hold Downs.", - "Device Code": "SEB2L0010", - "Quantity": 1, - "ADP Price": 230.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Solid Back Insert Package, Li'L Kiddos, 14\" Wide Or Less.", - "Device Code": "SEB2L0020", - "Quantity": 1, - "ADP Price": 632.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Solid Back Insert Package, Li'L Kiddos, Contoured, 14\" Wide.", - "Device Code": "SEB2L0025", - "Quantity": 1, - "ADP Price": 775.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Solid Back Insert, Includes T-Nuts.", - "Device Code": "SEB2L1005", - "Quantity": 1, - "ADP Price": 158.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Solid Back Insert, Includes T-Nuts, Li'LKiddos,14\" Wide Or Less.", - "Device Code": "SEB2L1010", - "Quantity": 1, - "ADP Price": 213.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "U Form Deep Contour Back Support", - "Device Code": "SEBAO0050", - "Quantity": 1, - "ADP Price": 744.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Amylior Inc.", - "Device Description": "Contour Back Support, Standard Sizes", - "Device Code": "SEB4P0010", - "Quantity": 1, - "ADP Price": 442.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Amylior Inc.", - "Device Description": "Contour Back Support, Non-Standard Sizes", - "Device Code": "SEB4P0015", - "Quantity": 1, - "ADP Price": 524.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Amylior Inc.", - "Device Description": "Contour Back Support For Heavy Duty", - "Device Code": "SEB4P0020", - "Quantity": 1, - "ADP Price": 825.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Blake Medical", - "Device Description": "Silverback Prime 16/18/20\" wide", - "Device Code": "SE0001108", - "Quantity": 1, - "ADP Price": 742.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Blake Medical", - "Device Description": "Silverback Max 16/18/20\" wide", - "Device Code": "SE0001109", - "Quantity": 1, - "ADP Price": 872.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Blake Medical", - "Device Description": "Silverback Max - Deep Contour 16/18/20\" wide", - "Device Code": "SE0001687", - "Quantity": 1, - "ADP Price": 943.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Blake Medical", - "Device Description": "Silverback Prime - Deep Contour 16/18/20\" wide", - "Device Code": "SE0001688", - "Quantity": 1, - "ADP Price": 817.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Blake Medical", - "Device Description": "Silverback Max - Extra Deep Contour 16/18/20\" wide", - "Device Code": "SE0001689", - "Quantity": 1, - "ADP Price": 990.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Blake Medical", - "Device Description": "Silverback Prime - Extra Deep Contour 16/18/20\" wide", - "Device Code": "SE0001690", - "Quantity": 1, - "ADP Price": 863.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Broda", - "Device Description": "APP Back Support (For 16\", 18\" and 20\" Seat Width)", - "Device Code": "SE0001882", - "Quantity": 1, - "ADP Price": 208.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Broda", - "Device Description": "APP Back Support (For 22\" and 24\" Seat Width)", - "Device Code": "SE0001883", - "Quantity": 1, - "ADP Price": 228.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Broda", - "Device Description": "APP Back Support (For 26\" and 28\" Seat Width)", - "Device Code": "SE0001884", - "Quantity": 1, - "ADP Price": 238.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Broda", - "Device Description": "Back Pad", - "Device Code": "SEBB-0010", - "Quantity": 1, - "ADP Price": 58.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Custom Fabricated", - "Device Description": "Flat Back/Planar Design, Vinyl CoverWithout Mounting Hardware", - "Device Code": "SEBCF110L", - "Quantity": 1, - "ADP Price": 259.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Custom Fabricated", - "Device Description": "Contoured Back (Foam On Rigid Base), Minimal Trunk Support, Vinyl Cover, Without Mounting Hardware", - "Device Code": "SEBCF112L", - "Quantity": 1, - "ADP Price": 431.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Custom Fabricated", - "Device Description": "Custom Contoured Back, ModerateTrunk Support,Vinyl Cover, Without Mounting Hardware", - "Device Code": "SEBCF113L", - "Quantity": 1, - "ADP Price": 673.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Custom Fabricated", - "Device Description": "Back With Permanent Lateral Supports, Vinyl Cover, Without Mounting Hardware", - "Device Code": "SEBCF114L", - "Quantity": 1, - "ADP Price": 561.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Custom Fabricated", - "Device Description": "Custom Shaped Sculptured Back,Includes Cover,Without Mounting Hardware", - "Device Code": "SEBCF115L", - "Quantity": 1, - "ADP Price": 819.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Custom Fabricated", - "Device Description": "Simple Molded Back (Foam In Place), Without Cover And Mounting Hardware", - "Device Code": "SEBCF116L", - "Quantity": 1, - "ADP Price": 810.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Custom Fabricated", - "Device Description": "Complex Molded Back (Foam InPlace),Without Cover And Mounting Hardware", - "Device Code": "SEBCF117L", - "Quantity": 1, - "ADP Price": 1122.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Custom Fabricated", - "Device Description": "Complex Indirect Molded Back, Without Cover And Mounting Hardware", - "Device Code": "SEBCF118L", - "Quantity": 1, - "ADP Price": 1259.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "Xtend Height Adjustable Thoracic Back Support 16\" - 20\" Wide", - "Device Code": "SE0000335", - "Quantity": 1, - "ADP Price": 475.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "Xtend Deep Height Adjustable Thoracic Back Support 16\" - 20\" Wide", - "Device Code": "SE0000336", - "Quantity": 1, - "ADP Price": 475.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "Xtend Deep Height Adjustable Thoracic Back Support 22\" -24\" Wide", - "Device Code": "SE0000338", - "Quantity": 1, - "ADP Price": 496.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "Classic Pelvic Back Support 16\"-20\" Wide", - "Device Code": "SE0000340", - "Quantity": 1, - "ADP Price": 496.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "Classic Deep Pelvic Back Support 16\" - 20\" Wide", - "Device Code": "SE0000341", - "Quantity": 1, - "ADP Price": 579.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "Armadillo Back Support 14\" - 24\" Wide", - "Device Code": "SE0001130", - "Quantity": 1, - "ADP Price": 687.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "Xtend Height Adjustable Thoracic Back Support 22 \" - 24\" Wide", - "Device Code": "SE0001182", - "Quantity": 1, - "ADP Price": 497.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "Optima Thoracic Back Support 21\" - 22\" Wide", - "Device Code": "SE0001215", - "Quantity": 1, - "ADP Price": 497.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "Optima Deep Thoracic Back Support 21\" - 22\" Wide", - "Device Code": "SE0001216", - "Quantity": 1, - "ADP Price": 566.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "Optima Thoracic Back Support 13\" - 20\" Wide", - "Device Code": "SE0001217", - "Quantity": 1, - "ADP Price": 476.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "Optima Deep Thoracic Back Support 13\" - 20\" Wide", - "Device Code": "SE0001219", - "Quantity": 1, - "ADP Price": 545.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "Optima Carbon Thoracic Back Support 14\" - 20\" Wide", - "Device Code": "SE0001222", - "Quantity": 1, - "ADP Price": 756.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "Optima Carbon Deep Thoracic Back Support 15\" - 20\" Wide", - "Device Code": "SE0001281", - "Quantity": 1, - "ADP Price": 824.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "Xtend Low Height Adjustable Thoracic Back Support 12\" - 20\" Wide", - "Device Code": "SE0001326", - "Quantity": 1, - "ADP Price": 475.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "Xtend Low Height Adjustable Thoracic Back Support 22\" - 24\" Wide", - "Device Code": "SE0001327", - "Quantity": 1, - "ADP Price": 497.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "Xtend Low Deep Height Adjustable Thoracic Back Support 12\" - 20\" Wide", - "Device Code": "SE0001328", - "Quantity": 1, - "ADP Price": 475.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "Xtend Low Deep Height Adjustable Thoracic Back Support 22\" - 24\" Wide", - "Device Code": "SE0001329", - "Quantity": 1, - "ADP Price": 496.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "UFit Customizable Pelvic Back Support 14\" - 20\" Wide", - "Device Code": "SE0001343", - "Quantity": 1, - "ADP Price": 618.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "UFit Customizable Pelvic Back Support 22\" - 24\" Wide", - "Device Code": "SE0001344", - "Quantity": 1, - "ADP Price": 687.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "UFit Deep Customizable Pelvic Back Support 14\" - 20\" Wide", - "Device Code": "SE0001345", - "Quantity": 1, - "ADP Price": 687.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "UFit Deep Customizable Pelvic Back Support 22\" - 24\" Wide", - "Device Code": "SE0001346", - "Quantity": 1, - "ADP Price": 825.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "Optima Thoracic Back Support 23\" - 29\" Wide", - "Device Code": "SE0001347", - "Quantity": 1, - "ADP Price": 497.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "Optima Deep Thoracic Back Support 23\" - 29\" Wide", - "Device Code": "SE0001348", - "Quantity": 1, - "ADP Price": 566.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "UFit II Customizable Thoracic Back Support 14\" - 20\" Wide", - "Device Code": "SE0001490", - "Quantity": 1, - "ADP Price": 652.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "UFit II Customizable Thoracic Back Support 22\" - 24\" Wide", - "Device Code": "SE0001491", - "Quantity": 1, - "ADP Price": 687.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "UFit II Deep Customizable Thoracic Back Support 14\" - 20\" Wide", - "Device Code": "SE0001492", - "Quantity": 1, - "ADP Price": 721.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "UFit II Deep Customizable Thoracic Back Support 22\" - 24\" Wide", - "Device Code": "SE0001493", - "Quantity": 1, - "ADP Price": 825.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "Classic Pelvic Back Support 22\" - 24\" Wide", - "Device Code": "SE0001494", - "Quantity": 1, - "ADP Price": 497.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "Classic Deep Pelvic Back Support 22\" - 24\" Wide", - "Device Code": "SE0001495", - "Quantity": 1, - "ADP Price": 566.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Custom Lunar Back", - "Device Code": "SE0000684", - "Quantity": 1, - "ADP Price": 656.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Custom Lunar Back HD", - "Device Code": "SE0000685", - "Quantity": 1, - "ADP Price": 1242.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Lunar Slim Back", - "Device Code": "SE0001243", - "Quantity": 1, - "ADP Price": 431.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Lunar Slim Back (Bariatric)", - "Device Code": "SE0001244", - "Quantity": 1, - "ADP Price": 690.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Basic Back Fits 16,18,20\" Wide W/C", - "Device Code": "SEBFM0005", - "Quantity": 1, - "ADP Price": 424.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Basic Back - Non Standard Sizes", - "Device Code": "SEBFM0010", - "Quantity": 1, - "ADP Price": 518.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Basic Back - Custom Sizes", - "Device Code": "SEBFM0015", - "Quantity": 1, - "ADP Price": 569.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Ultra Back Fits 16,18,20\" Wide W/C", - "Device Code": "SEBFM0020", - "Quantity": 1, - "ADP Price": 535.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Ultra Back - Non Standard Sizes", - "Device Code": "SEBFM0025", - "Quantity": 1, - "ADP Price": 621.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Ultra Back - Custom Sizes", - "Device Code": "SEBFM0030", - "Quantity": 1, - "ADP Price": 697.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Air Back Fits 16,18,20\" Wide W/C", - "Device Code": "SEBFM0035", - "Quantity": 1, - "ADP Price": 552.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Air Back - Non Standard Sizes", - "Device Code": "SEBFM0040", - "Quantity": 1, - "ADP Price": 656.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Air Back - Custom Sizes", - "Device Code": "SEBFM0045", - "Quantity": 1, - "ADP Price": 742.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Truefitt Back Fits 16,18,20\" Wide W/C", - "Device Code": "SEBFM0050", - "Quantity": 1, - "ADP Price": 604.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Truefitt Back - Non Standard Sizes", - "Device Code": "SEBFM0055", - "Quantity": 1, - "ADP Price": 638.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Truefitt Back - Bariatric Sizes", - "Device Code": "SEBFM0060", - "Quantity": 1, - "ADP Price": 863.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Truefitt Back - Custom Sizes", - "Device Code": "SEBFM0065", - "Quantity": 1, - "ADP Price": 707.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Phantom Back 12-18\" Width X 7\" Height", - "Device Code": "SEBFM0070", - "Quantity": 1, - "ADP Price": 275.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Super Back For Kids Fits 10, 12, 14 And 16\" Wide W/C", - "Device Code": "SEBFM0080", - "Quantity": 1, - "ADP Price": 431.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Super Back For Kids - Non Standard Sizes", - "Device Code": "SEBFM0085", - "Quantity": 1, - "ADP Price": 493.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Super Back For Kids - Custom Sizes", - "Device Code": "SEBFM0090", - "Quantity": 1, - "ADP Price": 569.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Max Back - Upcharge", - "Device Code": "SEBFM0150", - "Quantity": 1, - "ADP Price": 86.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Bariatric Basic Back 21x16 Through 42x20", - "Device Code": "SEBFM2005", - "Quantity": 1, - "ADP Price": 690.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Bariatric Basic Back - Custom Size", - "Device Code": "SEBFM2010", - "Quantity": 1, - "ADP Price": 742.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Bariatric Ultra Back 21x16 Through 24x20", - "Device Code": "SEBFM2015", - "Quantity": 1, - "ADP Price": 697.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Bariatric Ultra Back- Custom Size", - "Device Code": "SEBFM2020", - "Quantity": 1, - "ADP Price": 794.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Bariatric Air Back 21x16 Though 24x20", - "Device Code": "SEBFM2025", - "Quantity": 1, - "ADP Price": 828.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Bariatric Air Back- Custom Size", - "Device Code": "SEBFM2030", - "Quantity": 1, - "ADP Price": 914.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Orion Back", - "Device Code": "SEBFM3005", - "Quantity": 1, - "ADP Price": 400.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Low Back - Sizes From 16\" To 20\" - No Lateral", - "Device Code": "SEBFM3010", - "Quantity": 1, - "ADP Price": 431.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Mid Back - Sizes From 16\" To 20\" - No Lateral", - "Device Code": "SEBFM3015", - "Quantity": 1, - "ADP Price": 490.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Full Back - Sizes From 18\" To 24\" No Lateral", - "Device Code": "SEBFM3020", - "Quantity": 1, - "ADP Price": 507.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Mid Back - Sizes From 14\" To 22\" - Lateral", - "Device Code": "SEBFM3030", - "Quantity": 1, - "ADP Price": 531.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Low Back - Sizes From 14\" To 22\" - Lateral", - "Device Code": "SEBFM3035", - "Quantity": 1, - "ADP Price": 483.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Full Back - Sizes From 14\" To 22\" - Lateral", - "Device Code": "SEBFM3040", - "Quantity": 1, - "ADP Price": 549.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Mid Back - Sizes From 14\" To 22\" - Ultra Lateral", - "Device Code": "SEBFM3045", - "Quantity": 1, - "ADP Price": 573.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Full Back - Sizes From 14\" To 22\" - Ultra Lateral", - "Device Code": "SEBFM3050", - "Quantity": 1, - "ADP Price": 590.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Mid Back Style Heavy Duty", - "Device Code": "SEBFM3055", - "Quantity": 1, - "ADP Price": 690.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Future Mobility", - "Device Description": "Full Back Style Heavy Duty", - "Device Code": "SEBFM3060", - "Quantity": 1, - "ADP Price": 725.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Hoggi", - "Device Description": "Back Cushion trough Shaped", - "Device Code": "SE0000466", - "Quantity": 1, - "ADP Price": 322.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Hoggi", - "Device Description": "Back Cushion Shaped", - "Device Code": "SE0000469", - "Quantity": 1, - "ADP Price": 272.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Hoggi", - "Device Description": "Xps Adaptive Back Cushion", - "Device Code": "SEBK20050", - "Quantity": 1, - "ADP Price": 259.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Innovators 1993 Inc", - "Device Description": "K Special Back-Standard", - "Device Code": "SEBI30010", - "Quantity": 1, - "ADP Price": 130.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Innovators 1993 Inc", - "Device Description": "K Special Back-Custom", - "Device Code": "SEBI30020", - "Quantity": 1, - "ADP Price": 152.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Innovators 1993 Inc", - "Device Description": "Key-Hole Back", - "Device Code": "SEBI30030", - "Quantity": 1, - "ADP Price": 152.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Innovators 1993 Inc", - "Device Description": "Key-Hole Back Custom", - "Device Code": "SEBI30040", - "Quantity": 1, - "ADP Price": 169.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Innovators 1993 Inc", - "Device Description": "Key-Hole Back Custom Adjustable Top", - "Device Code": "SEBI30045", - "Quantity": 1, - "ADP Price": 169.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Innovators 1993 Inc", - "Device Description": "K-Combo Back", - "Device Code": "SEBI30060", - "Quantity": 1, - "ADP Price": 173.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Innovators 1993 Inc", - "Device Description": "K-Combo Back Custom", - "Device Code": "SEBI30065", - "Quantity": 1, - "ADP Price": 191.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Elite HD, Stock sizes only", - "Device Code": "SE0001051", - "Quantity": 1, - "ADP Price": 703.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Elite HD, Non stock sizes", - "Device Code": "SE0001052", - "Quantity": 1, - "ADP Price": 1113.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Mini - Paediatric", - "Device Code": "SE0001213", - "Quantity": 1, - "ADP Price": 583.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Elite TR - Adult", - "Device Code": "SE0001214", - "Quantity": 1, - "ADP Price": 596.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Posture Back Fits W/C 13\"-20\" Width & 12\"-20\"Height", - "Device Code": "SEB1M0005", - "Quantity": 1, - "ADP Price": 560.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Heavy Duty Posture Back Fits W/C20\"-25\" Width & 16\"-20\" Height", - "Device Code": "SEB1M0010", - "Quantity": 1, - "ADP Price": 801.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Deep Posture Back, All Sizes", - "Device Code": "SEB1M0015", - "Quantity": 1, - "ADP Price": 681.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Deep Heavy Duty Posture Back, Stock sizes only", - "Device Code": "SEB1M0020", - "Quantity": 1, - "ADP Price": 922.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Elite Back", - "Device Code": "SEB1M0025", - "Quantity": 1, - "ADP Price": 584.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "PB Elite Deep All Sizes", - "Device Code": "SEB1M0026", - "Quantity": 1, - "ADP Price": 618.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "PB Extra Wide Heavy Duty Backs All sizes", - "Device Code": "SEB1M0035", - "Quantity": 1, - "ADP Price": 1133.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "PB Extra Wide Deep Heavy Duty Backs All", - "Device Code": "SEB1M0040", - "Quantity": 1, - "ADP Price": 1239.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx High Back Fits W/C 16\" - 21\" Width & 20\" - 30\" Height", - "Device Code": "SEB1M1005", - "Quantity": 1, - "ADP Price": 560.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Trx Rehab Back, Fits W/C 18\" - 25\" Width", - "Device Code": "SEB1M1050", - "Quantity": 1, - "ADP Price": 204.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "JAY Zip Back All Sizes", - "Device Code": "SE0000640", - "Quantity": 1, - "ADP Price": 587.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 Back Includes Mounting Hardware (\"\"K\"\" Or \"\"G\"\" Type), Cover & Lumbar Supports (14\"\"-19\"\")", - "Device Code": "SEBJA0100", - "Quantity": 1, - "ADP Price": 501.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 Back Includes MountingHardware, Cover& Lumbar Supports (12\"/13\")", - "Device Code": "SEBJA0105", - "Quantity": 1, - "ADP Price": 501.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 Back- Includes Mounting Hardware (\"\"K\"\" Or \"\"G\"\" Type), Cover & Lumbar Supports (20\"\")", - "Device Code": "SEBJA0110", - "Quantity": 1, - "ADP Price": 560.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 Tall Back- Includes MountingHardware, Cover& Lumbar Supports (14\"/16\"/17\"/18\")", - "Device Code": "SEBJA0120", - "Quantity": 1, - "ADP Price": 574.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 Tall Back- Includes Mounting Hardware, Cover & Lumbar Supports (20\")", - "Device Code": "SEBJA0130", - "Quantity": 1, - "ADP Price": 662.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "JAY 2 Plus 20-23\", 23-26\" J2 BackAssemblyFor 0 Or 8 Degree Backposts", - "Device Code": "SEBJA0300", - "Quantity": 1, - "ADP Price": 982.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 Plus 20-23\", 23-26\" BackAssembly For 0 To 8 DegreeBackposts,With Headrest Mounting Kit", - "Device Code": "SEBJA0310", - "Quantity": 1, - "ADP Price": 1052.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "J3 Lower Thoracic Back, All Sizes", - "Device Code": "SEBJA0900", - "Quantity": 1, - "ADP Price": 380.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "J3 Mid Thoracic Back, All Sizes", - "Device Code": "SEBJA0905", - "Quantity": 1, - "ADP Price": 511.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "J3 Upper Thoracic Back, All Sizes", - "Device Code": "SEBJA0910", - "Quantity": 1, - "ADP Price": 600.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "J3 Shoulder Height Back, All Sizes", - "Device Code": "SEBJA0915", - "Quantity": 1, - "ADP Price": 618.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Basic Back, Fixed Strap Style, All Sizes", - "Device Code": "SEBJA2020", - "Quantity": 1, - "ADP Price": 322.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Basic Back, Fixed Clamp Style, All Sizes", - "Device Code": "SEBJA2025", - "Quantity": 1, - "ADP Price": 350.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Fit Back Adjustable Contour BackFor 10\" Or 12\" Frame Width,Various Back Heights", - "Device Code": "SEBJA4005", - "Quantity": 1, - "ADP Price": 290.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Fit Back Adjustable Contour Back For 14\" Or 16\" Frame Width, Various Back Heights", - "Device Code": "SEBJA4010", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Fit Back Adjustable Contour BackFor 18\" Frame Width,Various Back Heights", - "Device Code": "SEBJA4015", - "Quantity": 1, - "ADP Price": 366.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Care Back 15-18\" Wide", - "Device Code": "SEBJA5000", - "Quantity": 1, - "ADP Price": 440.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Care Back Foam Large Size", - "Device Code": "SEBJA5045", - "Quantity": 1, - "ADP Price": 136.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Care Back Shell Large Size", - "Device Code": "SEBJA5055", - "Quantity": 1, - "ADP Price": 282.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "J2 Deep Contour Back 14w-19w,Includes MountingHardware, Cover, Lumbar Supports & Lateral Wedges", - "Device Code": "SEBJA7000", - "Quantity": 1, - "ADP Price": 523.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "J2 Deep Contour Back 20wx20h,Includes MountingHardware, Cover, Lumbar Supports & Lateral Wedges", - "Device Code": "SEBJA7005", - "Quantity": 1, - "ADP Price": 557.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Focus Point Back, All Sizes", - "Device Code": "SEBJA8100", - "Quantity": 1, - "ADP Price": 540.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Encompass Back", - "Device Code": "SEBJA8200", - "Quantity": 1, - "ADP Price": 311.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Kaji Corporation", - "Device Description": "OWL Fusion Back (16\" x 16\" - 20\" x16\")", - "Device Code": "SE0001654", - "Quantity": 1, - "ADP Price": 863.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Kaji Corporation", - "Device Description": "OWL Fusion Back (20\" x 18\" - 20\" x20\")", - "Device Code": "SE0001655", - "Quantity": 1, - "ADP Price": 897.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Kaji Corporation", - "Device Description": "OWL Fusion Back (Custom Size)", - "Device Code": "SE0001656", - "Quantity": 1, - "ADP Price": 1018.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Kaji Corporation", - "Device Description": "OWL Comfort Back (16\" x 16\" - 20\" x16\")", - "Device Code": "SE0001657", - "Quantity": 1, - "ADP Price": 1001.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Kaji Corporation", - "Device Description": "OWL Comfort Back (20\" x 18\" - 20\" x20\")", - "Device Code": "SE0001658", - "Quantity": 1, - "ADP Price": 1035.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Kaji Corporation", - "Device Description": "OWL Comfort Back (Custom Size)", - "Device Code": "SE0001659", - "Quantity": 1, - "ADP Price": 1087.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Kid Kart", - "Device Description": "I-Back Cushion Tlc", - "Device Code": "SEBKT2015", - "Quantity": 1, - "ADP Price": 101.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Kid Kart", - "Device Description": "Xpress T-Back 1\" Short, Regular, Or Tall", - "Device Code": "SEBKT2025", - "Quantity": 1, - "ADP Price": 112.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Kid Kart", - "Device Description": "Xpress T-Back 2.5\" Short, Regular, Or Tall", - "Device Code": "SEBKT2030", - "Quantity": 1, - "ADP Price": 112.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom Posterior Back 12\" - 20\"", - "Device Code": "SE0001624", - "Quantity": 1, - "ADP Price": 629.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom Posterior Back 22\"", - "Device Code": "SE0001625", - "Quantity": 1, - "ADP Price": 863.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom Posterior Lateral Back 12\" - 20\"", - "Device Code": "SE0001626", - "Quantity": 1, - "ADP Price": 721.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom Posterior Lateral Back 22\"", - "Device Code": "SE0001627", - "Quantity": 1, - "ADP Price": 963.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom Deep Lateral Back 12\" - 20\"", - "Device Code": "SE0001628", - "Quantity": 1, - "ADP Price": 831.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom Deep Lateral Back 22\"", - "Device Code": "SE0001629", - "Quantity": 1, - "ADP Price": 883.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom CS Solid Back Cushion", - "Device Code": "SE0001711", - "Quantity": 1, - "ADP Price": 271.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom CS Pediatric Solid Back Cushion", - "Device Code": "SE0001712", - "Quantity": 1, - "ADP Price": 261.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom CS Solid Back Interface", - "Device Code": "SE0001713", - "Quantity": 1, - "ADP Price": 247.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom CS Pediatric Solid Back Interface", - "Device Code": "SE0001714", - "Quantity": 1, - "ADP Price": 247.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom CS Back Cushion", - "Device Code": "SE0001715", - "Quantity": 1, - "ADP Price": 242.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom CS Back (I-Back and T-Back)", - "Device Code": "SE0001779", - "Quantity": 1, - "ADP Price": 395.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom CS Back (Bi-Angular)", - "Device Code": "SE0001780", - "Quantity": 1, - "ADP Price": 696.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom Kids PL - Posterior Lateral Back 10\" -16\"", - "Device Code": "SE0002123", - "Quantity": 1, - "ADP Price": 759.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom Kids AL - Posterior Back Adjustable Laterals 10\"-16\"", - "Device Code": "SE0002124", - "Quantity": 1, - "ADP Price": 997.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom Kids ALCL - Posterior Back Adjustable Contoured Laterals 10\"-16\"", - "Device Code": "SE0002125", - "Quantity": 1, - "ADP Price": 1276.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom Custom Back", - "Device Code": "SE0002135", - "Quantity": 1, - "ADP Price": 1076.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom Custom Back (W+)", - "Device Code": "SE0002136", - "Quantity": 1, - "ADP Price": 1235.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ki Mobility", - "Device Description": "Complex Axiom Custom Back", - "Device Code": "SE0002137", - "Quantity": 1, - "ADP Price": 1435.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ki Mobility", - "Device Description": "Complex Axiom Custom Back (W+/H+)", - "Device Code": "SE0002138", - "Quantity": 1, - "ADP Price": 1546.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Lpa Medical Inc.", - "Device Description": "Contour Back Cushion", - "Device Code": "SEBO12005", - "Quantity": 1, - "ADP Price": 93.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Lpa Medical Inc.", - "Device Description": "Adjustable Tension Back", - "Device Code": "SEBO12010", - "Quantity": 1, - "ADP Price": 172.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "ML Shallow", - "Device Code": "SE0001087", - "Quantity": 1, - "ADP Price": 375.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "ML Kyphothic", - "Device Code": "SE0001089", - "Quantity": 1, - "ADP Price": 574.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "ML Slim Standard", - "Device Code": "SE0001334", - "Quantity": 1, - "ADP Price": 500.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "ML Slim Tall", - "Device Code": "SE0001335", - "Quantity": 1, - "ADP Price": 525.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "ML Slim Short", - "Device Code": "SE0001336", - "Quantity": 1, - "ADP Price": 525.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "ML Slim Custom", - "Device Code": "SE0001337", - "Quantity": 1, - "ADP Price": 600.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "The Fusion1 (Standard, All Sizes)", - "Device Code": "SE0001359", - "Quantity": 1, - "ADP Price": 495.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "The Fusion1 (Non-Standard, All Sizes)", - "Device Code": "SE0001360", - "Quantity": 1, - "ADP Price": 564.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "The Fusion1 (Bariatric)", - "Device Code": "SE0001361", - "Quantity": 1, - "ADP Price": 633.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "The Fusion Essential (Standard, All Sizes)", - "Device Code": "SE0001362", - "Quantity": 1, - "ADP Price": 695.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "The Fusion Essential (Non-Standard, All Sizes)", - "Device Code": "SE0001363", - "Quantity": 1, - "ADP Price": 764.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "The Fusion Essential (Bariatric)", - "Device Code": "SE0001364", - "Quantity": 1, - "ADP Price": 833.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "The Fusion2 (Standard, All Sizes)", - "Device Code": "SE0001584", - "Quantity": 1, - "ADP Price": 460.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "The Fusion2 (Non-Standard, All Sizes)", - "Device Code": "SE0001585", - "Quantity": 1, - "ADP Price": 518.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "The Fusion2 (Bariatric, All Sizes)", - "Device Code": "SE0001586", - "Quantity": 1, - "ADP Price": 575.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "The Fusion3 (Standard, All Sizes)", - "Device Code": "SE0001587", - "Quantity": 1, - "ADP Price": 495.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "The Fusion3 (Non-Standard, All Sizes)", - "Device Code": "SE0001588", - "Quantity": 1, - "ADP Price": 552.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "The Fusion3 (Bariatric, All Sizes)", - "Device Code": "SE0001589", - "Quantity": 1, - "ADP Price": 610.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Motion Concepts", - "Device Description": "Matrx MX2 Back (14\" x 6 \", 15\" x 6\",16\" x 6\", 17\" x 6\", 18\" x 6\") with fixed mounting or quick release hardware", - "Device Code": "SE0001460", - "Quantity": 1, - "ADP Price": 756.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Motion Concepts", - "Device Description": "Matrx MX2 Back (14\" x 9 \", 15\" x 9\",16\" x 9\", 17\" x 9\", 18\" x 9\") with fixed mounting or quick release hardware", - "Device Code": "SE0001461", - "Quantity": 1, - "ADP Price": 790.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Motion Concepts", - "Device Description": "Matrx MX2 Back (14\" x 12 \", 15\" x 12\",16\" x 12\", 17\" x 12\", 18\" x 12\") withfixed mounting or quick release hardware", - "Device Code": "SE0001462", - "Quantity": 1, - "ADP Price": 825.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Motion Concepts", - "Device Description": "Matrx MX2 Back (14\" x 16 \", 15\" x 16\",16\" x 16\", 17\" x 16\", 18\" x 16\") withfixed mounting or quick release hardware", - "Device Code": "SE0001463", - "Quantity": 1, - "ADP Price": 859.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Motion Concepts", - "Device Description": "Invacare Matrx E2 Back (6\" - 16\" high)", - "Device Code": "SE0001775", - "Quantity": 1, - "ADP Price": 666.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Motion Concepts", - "Device Description": "Invacare Matrx E2 Back (18\" - 20\" high)", - "Device Code": "SE0001776", - "Quantity": 1, - "ADP Price": 687.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Motion Concepts", - "Device Description": "Invacare Matrx E2 Deep Back (6\" - 16\" high)", - "Device Code": "SE0001777", - "Quantity": 1, - "ADP Price": 776.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Motion Concepts", - "Device Description": "Invacare Matrx E2 Deep Back (18\" - 20\" high)", - "Device Code": "SE0001778", - "Quantity": 1, - "ADP Price": 797.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Motion Concepts", - "Device Description": "Matrx MAC Back - Dual Layer HR Foam includes Side Contour extensions, Easy Set Hardware, Meshtex Fabric Cover- (16\"-20\"x16\"-22\")", - "Device Code": "SE0002119", - "Quantity": 1, - "ADP Price": 1030.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Motion Concepts", - "Device Description": "Matrx MAC Back - HUG Stamina Fiber Model includes Side Contour extensions, Easy Set Hardware, Meshtex Fabric Cover -(16\"-20\"x16\"-22\")", - "Device Code": "SE0002120", - "Quantity": 1, - "ADP Price": 1170.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Motion Concepts", - "Device Description": "Trx Contour Back, For Trx Systems, 16,18, 22\" WideWheelchairs, Height Adjustable 18-26\"", - "Device Code": "SEBZG0005", - "Quantity": 1, - "ADP Price": 237.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Motion Concepts", - "Device Description": "Trx Onyx Contour Back & Trx SinglePost Cloth Contour Back,For Trx Systems", - "Device Code": "SEBZG0020", - "Quantity": 1, - "ADP Price": 318.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Motion Concepts", - "Device Description": "Trx Single Post Onyx Contour Back For Trx Systems", - "Device Code": "SEBZG0025", - "Quantity": 1, - "ADP Price": 318.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Nighthawk", - "Device Description": "Relaxed Back Low", - "Device Code": "SEBNM0005", - "Quantity": 1, - "ADP Price": 159.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Nighthawk", - "Device Description": "Relaxed Back High", - "Device Code": "SEBNM0010", - "Quantity": 1, - "ADP Price": 159.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Nighthawk", - "Device Description": "Key-Hole Back", - "Device Code": "SEBNM0050", - "Quantity": 1, - "ADP Price": 197.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Nova Seating", - "Device Description": "Nova Shape Back - Custom Molded Back Cushion", - "Device Code": "SE0001835", - "Quantity": 1, - "ADP Price": 1875.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Otto Bock", - "Device Description": "Back-Finished With Spray Coating,Cover,Sewing Pattern", - "Device Code": "SEBOB9650", - "Quantity": 1, - "ADP Price": 1710.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Otto Bock", - "Device Description": "Back-Itemized Cushion (Unfinished)", - "Device Code": "SEBOB9655", - "Quantity": 1, - "ADP Price": 1253.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Permobil", - "Device Description": "ROHO Agility Carbon Back System with Air Only (items up to 10¿ high)", - "Device Code": "SE0001372", - "Quantity": 1, - "ADP Price": 966.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Permobil", - "Device Description": "ROHO Agility Carbon Back System with Air Only (items greater than 10¿ high)", - "Device Code": "SE0001373", - "Quantity": 1, - "ADP Price": 1208.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Permobil", - "Device Description": "Ergo Back - Fixed - All Sizes", - "Device Code": "SEB1P0005", - "Quantity": 1, - "ADP Price": 692.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Permobil", - "Device Description": "Ergo Back - Recline - All Sizes", - "Device Code": "SEB1P0010", - "Quantity": 1, - "ADP Price": 692.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Physipro", - "Device Description": "HP2 Back Support, all models, all sizes", - "Device Code": "SE0001071", - "Quantity": 1, - "ADP Price": 480.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Physipro", - "Device Description": "Premium Back Support, all sizes", - "Device Code": "SE0001072", - "Quantity": 1, - "ADP Price": 480.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Physipro", - "Device Description": "3D-Moulded Backrest - Custom", - "Device Code": "SE0002149", - "Quantity": 1, - "ADP Price": 2210.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Positech Innovation Inc.", - "Device Description": "BACKUS with detachable/waterproof foam cushion backrest (all sizes) including laterals and standard or swing-away anchors", - "Device Code": "SE0001436", - "Quantity": 1, - "ADP Price": 1425.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Positech Innovation Inc.", - "Device Description": "BACKUS (oversize) with detachable/waterproof foam cushion backrest (all sizes) including laterals and standard or swing-away anchors", - "Device Code": "SE0001437", - "Quantity": 1, - "ADP Price": 1550.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Positech Innovation Inc.", - "Device Description": "CURVUS with detachable waterproof foam cushion backrest (all sizes) including laterals and standard or swing-away anchors", - "Device Code": "SE0001438", - "Quantity": 1, - "ADP Price": 1550.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Positech Innovation Inc.", - "Device Description": "CURVUS (oversize) with detachable/waterproof foam cushion backrest (all sizes) including laterals and standard or swing-away anchors", - "Device Code": "SE0001439", - "Quantity": 1, - "ADP Price": 1675.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Positech Innovation Inc.", - "Device Description": "FLEXUS (complete system, one-size-fits-all) with height adjustable foam cushion backrest including laterals and standard or swing-away anchors", - "Device Code": "SE0001440", - "Quantity": 1, - "ADP Price": 2800.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Relax Personal Fit Back (All Sizes)", - "Device Code": "SE0001590", - "Quantity": 1, - "ADP Price": 535.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Relax Full Fit", - "Device Code": "SEBWM0010", - "Quantity": 1, - "ADP Price": 524.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Relax Full Fit (custom)", - "Device Code": "SEBWM0015", - "Quantity": 1, - "ADP Price": 621.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Relax Gentle Fit", - "Device Code": "SEBWM0020", - "Quantity": 1, - "ADP Price": 469.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Relax Gentle Fit (Custom)", - "Device Code": "SEBWM0025", - "Quantity": 1, - "ADP Price": 524.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Relax Form Fit", - "Device Code": "SEBWM0026", - "Quantity": 1, - "ADP Price": 707.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Relax Snug Fit", - "Device Code": "SEBWM0027", - "Quantity": 1, - "ADP Price": 604.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Relax Spiral Fit", - "Device Code": "SEBWM0030", - "Quantity": 1, - "ADP Price": 718.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Upcharge For Custom Width", - "Device Code": "SEBWM0035", - "Quantity": 1, - "ADP Price": 152.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Upcharge For Custom Height", - "Device Code": "SEBWM0040", - "Quantity": 1, - "ADP Price": 152.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Precision Rehab Manufacturing Inc.", - "Device Description": "Back Waterproof Foam", - "Device Code": "SEBWB0010", - "Quantity": 1, - "ADP Price": 1476.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Precision Rehab Manufacturing Inc.", - "Device Description": "Base Cushion Back, Includes All Modifications", - "Device Code": "SEBWB0015", - "Quantity": 1, - "ADP Price": 1793.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Precision Rehab Manufacturing Inc.", - "Device Description": "Precision - Fit Back Cushion, Subtle,Moderate Or AggresivePositioning. Includes Hinged Or Fixed Laterals And Cover.", - "Device Code": "SEBWB0020", - "Quantity": 1, - "ADP Price": 930.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Precision Rehab Manufacturing Inc.", - "Device Description": "Precision - Fit Back Cushion Upcharge,ExtraWide Or Extra Tall, 20\" - 24\"", - "Device Code": "SEBWB0022", - "Quantity": 1, - "ADP Price": 207.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Synergy Standard Back Support, up to 20\". For additional sizing see SEBND0015.", - "Device Code": "SE0000971", - "Quantity": 1, - "ADP Price": 311.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Pride Mobility Products", - "Device Description": "TRU-Comfort 4 and Sport Back (under 16\" wide)", - "Device Code": "SE0001754", - "Quantity": 1, - "ADP Price": 576.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Pride Mobility Products", - "Device Description": "TRU-Comfort 4 and Sport Back (16\" - 20\" wide)", - "Device Code": "SE0001755", - "Quantity": 1, - "ADP Price": 714.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Pride Mobility Products", - "Device Description": "TRU-Comfort 4 and Sport Back (over 20\" wide)", - "Device Code": "SE0001756", - "Quantity": 1, - "ADP Price": 852.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Q-Back 2.0 Extra Deep with Aluminum Contoured/Flat Top (W:14,15; H:Any)", - "Device Code": "SE0002092", - "Quantity": 1, - "ADP Price": 845.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Q-Back 2.0 Extra Deep with Aluminum Contoured/Flat Top (W:16-20; H:Any)", - "Device Code": "SE0002093", - "Quantity": 1, - "ADP Price": 973.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Q-Back 2.0 Extra Deep with Aluminum Contoured/Flat Top (W:21-24; H:Any)", - "Device Code": "SE0002094", - "Quantity": 1, - "ADP Price": 1080.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ride Designs", - "Device Description": "Ride Decaf, all sizes", - "Device Code": "SE0001045", - "Quantity": 1, - "ADP Price": 542.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ride Designs", - "Device Description": "Ride Java Back Regular/Tall Deep", - "Device Code": "SE0001143", - "Quantity": 1, - "ADP Price": 618.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ride Designs", - "Device Description": "Ride Java Back Grande", - "Device Code": "SE0001144", - "Quantity": 1, - "ADP Price": 561.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ride Designs", - "Device Description": "Ride Java Back Grande Deep", - "Device Code": "SE0001145", - "Quantity": 1, - "ADP Price": 638.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ride Designs", - "Device Description": "Ride Java Back 12\", 14\", 15\", 18\"", - "Device Code": "SE0001242", - "Quantity": 1, - "ADP Price": 542.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ride Designs", - "Device Description": "Ride Custom Back Bundle", - "Device Code": "SE0001875", - "Quantity": 1, - "ADP Price": 3041.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Ride Designs", - "Device Description": "Ride Custom Back Support", - "Device Code": "SEBR40010", - "Quantity": 1, - "ADP Price": 2254.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Roho", - "Device Description": "Agility Back Support", - "Device Code": "SE0000970", - "Quantity": 1, - "ADP Price": 636.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Roho", - "Device Description": "Agility Max Contour Back - all sizes", - "Device Code": "SE0001118", - "Quantity": 1, - "ADP Price": 822.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Roho", - "Device Description": "Agility Back - Custom Design - All Variation", - "Device Code": "SE0001167", - "Quantity": 1, - "ADP Price": 1439.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Roho", - "Device Description": "Recliner Wheelchair Cushion Made ToOrder(One Piece Back & Seat- 2 Sections,2 Valves)", - "Device Code": "SEBRO2005", - "Quantity": 1, - "ADP Price": 1035.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Roho", - "Device Description": "Recliner Wheelchair Cushion-Custom (More Than 2 Sections And/Or 2 Halves)", - "Device Code": "SEBRO2010", - "Quantity": 1, - "ADP Price": 1208.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products", - "Device Description": "ADI - AL and AFT Backrest - Active Contour, all sizes", - "Device Code": "SE0001290", - "Quantity": 1, - "ADP Price": 595.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products", - "Device Description": "ADI - AL and AFT Backrest - Deep, Contour, all sizes", - "Device Code": "SE0001291", - "Quantity": 1, - "ADP Price": 658.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products", - "Device Description": "ADI - AL and AFT Backrest - Extra Deep contour, all sizes", - "Device Code": "SE0001292", - "Quantity": 1, - "ADP Price": 721.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products", - "Device Description": "ADI - CF Backrest - Active Contour, all sizes", - "Device Code": "SE0001293", - "Quantity": 1, - "ADP Price": 774.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products", - "Device Description": "ADI - CF Backrest - Deep Contour, all sizes", - "Device Code": "SE0001294", - "Quantity": 1, - "ADP Price": 838.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products", - "Device Description": "Tarta Original (4 Vertebra) including mounting hardware and pads", - "Device Code": "SE0001504", - "Quantity": 1, - "ADP Price": 1691.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products", - "Device Description": "Tarta Original (5 Vertebra) including mounting hardware and pads", - "Device Code": "SE0001505", - "Quantity": 1, - "ADP Price": 2036.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products", - "Device Description": "Tarta Original (6 Vertebra) including mounting hardware and pads", - "Device Code": "SE0001506", - "Quantity": 1, - "ADP Price": 2346.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products", - "Device Description": "Tarta Original Central Spine (4 Vertebra up to 8 Ribs)", - "Device Code": "SE0001507", - "Quantity": 1, - "ADP Price": 773.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products", - "Device Description": "Tarta Original Central Spine (5 Vertebra up to 10 Ribs)", - "Device Code": "SE0001508", - "Quantity": 1, - "ADP Price": 963.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products", - "Device Description": "Tarta Original Central Spine (6 Vertebra up to 12 Ribs)", - "Device Code": "SE0001509", - "Quantity": 1, - "ADP Price": 1152.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth ADI Q-Back 2.0 Active (less than 16\" wide)", - "Device Code": "SE0001736", - "Quantity": 1, - "ADP Price": 680.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth ADI Q-Back 2.0 Active (16\" to 20\" wide)", - "Device Code": "SE0001737", - "Quantity": 1, - "ADP Price": 790.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth ADI Q-Back 2.0 Active (greater than 20\" wide)", - "Device Code": "SE0001738", - "Quantity": 1, - "ADP Price": 897.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth ADI Q-Back 2.0 Deep (less than 16\" wide)", - "Device Code": "SE0001739", - "Quantity": 1, - "ADP Price": 790.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth ADI Q-Back 2.0 Deep (16\" to 20\" wide)", - "Device Code": "SE0001740", - "Quantity": 1, - "ADP Price": 914.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth ADI Q-Back 2.0 Deep (greater than 20\" wide)", - "Device Code": "SE0001741", - "Quantity": 1, - "ADP Price": 1025.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth ADI Q-Back 2.0 Adjustable (less than 16\" wide)", - "Device Code": "SE0001742", - "Quantity": 1, - "ADP Price": 845.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth ADI Q-Back 2.0 Adjustable (16\" to 20\" wide)", - "Device Code": "SE0001743", - "Quantity": 1, - "ADP Price": 973.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth ADI Q-Back 2.0 Adjustable (greater than 20\" wide)", - "Device Code": "SE0001744", - "Quantity": 1, - "ADP Price": 1080.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products LLC", - "Device Description": "ADI 2.0 Back Assembly with Quick Release Pro Hardware, Shell (AL/ALFT), HR Foam Insert, any Height/Contour, and width less than or equal to 20\"", - "Device Code": "SE0002150", - "Quantity": 1, - "ADP Price": 963.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products LLC", - "Device Description": "ADI 2.0 Back Assembly with Quick Release Pro Hardware, Shell (AL/ALFT), HR Foam Insert, any Height/Contour, and width greater than 20\"", - "Device Code": "SE0002151", - "Quantity": 1, - "ADP Price": 1101.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products LLC", - "Device Description": "ADI 2.0 Back Assembly with Quick Release Pro Hardware, Shell (AL/ALFT), FRG Foam Insert, any Height/Contour, and width less than or equal to 20\"", - "Device Code": "SE0002152", - "Quantity": 1, - "ADP Price": 1032.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products LLC", - "Device Description": "ADI 2.0 Back Assembly with Quick Release Pro Hardware, Shell (AL/ALFT), FRG Foam Insert, any Height/Contour, and width greater than 20\"", - "Device Code": "SE0002153", - "Quantity": 1, - "ADP Price": 1170.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products LLC", - "Device Description": "ADI 2.0 Back Assembly with 2/4 Point Pro Hardware, Shell (AL/ALFT), HR Foam Insert, any Height/Contour, and width less than or equal to 20\"", - "Device Code": "SE0002154", - "Quantity": 1, - "ADP Price": 1032.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products LLC", - "Device Description": "ADI 2.0 Back Assembly with 2/4 Point Pro Hardware, Shell (AL/ALFT), HR Foam Insert, any Height/Contour, and width greater than 20\"", - "Device Code": "SE0002155", - "Quantity": 1, - "ADP Price": 1308.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products LLC", - "Device Description": "ADI 2.0 Back Assembly with 2/4 Point Pro Hardware, Shell (AL/ALFT), FRG Foam Insert, any Height/Contour, and width less than or equal to 20\"", - "Device Code": "SE0002156", - "Quantity": 1, - "ADP Price": 1101.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Stealth Products LLC", - "Device Description": "ADI 2.0 Back Assembly with 2/4 Point Pro Hardware, Shell (AL/ALFT), FRG", - "Device Code": "SE0002157", - "Quantity": 1, - "ADP Price": 1377.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Sunrise Medical", - "Device Description": "Sedeo Pro-Comfort Backrest 16\"w to 18\"w x 20\"h", - "Device Code": "SE0000655", - "Quantity": 1, - "ADP Price": 518.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Sunrise Medical", - "Device Description": "Sedeo Pro-Comfort Backrest 20\"w x 20\"h", - "Device Code": "SE0000656", - "Quantity": 1, - "ADP Price": 552.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Sunrise Medical", - "Device Description": "Sedeo Pro-comfort Backrest 22\"w x 20\" h", - "Device Code": "SE0000657", - "Quantity": 1, - "ADP Price": 587.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Sunrise Medical", - "Device Description": "Spex Kidz Adjustable Back Support (all sizes)", - "Device Code": "SE0001510", - "Quantity": 1, - "ADP Price": 1580.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Sunrise Medical", - "Device Description": "Spex Adjustable Back Support (14\"x16\" to 18\"x23\")", - "Device Code": "SE0001511", - "Quantity": 1, - "ADP Price": 1646.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Sunrise Medical", - "Device Description": "Spex Adjustable Back Support (20\"x18\" to 20\"x23\")", - "Device Code": "SE0001512", - "Quantity": 1, - "ADP Price": 1973.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Sunrise Medical", - "Device Description": "SuperShape KIDZ Back Support (10\"x12\" to 12\"x18\")", - "Device Code": "SE0001513", - "Quantity": 1, - "ADP Price": 2063.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Sunrise Medical", - "Device Description": "Supershape Back Support (14\"x14\" to 18\"x23\")", - "Device Code": "SE0001514", - "Quantity": 1, - "ADP Price": 2194.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Sunrise Medical", - "Device Description": "Supershape Back Support (20\"x16\" to 20\"x23\")", - "Device Code": "SE0001515", - "Quantity": 1, - "ADP Price": 2525.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Sunrise Medical", - "Device Description": "Comfi Back Support (10¿x12¿ to 18¿x23¿)", - "Device Code": "SE0001516", - "Quantity": 1, - "ADP Price": 1425.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Sunrise Medical", - "Device Description": "Comfi Back Support (20\"x18\" to 20\"x23\")", - "Device Code": "SE0001517", - "Quantity": 1, - "ADP Price": 1535.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Sunrise Medical", - "Device Description": "JAY Syncra Back (all sizes)", - "Device Code": "SE0001678", - "Quantity": 1, - "ADP Price": 863.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Sunrise Medical", - "Device Description": "Jay J3 Plus Backrest - Mid Thoracic (MT) with or without Vanity Shell Extension - All sizes", - "Device Code": "SE0001763", - "Quantity": 1, - "ADP Price": 1254.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Sunrise Medical", - "Device Description": "Jay J3 Plus Backrest - Upper Thoracic (UT) - All Sizes", - "Device Code": "SE0001764", - "Quantity": 1, - "ADP Price": 1250.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Sunrise Medical", - "Device Description": "Jay J3 Plus Backrest - Shoulder Height (SH) - All Sizes", - "Device Code": "SE0001765", - "Quantity": 1, - "ADP Price": 1361.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Sunrise Medical", - "Device Description": "Mid Thoracic Posterior Deep Jay 3 Back - Sizes 12 Height To 26 Width Sizes 15 Height To 26 Width", - "Device Code": "SEBJA8205", - "Quantity": 1, - "ADP Price": 1052.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Sunrise Medical", - "Device Description": "Upper Thoracic Posterior Deep Jay 3 Back - Sizes 18 Height To 24 Width", - "Device Code": "SEBJA8210", - "Quantity": 1, - "ADP Price": 1121.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Sunrise Medical", - "Device Description": "Shoulder Height Posterior Deep Jay 3 Back", - "Device Code": "SEBJA8215", - "Quantity": 1, - "ADP Price": 1221.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Sunrise Medical", - "Device Description": "Back Cushion 16x20,18x20, 20x20", - "Device Code": "SEBM90005", - "Quantity": 1, - "ADP Price": 169.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Sunrise Medical", - "Device Description": "Lateral Support Backrest 16x20,18x20", - "Device Code": "SEBM90010", - "Quantity": 1, - "ADP Price": 297.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Sunrise Medical", - "Device Description": "Backrest \"Plush\", Deep Or Active Contour", - "Device Code": "SEBM90020", - "Quantity": 1, - "ADP Price": 459.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Supracor", - "Device Description": "Stimulite Lumbar Support", - "Device Code": "SEBRR0010", - "Quantity": 1, - "ADP Price": 110.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Free Form Custom Low Back Kit (Small) including mount hardware", - "Device Code": "SE0001643", - "Quantity": 1, - "ADP Price": 1946.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Free Form Custom Low Back Kit (Medium) including mount hardware", - "Device Code": "SE0001644", - "Quantity": 1, - "ADP Price": 2450.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Free Form Custom Low Back Kit (Large) including mount hardware", - "Device Code": "SE0001645", - "Quantity": 1, - "ADP Price": 2967.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Free Form Custom Back Kit (Small) including mount hardware", - "Device Code": "SE0001646", - "Quantity": 1, - "ADP Price": 2967.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Free Form Custom Back Kit (Medium) including mount hardware", - "Device Code": "SE0001647", - "Quantity": 1, - "ADP Price": 3478.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Free Form Custom Back Kit (Large) including mount hardware", - "Device Code": "SE0001648", - "Quantity": 1, - "ADP Price": 3981.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Free Form Custom Back Kit (XL) with Mounting hardware & Stimulite Cover", - "Device Code": "SE0001856", - "Quantity": 1, - "ADP Price": 6793.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Free Form Custom Back Kit (XXL) with Mounting hardware & Stimulite Cover", - "Device Code": "SE0001857", - "Quantity": 1, - "ADP Price": 7493.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Respira Sport Lower Thoracic with FA Mount", - "Device Code": "SE0001955", - "Quantity": 1, - "ADP Price": 894.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Respira Sport Lower Thoracic with FA Mount Ext", - "Device Code": "SE0001956", - "Quantity": 1, - "ADP Price": 911.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Respira Sport Lower Thoracic with BA Mount", - "Device Code": "SE0001957", - "Quantity": 1, - "ADP Price": 1093.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Respira Sport Mid Thoracic with FA Mount", - "Device Code": "SE0001958", - "Quantity": 1, - "ADP Price": 894.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Respira Sport Mid Thoracic with FA Mount Ext", - "Device Code": "SE0001959", - "Quantity": 1, - "ADP Price": 911.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Respira Sport Mid Thoracic with BA Mount", - "Device Code": "SE0001960", - "Quantity": 1, - "ADP Price": 1093.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Respira Comfort Upper Thoracic with FA Mount", - "Device Code": "SE0001961", - "Quantity": 1, - "ADP Price": 825.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Respira Comfort Upper Thoracic with FA-EXT Mount", - "Device Code": "SE0001962", - "Quantity": 1, - "ADP Price": 842.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Respira Comfort Upper Thoracic with BA Mount", - "Device Code": "SE0001963", - "Quantity": 1, - "ADP Price": 1093.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Respira Comfort Upper Thoracic Deep with FA Mount", - "Device Code": "SE0001964", - "Quantity": 1, - "ADP Price": 894.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Respira Comfort Upper Thoracic Deep with FA-EXT Mount", - "Device Code": "SE0001965", - "Quantity": 1, - "ADP Price": 911.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Respira Comfort Upper Thoracic Deep with BA Mount", - "Device Code": "SE0001966", - "Quantity": 1, - "ADP Price": 1093.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Respira Comfort Mid Thoracic with FA Mount", - "Device Code": "SE0001967", - "Quantity": 1, - "ADP Price": 825.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Respira Comfort Mid Thoracic with FA-EXT Mount", - "Device Code": "SE0001968", - "Quantity": 1, - "ADP Price": 911.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Respira Comfort Mid Thoracic with BA Mount", - "Device Code": "SE0001969", - "Quantity": 1, - "ADP Price": 1024.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Respira Comfort Mid Thoracic Deep with FA Mount", - "Device Code": "SE0001970", - "Quantity": 1, - "ADP Price": 894.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Respira Comfort Mid Thoracic Deep with FA-EXT Mount", - "Device Code": "SE0001971", - "Quantity": 1, - "ADP Price": 911.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Symmetric Designs", - "Device Description": "Respira Comfort Mid Thoracic Deep with BA Mount", - "Device Code": "SE0001972", - "Quantity": 1, - "ADP Price": 1024.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "The Comfort Company", - "Device Description": "Acta Relief Back - All Variations", - "Device Code": "SE0001168", - "Quantity": 1, - "ADP Price": 877.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "The Comfort Company", - "Device Description": "COMFORT UNITE 1 BACK SUPPORT", - "Device Code": "SE0002169", - "Quantity": 1, - "ADP Price": 654.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "The Comfort Company", - "Device Description": "COMFORT UNITE 1 WING BACK SUPPORT", - "Device Code": "SE0002170", - "Quantity": 1, - "ADP Price": 859.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "The Comfort Company", - "Device Description": "COMFORT UNITE 1 LTS BACK SUPPORT", - "Device Code": "SE0002171", - "Quantity": 1, - "ADP Price": 1005.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "The Comfort Company", - "Device Description": "COMFORT UNITE 2 BACK SUPPORT", - "Device Code": "SE0002172", - "Quantity": 1, - "ADP Price": 764.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "The Comfort Company", - "Device Description": "COMFORT UNITE 3 BACK SUPPORT", - "Device Code": "SE0002173", - "Quantity": 1, - "ADP Price": 888.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "The Comfort Company", - "Device Description": "Comfort Relief Back Support", - "Device Code": "SE0002191", - "Quantity": 1, - "ADP Price": 917.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "The Comfort Company", - "Device Description": "Comfort Relief LTS Back Support", - "Device Code": "SE0002192", - "Quantity": 1, - "ADP Price": 1250.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "The Comfort Company", - "Device Description": "Comfort Embrace Back Support", - "Device Code": "SE0002193", - "Quantity": 1, - "ADP Price": 758.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "The Comfort Company", - "Device Description": "Comfort Embrace LTS Back Support", - "Device Code": "SE0002194", - "Quantity": 1, - "ADP Price": 1102.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "The Comfort Company", - "Device Description": "COMFORT EMBRACE BACK SUPPORT, width 22 inches or greater", - "Device Code": "SE0002359", - "Quantity": 1, - "ADP Price": 978.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "The Comfort Company", - "Device Description": "COMFORT EMBRACE LTS BACK SUPPORT, width 22 inches or greater", - "Device Code": "SE0002360", - "Quantity": 1, - "ADP Price": 1316.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "The Comfort Company", - "Device Description": "COMFORT UNITE 1 BACK SUPPORT, width 22 inches or greater", - "Device Code": "SE0002361", - "Quantity": 1, - "ADP Price": 843.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "The Comfort Company", - "Device Description": "COMFORT UNITE 1 WING BACK SUPPORT, width 22 inches or greater", - "Device Code": "SE0002362", - "Quantity": 1, - "ADP Price": 2093.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "The Comfort Company", - "Device Description": "COMFORT UNITE 1 LTS BACK SUPPORT, width 22 inches or greater", - "Device Code": "SE0002363", - "Quantity": 1, - "ADP Price": 1212.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "The Comfort Company", - "Device Description": "COMFORT UNITE 2 BACK SUPPORT, width 22 inches or greater", - "Device Code": "SE0002364", - "Quantity": 1, - "ADP Price": 971.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "The Comfort Company", - "Device Description": "COMFORT UNITE 3 BACK SUPPORT, width 22 inches or greater", - "Device Code": "SE0002365", - "Quantity": 1, - "ADP Price": 1078.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "The Comfort Company", - "Device Description": "Acta-Back, All Variations, All Sizes", - "Device Code": "SEB7C0010", - "Quantity": 1, - "ADP Price": 650.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "The Comfort Company", - "Device Description": "Acta-Back, All Variations, Custom Sizes", - "Device Code": "SEB7C0015", - "Quantity": 1, - "ADP Price": 1155.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "The Comfort Company", - "Device Description": "Incrediback, Moldable, Tall, Deep,Tall-Deep,All Sizes", - "Device Code": "SEB7C0020", - "Quantity": 1, - "ADP Price": 644.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "The Comfort Company", - "Device Description": "Incrediback, Modable, Tall, Deep, Tall-Deep,Custom Sizes", - "Device Code": "SEB7C0025", - "Quantity": 1, - "ADP Price": 1311.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Varilite Medical Products", - "Device Description": "Junior Backs", - "Device Code": "SE0001147", - "Quantity": 1, - "ADP Price": 643.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Varilite Medical Products", - "Device Description": "Icon Back - Low", - "Device Code": "SEBVP0100", - "Quantity": 1, - "ADP Price": 618.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Varilite Medical Products", - "Device Description": "Icon Back -Mid", - "Device Code": "SEBVP0105", - "Quantity": 1, - "ADP Price": 643.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Varilite Medical Products", - "Device Description": "Icon Back - Deep", - "Device Code": "SEBVP0115", - "Quantity": 1, - "ADP Price": 884.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Varilite Medical Products", - "Device Description": "Icon Back - Bariatric", - "Device Code": "SEBVP0120", - "Quantity": 1, - "ADP Price": 965.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Varilite Medical Products", - "Device Description": "Icon Back - Tall", - "Device Code": "SEBVP1110", - "Quantity": 1, - "ADP Price": 724.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "Viva Contoured Postural Back14\"-16\" W/C Or 16\"-18\" W/C", - "Device Code": "SEBVC0015", - "Quantity": 1, - "ADP Price": 198.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "Viscount Tall Back Support For 16' Or 18\" W/C", - "Device Code": "SEBVC0030", - "Quantity": 1, - "ADP Price": 1036.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "Viscount Tall Back Support, Custom Sizes", - "Device Code": "SEBVC0035", - "Quantity": 1, - "ADP Price": 1308.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support Options", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Custom Modifications And Sizing -Including Custom Sizes,Additional Postural Support - LumbarPad, Foam Pads Etc.(Maximum 6)", - "Device Code": "SEBND0015", - "Quantity": 6, - "ADP Price": 47.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support Options", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Additional Pressure Relief - Gel/AirInserts/Pads Etc.(Maximum 6)", - "Device Code": "SEBND0020", - "Quantity": 6, - "ADP Price": 116.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Modify Or Refurbish Existing CustomFabricated Back,Includes Parts, Hardware & Labour", - "Device Code": "SEMCF200L", - "Quantity": 1, - "ADP Price": 194.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Back Channeling - Upgrade For Slots For Lateral Adjustments", - "Device Code": "SEMCF201L", - "Quantity": 1, - "ADP Price": 129.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Back Reinforcement - Heavy Duty Upgrade", - "Device Code": "SEMCF202L", - "Quantity": 1, - "ADP Price": 86.0, - "SN Required": "No" - }, - { - "Device Type": "Back Support Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Back Plaster Molding/Vacuum Form, for Custom Fabricated Device Only", - "Device Code": "SEUCF003L", - "Quantity": 1, - "ADP Price": 138.0, - "SN Required": "No" - }, - { - "Device Type": "Caster Pin Locks (pair)", - "Manufacturer": "THOMASHILFEN", - "Device Description": "Caster Pin Locks (pair)", - "Device Code": "WAMS", - "Quantity": 1, - "ADP Price": 135.0, - "SN Required": "No" - }, - { - "Device Type": "Clothing Guards", - "Manufacturer": "THOMASHILFEN", - "Device Description": "Clothing Guards", - "Device Code": "WAMV", - "Quantity": 1, - "ADP Price": 99.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Basis Seat & Back Including Connecting Hinge (Select Type). Does Not Include Mounting Hardware.", - "Device Code": "SEC2L0005", - "Quantity": 1, - "ADP Price": 511.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Basis Contoured Seat & Back IncludingConnecting Hinge(Select Type). Does Not Include Mounting Hardware.", - "Device Code": "SEC2L0010", - "Quantity": 1, - "ADP Price": 742.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Basis Seat & Back Including Connecting Hinge Package. Li'L Kiddos,14\" Wide Or Less. Does Not Include Mounting Hardware.", - "Device Code": "SEC2L0015", - "Quantity": 1, - "ADP Price": 595.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Basis Contoured Seat & Back IncludingConnecting HingePackage. Li'L Kiddos,14\" Wide Or Less.Does Not IncludeMounting Hardware.", - "Device Code": "SEC2L0020", - "Quantity": 1, - "ADP Price": 897.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Amylior Inc.", - "Device Description": "Bariatric Power Recline With Integrated Shear Reduction (Isr)", - "Device Code": "SEC4P0065", - "Quantity": 1, - "ADP Price": 6999.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Broda", - "Device Description": "Hsp Padding Package(Includes Short Wing Cover, ExtendedShoulder Bolsters,Full Extension Foot Pad, F-2 Foot Rest, Thigh Belt)", - "Device Code": "SECB-0005", - "Quantity": 1, - "ADP Price": 486.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Custom Fabricated", - "Device Description": "Modify Or Refurbish Existing CustomSeating System.Includes Parts,Hardware,Labour Changes To Head Rest,Back Support,Seat, & Footrest Etc.", - "Device Code": "SEMCF900L", - "Quantity": 1, - "ADP Price": 431.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Hoggi", - "Device Description": "Adjustible Height Back System Planar Back Cushion", - "Device Code": "SE0000467", - "Quantity": 1, - "ADP Price": 272.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Hoggi", - "Device Description": "Configurable Adjustible Height I Back System", - "Device Code": "SE0000468", - "Quantity": 1, - "ADP Price": 272.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Hoggi", - "Device Description": "Bingo Ius Or Xps Seat Frame Size 1", - "Device Code": "SECK20005", - "Quantity": 1, - "ADP Price": 1352.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Hoggi", - "Device Description": "Bingo Ius Or Xps Seat Frame Size 2", - "Device Code": "SECK20010", - "Quantity": 1, - "ADP Price": 1373.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Hoggi", - "Device Description": "Ius Adaptive Seat And Back Cushions - Breathable", - "Device Code": "SECK20100", - "Quantity": 1, - "ADP Price": 224.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Hoggi", - "Device Description": "Ius Adaptive Seat And Back CushionsWith Airflex", - "Device Code": "SECK20105", - "Quantity": 1, - "ADP Price": 607.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Kid Kart", - "Device Description": "Xpress Adjustable Contour Seating Package", - "Device Code": "SECKT3005", - "Quantity": 1, - "ADP Price": 773.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Kid Kart", - "Device Description": "Xpress Shell Assembly With Planar Seating", - "Device Code": "SECKT3010", - "Quantity": 1, - "ADP Price": 555.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Kid Kart", - "Device Description": "Xpress Shell Assembly With Contour Seating", - "Device Code": "SECKT3015", - "Quantity": 1, - "ADP Price": 773.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Otto Bock", - "Device Description": "OBSS Ortho-Shape", - "Device Code": "SE0001046", - "Quantity": 1, - "ADP Price": 3723.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "R82", - "Device Description": "XPanda Seating System", - "Device Code": "SE0001947", - "Quantity": 1, - "ADP Price": 2491.48, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Sunrise Medical", - "Device Description": "Squiggle Seating System", - "Device Code": "SE0000701", - "Quantity": 1, - "ADP Price": 1477.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Sunrise Medical", - "Device Description": "Wonderseat Bounce (Size 0/1) with Constructa cushion, growth-adjust back support, drop mount hardware and Spex seat base with quick release. Includes hardware and support for head, trunk, arm, and thigh, harness for shoulder and hip belt.", - "Device Code": "SE0002145", - "Quantity": 1, - "ADP Price": 4555.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Sunrise Medical", - "Device Description": "Wonderseat Space (Size 0/1) with Constructa cushion, growth-adjust back support, drop mount hardware and Spex seat base with quick release. Includes hardware and support for head, trunk, arm, and thigh, harness for shoulder and hip belt.", - "Device Code": "SE0002146", - "Quantity": 1, - "ADP Price": 5175.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Sunrise Medical", - "Device Description": "Mygo Seat Shell Size 1Includes Seat Shell And Cushions", - "Device Code": "SECOB4015", - "Quantity": 1, - "ADP Price": 1559.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Sunrise Medical", - "Device Description": "Mygo Seat Shell Size 2Includes Seat Shell Cushions And Shoulder Support", - "Device Code": "SECOB4020", - "Quantity": 1, - "ADP Price": 1793.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Symmetric Designs", - "Device Description": "Free Form Full Body FIT Kit (includes basic headrest, mounting hardware and universal mounting plate)", - "Device Code": "SE0001604", - "Quantity": 1, - "ADP Price": 6519.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "Symmetric Designs", - "Device Description": "Free Form Full Body FIT Kit (includes basic headrest, mounting hardware, universal mounting plate and rotary interface)", - "Device Code": "SE0001618", - "Quantity": 1, - "ADP Price": 6921.0, - "SN Required": "No" - }, - { - "Device Type": "Complete Assembly", - "Manufacturer": "THOMASHILFEN", - "Device Description": "EasyS or EasyS Modular", - "Device Code": "SE0001026", - "Quantity": 1, - "ADP Price": 1377.0, - "SN Required": "No" - }, - { - "Device Type": "Elevating Legrests (pair)", - "Manufacturer": "THOMASHILFEN", - "Device Description": "Elevating Legrests (pair)", - "Device Code": "WAMK", - "Quantity": 1, - "ADP Price": 318.0, - "SN Required": "No" - }, - { - "Device Type": "Foot/Leg Support Hardware", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Complex Specialized Mounting Hardware", - "Device Code": "SEFND0030", - "Quantity": 2, - "ADP Price": 86.0, - "SN Required": "No" - }, - { - "Device Type": "Foot/Leg Support Hardware", - "Manufacturer": "Custom Fabricated", - "Device Description": "Mount Footrest To Seating System", - "Device Code": "SEICF501L", - "Quantity": 2, - "ADP Price": 104.0, - "SN Required": "No" - }, - { - "Device Type": "Foot/Leg Support Options", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Extra Padding For Specific Pressure Relief - (Maximum 2)", - "Device Code": "SEFND0035", - "Quantity": 2, - "ADP Price": 43.0, - "SN Required": "No" - }, - { - "Device Type": "Foot/Leg Support Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Footrest Extension, Not Padded (Maximum 2)", - "Device Code": "SE0000322", - "Quantity": 2, - "ADP Price": 65.0, - "SN Required": "No" - }, - { - "Device Type": "Foot/Leg Support Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Footrest Discrepancy Upcharge - Accommodates Differences Between Left & Right Leg", - "Device Code": "SEMCF801L", - "Quantity": 1, - "ADP Price": 69.0, - "SN Required": "No" - }, - { - "Device Type": "Foot/Leg Support Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Footrest Reinforcement Upcharge -Heavy DutyUpgrade To Reinforce Footrest", - "Device Code": "SEMCF802L", - "Quantity": 2, - "ADP Price": 121.0, - "SN Required": "No" - }, - { - "Device Type": "Foot/Leg Support Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Footrest Padding (Maximum2)", - "Device Code": "SEMCF803L", - "Quantity": 2, - "ADP Price": 52.0, - "SN Required": "No" - }, - { - "Device Type": "Foot/Leg Support(s)", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Amputee Board/Stump Support - Includes Mounting Hardware & Padding", - "Device Code": "SEFND0005", - "Quantity": 1, - "ADP Price": 246.0, - "SN Required": "No" - }, - { - "Device Type": "Foot/Leg Support(s)", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Calf Panel - Includes Mounting Hardware & Padding", - "Device Code": "SEFND0010", - "Quantity": 2, - "ADP Price": 43.0, - "SN Required": "No" - }, - { - "Device Type": "Foot/Leg Support(s)", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "1 Piece Foot Board - IncludesMountingHardware & Padding", - "Device Code": "SEFND0015", - "Quantity": 1, - "ADP Price": 95.0, - "SN Required": "No" - }, - { - "Device Type": "Foot/Leg Support(s)", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Foot Box - Includes MountingHardware & Padding -Foot Box May Be 1 Piece Or 2 Piece (Each Foot)", - "Device Code": "SEFND0020", - "Quantity": 2, - "ADP Price": 207.0, - "SN Required": "No" - }, - { - "Device Type": "Foot/Leg Support(s)", - "Manufacturer": "Custom Fabricated", - "Device Description": "One Piece Fixed Footrest,Not Padded", - "Device Code": "SEFCF101L", - "Quantity": 1, - "ADP Price": 129.0, - "SN Required": "No" - }, - { - "Device Type": "Foot/Leg Support(s)", - "Manufacturer": "Custom Fabricated", - "Device Description": "Complex Foot Rest (One Or TwoPiece),Includes Parts, Hardware, And Labour", - "Device Code": "SEFCF102L", - "Quantity": 1, - "ADP Price": 380.0, - "SN Required": "No" - }, - { - "Device Type": "Foot/Leg Support(s)", - "Manufacturer": "Custom Fabricated", - "Device Description": "One Piece Double Footbox, Not Padded", - "Device Code": "SEFCF103L", - "Quantity": 1, - "ADP Price": 256.0, - "SN Required": "No" - }, - { - "Device Type": "Foot/Leg Support(s)", - "Manufacturer": "Custom Fabricated", - "Device Description": "Footpocket, Not Padded ( Maximum 2)", - "Device Code": "SEFCF106L", - "Quantity": 2, - "ADP Price": 173.0, - "SN Required": "No" - }, - { - "Device Type": "Foot/Leg Support(s)", - "Manufacturer": "Custom Fabricated", - "Device Description": "Calf Support, Padded And Removable", - "Device Code": "SEFCF107L", - "Quantity": 2, - "ADP Price": 168.0, - "SN Required": "No" - }, - { - "Device Type": "Forearm Crutches", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Forearm Crutches", - "Device Code": "MKZND0005", - "Quantity": 1, - "ADP Price": 121.0, - "SN Required": "Yes" - }, - { - "Device Type": "Grade Aids (pair)", - "Manufacturer": "THOMASHILFEN", - "Device Description": "Grade Aids (pair)", - "Device Code": "WAMR", - "Quantity": 1, - "ADP Price": 91.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Curved Hr Pad Or Contoured Hr PadOr Bell Curved Hr Pad,Cobra Headrest Bracket.", - "Device Code": "SEH2L0030", - "Quantity": 1, - "ADP Price": 381.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Curved Hr Pad Or Contoured Hr PadOr Bell Curved Hr Pad,Cobra Headrest Bracket, Flip-Down.", - "Device Code": "SEH2L0035", - "Quantity": 1, - "ADP Price": 455.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "STA-RITE Adjustable Forehead Stabilizer", - "Device Code": "SE0001745", - "Quantity": 1, - "ADP Price": 342.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "STA-RITE Gel Headrest Pad (1\" Ball Clamp M/A Adapter, 5X10\")", - "Device Code": "SE0001757", - "Quantity": 1, - "ADP Price": 193.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "STA-RITE Gel Headrest Pad (1\" Ball Clamp M/A Adapter, 5X12\")", - "Device Code": "SE0001758", - "Quantity": 1, - "ADP Price": 199.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "STA-RITE Gel Headrest Pad (1\" Ball Clamp M/A Adapter, 5X14\")", - "Device Code": "SE0001759", - "Quantity": 1, - "ADP Price": 206.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "STA-RITE Gel Headrest Pad (1\" Ball Clamp M/A Adapter, 5X10\") with Adjustable Forehead Stabilizer", - "Device Code": "SE0001760", - "Quantity": 1, - "ADP Price": 534.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "STA-RITE Gel Headrest Pad (1\" Ball Clamp M/A Adapter, 5X12\") with Adjustable Forehead Stabilizer", - "Device Code": "SE0001761", - "Quantity": 1, - "ADP Price": 541.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "STA-RITE Gel Headrest Pad (1\" Ball Clamp M/A Adapter, 5X14\") with Adjustable Forehead Stabilizer", - "Device Code": "SE0001762", - "Quantity": 1, - "ADP Price": 548.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "SO SOFT Oval Headrest Small with Multi-axis Adapter and zippered cover", - "Device Code": "SE0001821", - "Quantity": 1, - "ADP Price": 172.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "SO SOFT Oval Headrest Large with Multi-axis Adapter and zippered cover", - "Device Code": "SE0001822", - "Quantity": 1, - "ADP Price": 182.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "SO SOFT Oval Headrest Extended with Multi-axis Adapter and zippered cover", - "Device Code": "SE0001823", - "Quantity": 1, - "ADP Price": 199.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "SO SOFT Oval Headrest Large Extended with Multi-axis Adapter and zippered cover", - "Device Code": "SE0001824", - "Quantity": 1, - "ADP Price": 199.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "SO SOFT Quad Headrest with Multi-axis Adapter and zippered cover", - "Device Code": "SE0001825", - "Quantity": 1, - "ADP Price": 182.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "SO SOFT Deep U Headrest with Multi- axis Adapter and zippered cover", - "Device Code": "SE0001826", - "Quantity": 1, - "ADP Price": 182.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "SO SOFT Oxbow Headrest with Multi-axis Adapter and zippered cover", - "Device Code": "SE0001827", - "Quantity": 1, - "ADP Price": 182.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "SO SOFT Large Oxbow Headrest with Multi-axis Adapter and zippered cover", - "Device Code": "SE0001828", - "Quantity": 1, - "ADP Price": 273.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "Standard Curved Padded Headrest with Multi-axis Adapter and zippered cover", - "Device Code": "SE0001829", - "Quantity": 1, - "ADP Price": 137.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "Large Padded Headrest with Multi-axis Adapter and zippered cover", - "Device Code": "SE0001830", - "Quantity": 1, - "ADP Price": 190.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "Standard Curved Padded Headrest", - "Device Code": "SEHAO0005", - "Quantity": 1, - "ADP Price": 100.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "Macintosh Oxbow Headrest", - "Device Code": "SEHAO0010", - "Quantity": 1, - "ADP Price": 173.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "Custom Headrest", - "Device Code": "SEHAO0015", - "Quantity": 1, - "ADP Price": 173.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "Deep \"U\" Headrest", - "Device Code": "SEHAO0020", - "Quantity": 1, - "ADP Price": 135.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "Large Padded Headrest", - "Device Code": "SEHAO0025", - "Quantity": 1, - "ADP Price": 100.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "So Soft Oval Headrest", - "Device Code": "SEHAO0030", - "Quantity": 1, - "ADP Price": 135.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Amylior Inc.", - "Device Description": "Curved Headrest, All Sizes", - "Device Code": "SEH4P0010", - "Quantity": 1, - "ADP Price": 161.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Blake Medical", - "Device Description": "Geo-Matrix Headrest Pad (Curve)", - "Device Code": "SE0001533", - "Quantity": 1, - "ADP Price": 147.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Blake Medical", - "Device Description": "Geo-Matrix Headrest Pad (Sweet Spot)", - "Device Code": "SE0001534", - "Quantity": 1, - "ADP Price": 150.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Blake Medical", - "Device Description": "Geo-Matrix Headrest Pad (Flat)", - "Device Code": "SE0001535", - "Quantity": 1, - "ADP Price": 155.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Blake Medical", - "Device Description": "Geo-Matrix Headrest Pad (Custom Removable)", - "Device Code": "SE0001536", - "Quantity": 1, - "ADP Price": 178.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Broda", - "Device Description": "APP Head Support (For 16\", 18\" and 20\" Seat Width)", - "Device Code": "SE0001885", - "Quantity": 1, - "ADP Price": 85.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Broda", - "Device Description": "APP Head Support (For 22\" and 24\" Seat Width)", - "Device Code": "SE0001886", - "Quantity": 1, - "ADP Price": 93.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Broda", - "Device Description": "APP Head Support (For 26\" and 28\" Seat Width)", - "Device Code": "SE0001887", - "Quantity": 1, - "ADP Price": 100.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Broda", - "Device Description": "Neckrest Cushion", - "Device Code": "SEHB-0010", - "Quantity": 1, - "ADP Price": 41.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Custom Fabricated", - "Device Description": "Flat Headrest/Planar Head Support,Vinyl Cover,Without Hardware", - "Device Code": "SEHCF040L", - "Quantity": 1, - "ADP Price": 108.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Custom Fabricated", - "Device Description": "Contoured Headrest/Curved Surface,Vinyl Cover,Without Hardware", - "Device Code": "SEHCF050L", - "Quantity": 1, - "ADP Price": 173.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Custom Fabricated", - "Device Description": "Complex Headrest/Contoured OrMolded, Vinyl Cover,Without Hardware", - "Device Code": "SEHCF060L", - "Quantity": 1, - "ADP Price": 267.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Custom Fabricated", - "Device Description": "Neckrest With Vinyl Cover, Without Hardware", - "Device Code": "SEHCF070L", - "Quantity": 1, - "ADP Price": 164.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Custom Fabricated", - "Device Description": "Adjustable Headrest With Neckrest,Vinyl Cover,Without Hardware", - "Device Code": "SEHCF080L", - "Quantity": 1, - "ADP Price": 362.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Custom Fabricated", - "Device Description": "Head Or Neckrest Incorporated WithMobility Switches,Vinyl Cover, Without Hardware", - "Device Code": "SEHCF090L", - "Quantity": 1, - "ADP Price": 267.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "NXT MultiFit Head Support Pad Selection", - "Device Code": "SE0001131", - "Quantity": 1, - "ADP Price": 155.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Future Mobility", - "Device Description": "Large Padded Headrest", - "Device Code": "SEHFM0005", - "Quantity": 1, - "ADP Price": 190.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Future Mobility", - "Device Description": "Small Padded Headrest", - "Device Code": "SEHFM0010", - "Quantity": 1, - "ADP Price": 186.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Future Mobility", - "Device Description": "Large Headrest With Multi-Axial Hardware", - "Device Code": "SEHFM0015", - "Quantity": 1, - "ADP Price": 245.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Future Mobility", - "Device Description": "Small Headrest With Multi-Axial Hardware", - "Device Code": "SEHFM0020", - "Quantity": 1, - "ADP Price": 242.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Hoggi", - "Device Description": "Ius Headrest", - "Device Code": "SEHK20005", - "Quantity": 1, - "ADP Price": 248.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Elan Standard Headrest Pad with removable cover - 6\" x 3.5\", 10\" x5\" or 14\" x 5\"", - "Device Code": "SE0001320", - "Quantity": 1, - "ADP Price": 310.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Elan Standard Headrest Pad with removable Infection Control cover - 6\" x 3.5\", 10\" x 5\" or 14\" x 5\"", - "Device Code": "SE0001321", - "Quantity": 1, - "ADP Price": 335.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Elan Occipital Headrest Pad with removable cover - 9\" x 7\" or 12\"x 8\"", - "Device Code": "SE0001322", - "Quantity": 1, - "ADP Price": 341.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Elan Occipital Headrest Pad w/ removable Infection Control cover 9\" x 7\" or 12\" x 8\"", - "Device Code": "SE0001323", - "Quantity": 1, - "ADP Price": 366.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Elan 4 Point Headrest Pad with standard removable cover", - "Device Code": "SE0001324", - "Quantity": 1, - "ADP Price": 448.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Elan 4 Point Headrest Pad (w/ Infection Control) with removable cover", - "Device Code": "SE0001325", - "Quantity": 1, - "ADP Price": 473.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Jay Medical", - "Device Description": "Single Pad Headrest - Small", - "Device Code": "SEHJA0005", - "Quantity": 1, - "ADP Price": 72.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Jay Medical", - "Device Description": "Single Pad Headrest - Large", - "Device Code": "SEHJA0006", - "Quantity": 1, - "ADP Price": 72.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Jay Medical", - "Device Description": "Three Pad Headrest - Small", - "Device Code": "SEHJA0010", - "Quantity": 1, - "ADP Price": 181.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Jay Medical", - "Device Description": "Three Pad Headrest - Large", - "Device Code": "SEHJA0011", - "Quantity": 1, - "ADP Price": 181.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Jay Medical", - "Device Description": "Three Pad Headrest - Large Junior", - "Device Code": "SEHJA0013", - "Quantity": 1, - "ADP Price": 181.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Jay Medical", - "Device Description": "Four Pad Rotational Headrest - Standard", - "Device Code": "SEHJA0017", - "Quantity": 1, - "ADP Price": 380.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Jay Medical", - "Device Description": "Full Width Headrest", - "Device Code": "SEHJA0020", - "Quantity": 1, - "ADP Price": 127.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Jay Medical", - "Device Description": "Three Pad Rotational Headrest - Small", - "Device Code": "SEHJA0026", - "Quantity": 1, - "ADP Price": 304.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Jay Medical", - "Device Description": "Three Pad Rotational Headrest - Large", - "Device Code": "SEHJA0027", - "Quantity": 1, - "ADP Price": 304.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Kid Kart", - "Device Description": "Xpress Tri-Wing Adjustable Head Support", - "Device Code": "SEHKT3005", - "Quantity": 1, - "ADP Price": 107.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Kid Kart", - "Device Description": "Xpress Micro Adjustable Head Support", - "Device Code": "SEHKT3010", - "Quantity": 1, - "ADP Price": 211.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Kid Kart", - "Device Description": "Xpress Planar Head Support", - "Device Code": "SEHKT3015", - "Quantity": 1, - "ADP Price": 138.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Ki Mobility", - "Device Description": "Headrest Support (Size 1 & 2)", - "Device Code": "SEHOB6005", - "Quantity": 1, - "ADP Price": 247.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Ki Mobility", - "Device Description": "Contoured Headrest (Size 1 & 2)", - "Device Code": "SEHOB6010", - "Quantity": 1, - "ADP Price": 138.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Ki Mobility", - "Device Description": "Fixed Wing Headrest (Size 1 & 2)", - "Device Code": "SEHOB6015", - "Quantity": 1, - "ADP Price": 342.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Ki Mobility", - "Device Description": "Adjustable Wing Headrest (Size 1 & 2)", - "Device Code": "SEHOB6020", - "Quantity": 1, - "ADP Price": 485.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Lpa Medical Inc.", - "Device Description": "Cervical Support", - "Device Code": "SEHO12005", - "Quantity": 1, - "ADP Price": 36.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Lpa Medical Inc.", - "Device Description": "Contour Headrest", - "Device Code": "SEHO12010", - "Quantity": 1, - "ADP Price": 86.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "ML Contour", - "Device Code": "SE0001133", - "Quantity": 1, - "ADP Price": 179.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "ML Adapt Headrest - includes Adjustable Pad, Multi-Axis Hardware and Mounting Bracket", - "Device Code": "SE0002090", - "Quantity": 1, - "ADP Price": 345.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "ML Multi-Axis Headrest - includes Contour Pad, Multi-Axis Hardware and Mounting Bracket", - "Device Code": "SE0002091", - "Quantity": 1, - "ADP Price": 345.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Motion Concepts", - "Device Description": "Snug Adjustable headrest 14\" and 18\"", - "Device Code": "SE0002176", - "Quantity": 1, - "ADP Price": 431.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Motion Concepts", - "Device Description": "Snug Adjustable Headrest 14\" and 18\" Asymmetrical", - "Device Code": "SE0002177", - "Quantity": 1, - "ADP Price": 445.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Motion Concepts", - "Device Description": "Snug Adjustable Headrest 14\" and 18\" Infection Control", - "Device Code": "SE0002178", - "Quantity": 1, - "ADP Price": 459.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Motion Concepts", - "Device Description": "Snug Adjustable Headrest 14\" and 18\" Asymmetrical Infection Control", - "Device Code": "SE0002179", - "Quantity": 1, - "ADP Price": 473.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Motion Concepts", - "Device Description": "Onyx Auto Style Headrest", - "Device Code": "SEHZG0005", - "Quantity": 1, - "ADP Price": 161.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Otto Bock", - "Device Description": "X-Style Headrest/Neckrest Combination, Adult & Paediatric Sizes.", - "Device Code": "SEHOB0015", - "Quantity": 1, - "ADP Price": 108.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Otto Bock", - "Device Description": "Headrest - Large/Small", - "Device Code": "SEHOB0100", - "Quantity": 1, - "ADP Price": 72.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Permobil", - "Device Description": "Headrest - For Ergo Back", - "Device Code": "SEH1P0005", - "Quantity": 1, - "ADP Price": 405.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Physipro", - "Device Description": "Headrest", - "Device Code": "SE0001073", - "Quantity": 1, - "ADP Price": 147.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Physipro", - "Device Description": "Symbio Headrest Support with Standard Pad 7\" x 4\", 8\" x 5\", 9\" x 6\"", - "Device Code": "SE0001787", - "Quantity": 1, - "ADP Price": 459.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Physipro", - "Device Description": "Symbio Headrest Support with Head Neck Pad 6\" x 4.5\", 7\" x 5\", 8\" x 6\"", - "Device Code": "SE0001800", - "Quantity": 1, - "ADP Price": 500.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Physipro", - "Device Description": "Symbio Headrest Support with Integrated Adjustable Lateral Control Pad 5\" x 4.5\", 6\" x 6.25\"", - "Device Code": "SE0001801", - "Quantity": 1, - "ADP Price": 674.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Physipro", - "Device Description": "Symbio Headrest Support with Adjustable Lateral Pad 6\" x 4\", 7\" x 5\", 8\" x 6\" (Left or Right Extension)", - "Device Code": "SE0001802", - "Quantity": 1, - "ADP Price": 600.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Physipro", - "Device Description": "Symbio Headrest Support with Adjustable Lateral Pad 6\" x 4\", 7\" x 5\",8\" x 6\" (Double Extension)", - "Device Code": "SE0001803", - "Quantity": 1, - "ADP Price": 613.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Positech Innovation Inc.", - "Device Description": "SUMMUS (all sizes) including hardware (support holder and fastener)", - "Device Code": "SE0001446", - "Quantity": 1, - "ADP Price": 500.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Relax Multi-Axis Headrest System", - "Device Code": "SE0001542", - "Quantity": 1, - "ADP Price": 449.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Contour Headrest Including Brackets", - "Device Code": "SEHWM0005", - "Quantity": 1, - "ADP Price": 221.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Precision Rehab Manufacturing Inc.", - "Device Description": "Headreast - Large (14\") Or Small (10\") Pad", - "Device Code": "SEHWB0010", - "Quantity": 1, - "ADP Price": 104.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Pad - All Positioning Head Pad - 13\"x8\", 9\"x6.5\", 8\"x6.25\", 7\"x6\"", - "Device Code": "SE0001994", - "Quantity": 1, - "ADP Price": 177.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Pad - Comfort Plus Head Pad- 14\"x6\", 10\"x6\", 8\"x6\", 6\"x4\"", - "Device Code": "SE0001995", - "Quantity": 1, - "ADP Price": 193.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Pad - Adjustable Comfort Plus Head Pad - 14\"x5\"", - "Device Code": "SE0001996", - "Quantity": 1, - "ADP Price": 382.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest - Adjustable Comfort Plus Head Pad - 19\"x5\"", - "Device Code": "SE0001997", - "Quantity": 1, - "ADP Price": 474.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Pad - Combo Head Pad - All Sizes", - "Device Code": "SE0001998", - "Quantity": 1, - "ADP Price": 342.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Pad - i2i Adjustable Foam Head Pad (Small/Medium/Large/Extra Large - Low/Standard Profile - Standard/Short Arm - Any Size)", - "Device Code": "SE0001999", - "Quantity": 1, - "ADP Price": 428.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Pad - i2i Fix Foam Head Pad (Extra Small Nino/Small Nino/Small/Medium/Large/Extra Large - Low/Standard Profile - Standard/Short Arm - Any Size)", - "Device Code": "SE0002000", - "Quantity": 1, - "ADP Price": 404.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Pad - i2i Adjustable Gel Head Pad (Small/Medium/Large/Extra Large - Low/Standard Profile - Standard/Short Arm - Any Size)", - "Device Code": "SE0002001", - "Quantity": 1, - "ADP Price": 638.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Pad - i2i Fixed Gel Head Pad (Extra Small Nino/Small Nino/Small/Medium/Large/Extra Large - Low/Standard Profile - Standard/Short Arm - Any Size)", - "Device Code": "SE0002002", - "Quantity": 1, - "ADP Price": 613.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Pad - OB Contoured 9\"x3.5\" Head Pad", - "Device Code": "SE0002003", - "Quantity": 1, - "ADP Price": 72.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Pad - OB Contoured 9\"x5.5\" Head Pad", - "Device Code": "SE0002004", - "Quantity": 1, - "ADP Price": 88.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Pad - Tri-Comfort Head Pad (19\"x6\", 14\"x6\", 10\"x6\", 8\"x6\", 6\"x4\")", - "Device Code": "SE0002005", - "Quantity": 1, - "ADP Price": 190.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Pad - Occipital/Sub-Occipital Head Pad (Standard/Flat/Curved - All Sizes)", - "Device Code": "SE0002006", - "Quantity": 1, - "ADP Price": 66.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "Sedeo Pro small headrest pad", - "Device Code": "SE0000664", - "Quantity": 1, - "ADP Price": 69.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "Sedeo Pro Flexible Headrest Pad", - "Device Code": "SE0000665", - "Quantity": 1, - "ADP Price": 93.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "Sedeo Pro Large Headrest Pad", - "Device Code": "SE0000666", - "Quantity": 1, - "ADP Price": 100.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "SEDEO Pad Small (w/ cover)", - "Device Code": "SE0001679", - "Quantity": 1, - "ADP Price": 179.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "SEDEO Pad Small (w/ cover including Multi-Position Headrest Mount)", - "Device Code": "SE0001680", - "Quantity": 1, - "ADP Price": 386.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "SEDEO Pad Flexible", - "Device Code": "SE0001681", - "Quantity": 1, - "ADP Price": 221.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "SEDEO Pad Flexible (including Multi-Position Headrest Mount)", - "Device Code": "SE0001682", - "Quantity": 1, - "ADP Price": 428.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "Plush Headrest (all sizes)", - "Device Code": "SE0001683", - "Quantity": 1, - "ADP Price": 230.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "Adjust-A-Plush Headrest (all sizes)", - "Device Code": "SE0001684", - "Quantity": 1, - "ADP Price": 267.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "SPEX Square Headrest Pad, Small", - "Device Code": "SE0001839", - "Quantity": 1, - "ADP Price": 159.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "SPEX Square Headrest Pad, Large", - "Device Code": "SE0001840", - "Quantity": 1, - "ADP Price": 159.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "SPEX Comfi Headrest Pad, Standard", - "Device Code": "SE0001841", - "Quantity": 1, - "ADP Price": 276.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "SPEX Comfi Headrest Pad, Extended", - "Device Code": "SE0001842", - "Quantity": 1, - "ADP Price": 314.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "Spex Contoured Headrest Pad, Small", - "Device Code": "SE0001843", - "Quantity": 1, - "ADP Price": 159.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "Spex Contoured Headrest Pad, Large", - "Device Code": "SE0001844", - "Quantity": 1, - "ADP Price": 159.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "Spex Lateral Control Headrest, Small", - "Device Code": "SE0001845", - "Quantity": 1, - "ADP Price": 462.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "Spex Lateral Control Headrest Large", - "Device Code": "SE0001846", - "Quantity": 1, - "ADP Price": 462.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "Spex Compact Headrest Pad", - "Device Code": "SE0001847", - "Quantity": 1, - "ADP Price": 159.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "Stylo 160", - "Device Code": "SE0001848", - "Quantity": 1, - "ADP Price": 404.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "Stylo 260", - "Device Code": "SE0001849", - "Quantity": 1, - "ADP Price": 483.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "Stylo Flipback 160", - "Device Code": "SE0001850", - "Quantity": 1, - "ADP Price": 490.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "Stylo Flipback 260", - "Device Code": "SE0001851", - "Quantity": 1, - "ADP Price": 573.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "Small Headrest Assesmbly", - "Device Code": "SEHM90005", - "Quantity": 1, - "ADP Price": 114.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "Large Headrest", - "Device Code": "SEHM90015", - "Quantity": 1, - "ADP Price": 128.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "Offset Headrest Lateral", - "Device Code": "SEHM90025", - "Quantity": 1, - "ADP Price": 176.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Sunrise Medical", - "Device Description": "Offset Headrest Large", - "Device Code": "SEHM90030", - "Quantity": 1, - "ADP Price": 183.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Symmetric Designs", - "Device Description": "Savant Headrest", - "Device Code": "SE0001617", - "Quantity": 1, - "ADP Price": 344.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Symmetric Designs", - "Device Description": "Savant Head Rest with Carbon Cover (All Sizes)", - "Device Code": "SE0001876", - "Quantity": 1, - "ADP Price": 407.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Symmetric Designs", - "Device Description": "TWIN Forward Flex Headrest Mounting Hardware with Flip Back Function", - "Device Code": "SE0001919", - "Quantity": 1, - "ADP Price": 529.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Symmetric Designs", - "Device Description": "8\"/10\" Oval Pad 200/250mm x 115mm with Neoprene cover", - "Device Code": "SE0001921", - "Quantity": 1, - "ADP Price": 183.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Symmetric Designs", - "Device Description": "12\"/14\" Oval Pad 300/350mm x 115mm with Neoprene cover", - "Device Code": "SE0001922", - "Quantity": 1, - "ADP Price": 197.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Symmetric Designs", - "Device Description": "16\"/18\" Oval Pad 400/450mm x 115mm with Neoprene cover", - "Device Code": "SE0001923", - "Quantity": 1, - "ADP Price": 210.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Symmetric Designs", - "Device Description": "9\"/11\" Winged Pad 230/280mm x 140mm with Neoprene cover", - "Device Code": "SE0001924", - "Quantity": 1, - "ADP Price": 224.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "The Comfort Company", - "Device Description": "Headrest - Moldable, Includes Cover", - "Device Code": "SEH7C0015", - "Quantity": 1, - "ADP Price": 188.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "Vector Head N Neck Support, 11\"W X 8\"D Pad", - "Device Code": "SEHVC0005", - "Quantity": 1, - "ADP Price": 200.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "Vector Head N Neck Support, Custom Pad", - "Device Code": "SEHVC0010", - "Quantity": 1, - "ADP Price": 283.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Heads Up Pad All Sizes -Add On Occipital Pads Optional", - "Device Code": "SE0001099", - "Quantity": 1, - "ADP Price": 207.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "8\" Or 10\" Plush Pad With Linx Vertical/Horizontal Mount", - "Device Code": "SEHWH5005", - "Quantity": 1, - "ADP Price": 188.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "14\" Plush Pad With Linx Vertical/Horizontal Mount", - "Device Code": "SEHWH5010", - "Quantity": 1, - "ADP Price": 197.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "19\" Plush Pad With Link Vertical/Horizontal Mount", - "Device Code": "SEHWH5015", - "Quantity": 1, - "ADP Price": 288.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "8\" Or 10\" Plush Pad With LightweightVertical/Horizontal Mount", - "Device Code": "SEHWH5020", - "Quantity": 1, - "ADP Price": 188.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "8\" Or 10\" Plush Pad With Onyx Vertical/Horizontal Mount", - "Device Code": "SEHWH5025", - "Quantity": 1, - "ADP Price": 188.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "14\" Plush Pad With Onyx Vertical/Horizontal Mount", - "Device Code": "SEHWH5030", - "Quantity": 1, - "ADP Price": 197.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "19\" Plush Pad With Onyx Vertical/Horizontal Mount", - "Device Code": "SEHWH5032", - "Quantity": 1, - "ADP Price": 260.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "8\" Or 10\" Plush Pad With Pro Vertical/Horizontal Mount", - "Device Code": "SEHWH5035", - "Quantity": 1, - "ADP Price": 202.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "14\" Plush Pad With Pro Vertical/Horizontal Mount", - "Device Code": "SEHWH5040", - "Quantity": 1, - "ADP Price": 210.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "19\" Plush Pad With Pro Vertical/Horizontal Mount", - "Device Code": "SEHWH5045", - "Quantity": 1, - "ADP Price": 292.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Small Pad With Linx Vertical/Horizontal Mount", - "Device Code": "SEHWH5050", - "Quantity": 1, - "ADP Price": 123.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Medium Pad With Linx Vertical/Horizontal Mount", - "Device Code": "SEHWH5055", - "Quantity": 1, - "ADP Price": 133.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Large Pad With Linx Vertical/Horizontal Mount", - "Device Code": "SEHWH5060", - "Quantity": 1, - "ADP Price": 142.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Small Pad With Lightweight Vertical/Horizontal Mount", - "Device Code": "SEHWH5065", - "Quantity": 1, - "ADP Price": 123.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Medium Pad With Lightweight Vertical/Horizontal Mount, LWS-CCS3", - "Device Code": "SEHWH5070", - "Quantity": 1, - "ADP Price": 133.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Large Pad With Lightweight Vertical/Horizontal Mount", - "Device Code": "SEHWH5075", - "Quantity": 1, - "ADP Price": 142.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Small Pad With Onyx Vertical/Horizontal Mount", - "Device Code": "SEHWH5080", - "Quantity": 1, - "ADP Price": 165.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Medium Pad With Lightweight Vertical/Horizontal Mount, ONYX-CCS3", - "Device Code": "SEHWH5085", - "Quantity": 1, - "ADP Price": 174.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Large Pad With Onyx Vertical/Horizontal Mount", - "Device Code": "SEHWH5090", - "Quantity": 1, - "ADP Price": 183.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Small Pad With Pro Vertical/Horizontal Mount", - "Device Code": "SEHWH5095", - "Quantity": 1, - "ADP Price": 142.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Medium Pad With Pro Vertical/Horizontal Mount", - "Device Code": "SEHWH5105", - "Quantity": 1, - "ADP Price": 151.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Large Pad With Pro Vertical/Horizontal Mount", - "Device Code": "SEHWH5110", - "Quantity": 1, - "ADP Price": 197.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "10\" Plush Occipital Pad & Single Sub-Occipital PadWith Linx Vertical/Horizontal Mount", - "Device Code": "SEHWH7005", - "Quantity": 1, - "ADP Price": 361.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "4\"X6\"Occipital Pad & Single Sub-Occipital PadWith Lynx Vertical/Horizontal Mount", - "Device Code": "SEHWH7010", - "Quantity": 1, - "ADP Price": 316.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "T-Bar Occipital Pads & Single Sub-Occipital Pad2.25\"X7\" & 2.25\"X5\" With LinxVertical/Horizontal Mount", - "Device Code": "SEHWH7015", - "Quantity": 1, - "ADP Price": 562.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "10\" Plush Occipital Pad & Single Sub-Occipital PadWith Onyx Vertical/Horizontal Mount", - "Device Code": "SEHWH7020", - "Quantity": 1, - "ADP Price": 339.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "4\"X6\" Occipital Pad & Single Sub-Occipital PadWith Onyx Vertical/Horizontal Mount", - "Device Code": "SEHWH7025", - "Quantity": 1, - "ADP Price": 288.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "T-Bar Occipital Pads & Single Sub-Occipital Pad2.25\"X7\" & 2.25\"X5\" With OnyxVertical/Horizontal Mount", - "Device Code": "SEHWH7030", - "Quantity": 1, - "ADP Price": 535.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "10\" Plush Occipital Pad & Single Sub-Occipital PadWith Pro Verticial/Horizontal Mount", - "Device Code": "SEHWH7035", - "Quantity": 1, - "ADP Price": 371.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "4\"X6\" Occipital Pad & Single Sub-Occipital PadWith Pro Vertical/Horizontal Mount", - "Device Code": "SEHWH7040", - "Quantity": 1, - "ADP Price": 320.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "T-Bar Occipital Pads & Single Sub-Occipital Pad2.25\"X7\" & 2.25\"X5\" With ProVertical/Horizontal Mount", - "Device Code": "SEHWH7045", - "Quantity": 1, - "ADP Price": 572.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "4\"X6\"Occipital Pad With Size 1/2 Sub-Occipital PadsWith Lynx Vertical/Horizontal Mount", - "Device Code": "SEHWH7050", - "Quantity": 1, - "ADP Price": 380.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "8\"/10\" Plush Occipital Pad With Size1sub-Occipital PadsWith Lynx Vertical/Horizontal Mount", - "Device Code": "SEHWH7055", - "Quantity": 1, - "ADP Price": 430.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "T-Bar Occipital Pads With Size 1sub-Occipital Pads2.25\"X7\" With Linx Vertical/Horizontal Mount", - "Device Code": "SEHWH7060", - "Quantity": 1, - "ADP Price": 599.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "4\"X6\"Occipital Pad With Size 1/2 Sub-Occipital PadsWith Onyx Vertical/Horizontal Mount", - "Device Code": "SEHWH7065", - "Quantity": 1, - "ADP Price": 297.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "8\"/10\" Plush Occipital Pad With Size1sub-Occipital PadsWith Onyx Vertical/Horizontal Mount", - "Device Code": "SEHWH7070", - "Quantity": 1, - "ADP Price": 453.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "T-Bar Occipital Pads With Size 1sub-Occipital Pads2.25\"X7\" With Onyx Vertical/Horizontal Mount", - "Device Code": "SEHWH7075", - "Quantity": 1, - "ADP Price": 612.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "4\"X6\"Occipital Pad With Size 1/2 Sub-Occipital PadsWith Pro Vertical/Horizontal Mount", - "Device Code": "SEHWH7080", - "Quantity": 1, - "ADP Price": 416.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "8\"/10\" Plush Occipital Pad With Size 1Sub-Occipital PadsWith Pro Vertical/Horizontal Mount", - "Device Code": "SEHWH7085", - "Quantity": 1, - "ADP Price": 467.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "T-Bar Occipital Pads With Size 1 Sub-Occipital Pads2.25\"X7\" With Pro Vertical/Horizontal Mount", - "Device Code": "SEHWH7090", - "Quantity": 1, - "ADP Price": 636.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Occipital Pad With Size 3/4 Sub-Occipital Pads 1\"X4\",4\"X6\",1\"X4\" With LynxVertical/Horizontal Mount", - "Device Code": "SEHWH7105", - "Quantity": 1, - "ADP Price": 380.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "T-Bar Occipital Pads With Size 3 SingleSub-Occipital Pads2.25\"X5\" With Linx Vertical/Horizontal Mount", - "Device Code": "SEHWH7110", - "Quantity": 1, - "ADP Price": 599.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Occipital Pad With Size 3/4 Sub-Occipital Pads 1\"X4\",4\"X6\",1\"X4\" With OnyxVertical/Horizontal Mount", - "Device Code": "SEHWH7115", - "Quantity": 1, - "ADP Price": 393.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "T-Bar Occipital Pads With Size 3 SingleSub-Occipital Pads2.25\"X5\" With Onyx Vertical/Horizontal Mount", - "Device Code": "SEHWH7120", - "Quantity": 1, - "ADP Price": 612.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Occipital Pad With Size 3/4 Sub-Occipital Pads 1\"X4\",4\"X6\",1\"X4\" With ProVertical/Horizontal Mount", - "Device Code": "SEHWH7125", - "Quantity": 1, - "ADP Price": 416.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "T-Bar Occipital Pads With Size 3 SingleSub-Occipital Pads2.25\"X5\" With Pro Vertical/Horizontal Mount", - "Device Code": "SEHWH7130", - "Quantity": 1, - "ADP Price": 636.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Single Pad Dynamic Forehead Strap System All Sizes", - "Device Code": "SEHWH7200", - "Quantity": 1, - "ADP Price": 252.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Single Pad Static Forehead Strap System All Sizes", - "Device Code": "SEHWH7205", - "Quantity": 1, - "ADP Price": 266.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Unilateral Lfc With Pads And InterfacePlateFor Plush & Contoured Cradle Systems", - "Device Code": "SEHWH7230", - "Quantity": 1, - "ADP Price": 216.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Bilateral Lfc With Pads And InterfacePlateFor Plush & Contoured Cradle Systems", - "Device Code": "SEHWH7235", - "Quantity": 1, - "ADP Price": 398.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Lateral Facial Component With Pad", - "Device Code": "SEHWH7250", - "Quantity": 2, - "ADP Price": 183.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest", - "Manufacturer": "Whitmyer Biomechanix", - "Device Description": "Adjust-A-Plush Headrest System", - "Device Code": "SEHWH7260", - "Quantity": 1, - "ADP Price": 235.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Standard Mounting Hardware NotIncluded In Base Device -Removable, Allows Height, Anterior & Posterior Adjustments", - "Device Code": "SEHND0005", - "Quantity": 1, - "ADP Price": 121.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Non Standard Mounting Hardware Not Included In Base Device - Removable, Allows Multi Axis Adjustments", - "Device Code": "SEHND0010", - "Quantity": 1, - "ADP Price": 138.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Complex Specialized Mounting Hardware", - "Device Code": "SEHND0015", - "Quantity": 1, - "ADP Price": 259.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Bracket To Mount Headrest ToSeating System/BackSupport Or Wheelchair", - "Device Code": "SEHND0020", - "Quantity": 1, - "ADP Price": 86.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Custom Fabricated", - "Device Description": "Simple Headrest Hardware, Allows ForRemovability& Height Adjustment", - "Device Code": "SEICF006L", - "Quantity": 1, - "ADP Price": 60.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Custom Fabricated", - "Device Description": "Complex Headrest Hardware, AllowsFor Removability& Height And Forward Adjustment", - "Device Code": "SEICF007L", - "Quantity": 1, - "ADP Price": 134.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Custom Fabricated", - "Device Description": "Multi-Axis Headrest Hardware, AllowsFor Removability And Multi Adjustments", - "Device Code": "SEICF008L", - "Quantity": 1, - "ADP Price": 225.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Custom Fabricated", - "Device Description": "Wheelchair Mounting Bracket For Headrest Hardware", - "Device Code": "SEICF009L", - "Quantity": 1, - "ADP Price": 190.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Motion Concepts", - "Device Description": "Matrx Flipp LOXX Standard Hardware with mounting plate kit", - "Device Code": "SE0001977", - "Quantity": 1, - "ADP Price": 486.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Motion Concepts", - "Device Description": "Matrx Flipp LOXX Extended Hardware with mounting plate kit", - "Device Code": "SE0001978", - "Quantity": 1, - "ADP Price": 486.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Motion Concepts", - "Device Description": "Matrx Flipp LOXX Mini Hardware with mounting plate kit", - "Device Code": "SE0001979", - "Quantity": 1, - "ADP Price": 486.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Motion Concepts", - "Device Description": "Matrx Flipp LOXX Mini Extended Hardware with mounting plate kit", - "Device Code": "SE0001980", - "Quantity": 1, - "ADP Price": 486.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Motion Concepts", - "Device Description": "Matrx Flipp Elan Standard Hardware with mounting plate kit", - "Device Code": "SE0001981", - "Quantity": 1, - "ADP Price": 496.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Motion Concepts", - "Device Description": "Matrx Flipp ELAN Mini Hardware with mounting plate kit", - "Device Code": "SE0001982", - "Quantity": 1, - "ADP Price": 496.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Motion Concepts", - "Device Description": "Matrx Flipp ELAN Extended Hardware with mounting plate kit", - "Device Code": "SE0001983", - "Quantity": 1, - "ADP Price": 561.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Seat Back Mount- ½\" Square Back Mount", - "Device Code": "SE0002038", - "Quantity": 1, - "ADP Price": 62.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Seat Back Mount- ½\" Square Flip Down Back Mount", - "Device Code": "SE0002041", - "Quantity": 1, - "ADP Price": 152.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Seat Back Mount- Ottobock Clamp Offset Oval Complete", - "Device Code": "SE0002042", - "Quantity": 1, - "ADP Price": 176.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Horizontal Adjustment Bar - 7\" Bar with 1\"/17mm Ball", - "Device Code": "SE0002043", - "Quantity": 1, - "ADP Price": 35.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Horizontal Adjustment Bar - 17” Bar with 17mm Ball", - "Device Code": "SE0002044", - "Quantity": 1, - "ADP Price": 58.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Adapter - Universal Adapter Plate", - "Device Code": "SE0002045", - "Quantity": 1, - "ADP Price": 59.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Adapter - Adapter Plate for Permobil® backrests", - "Device Code": "SE0002046", - "Quantity": 1, - "ADP Price": 32.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Adapter - Adapter Plate for Kid Kart® backrests", - "Device Code": "SE0002047", - "Quantity": 1, - "ADP Price": 59.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Adapter - 17mm Adapter Ring for TWB and HMO hardware", - "Device Code": "SE0002048", - "Quantity": 1, - "ADP Price": 28.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Adapter - 17mm Adapter Ring for Ottobock hardware", - "Device Code": "SE0002049", - "Quantity": 1, - "ADP Price": 30.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Adapter -1\" (2.54cm) Crossbar Adapter Clamp", - "Device Code": "SE0002050", - "Quantity": 1, - "ADP Price": 59.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Adapter - Horizontal adjustment track for SBM or Ottobock hardware", - "Device Code": "SE0002051", - "Quantity": 1, - "ADP Price": 58.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Adapter - Single Point Adaptor", - "Device Code": "SE0002052", - "Quantity": 1, - "ADP Price": 50.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Tarta Back Headrest Adaptor", - "Device Code": "SE0002053", - "Quantity": 1, - "ADP Price": 99.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Link Options - Additional 17mm Ball Link", - "Device Code": "SE0002054", - "Quantity": 1, - "ADP Price": 38.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Link Options - Additional 2” In-Line Swing Away / Flip Down Link", - "Device Code": "SE0002055", - "Quantity": 1, - "ADP Price": 146.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Link Options - Additional Link (3\"/ 2\" / 1.5\")", - "Device Code": "SE0002056", - "Quantity": 2, - "ADP Price": 83.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Tone Deflector for 17mm Ball", - "Device Code": "SE0002057", - "Quantity": 1, - "ADP Price": 259.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Tone Deflector for 1\" Ball", - "Device Code": "SE0002058", - "Quantity": 1, - "ADP Price": 213.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Multi Axis, 15mm Square Tubing, 1\" Mounting Ball (470 Series)", - "Device Code": "SE0002059", - "Quantity": 1, - "ADP Price": 219.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Multi-Axis, 1\"/17mm Mounting Ball, Metric (470 Series)", - "Device Code": "SE0002060", - "Quantity": 1, - "ADP Price": 187.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Ottobock Head Support Mounting Hardware Multi-Axis (Curved/Straight)", - "Device Code": "SE0002061", - "Quantity": 1, - "ADP Price": 320.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - UniLink Head Solutions Hardware - Square Vertical Bar (12\"-15mm, 12\"-1/2\", 7\"-1/2\")", - "Device Code": "SE0002062", - "Quantity": 1, - "ADP Price": 335.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - UniLink Head Solutions FDM Hardware, Square Vertical Bar (7 ½\"-15mm, 7 ½\"-1/2\")", - "Device Code": "SE0002063", - "Quantity": 1, - "ADP Price": 409.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - UniLink Head Solutions Hardware Offset, Square Vertical Bar (14\"-1/2\", 10\"-1/2\")", - "Device Code": "SE0002064", - "Quantity": 1, - "ADP Price": 404.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - UniLink Headrest Stealth Ultra", - "Device Code": "SE0002065", - "Quantity": 1, - "ADP Price": 335.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - UniLink Ultra FDM, Square Vertical Bar,(7.5\"-15mm, 7\"-1/2\") REQ UHBSU23200", - "Device Code": "SE0002066", - "Quantity": 1, - "ADP Price": 364.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - UniLink Ultra, Offset, Square Vertical Bar, (14\"-1/2\") REQ UHBSU23200", - "Device Code": "SE0002067", - "Quantity": 1, - "ADP Price": 252.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - UniLink Ultra, Square Vertical Bar, (12\"-15mm,12\"-1/2\", 7\"-1/2\") REQ UHBSU23200", - "Device Code": "SE0002068", - "Quantity": 1, - "ADP Price": 183.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Head Support - Universal Multi-Axis Bracket (500/501)", - "Device Code": "SE0002069", - "Quantity": 1, - "ADP Price": 338.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Swing Away - Receiver for Comfort Plus Original OR ACP/TCP OR Low Profile - Left/Right Point (9” Rod)", - "Device Code": "SE0002070", - "Quantity": 1, - "ADP Price": 342.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Swing Away Receiver Both Sides for Comfort Plus Original OR ACP/TCP (2-9” Rods)", - "Device Code": "SE0002071", - "Quantity": 1, - "ADP Price": 404.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Swing Away - Receiver Both Sides for Low Profile (2-9” Rods)", - "Device Code": "SE0002072", - "Quantity": 1, - "ADP Price": 380.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Swing Away - 4 Point Swing Away for Comfort Plus Original - 2 Points (2-9\" Rods)", - "Device Code": "SE0002073", - "Quantity": 1, - "ADP Price": 465.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Swing Away - 4 Point Swing Away for Comfort Plus Original - 3 Points (3-9\" Rods)", - "Device Code": "SE0002074", - "Quantity": 1, - "ADP Price": 528.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - 4 Point Swing Away for Comfort Plus Original - All Points (4-9\" Rods)", - "Device Code": "SE0002075", - "Quantity": 1, - "ADP Price": 589.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - 4 Point Swing Away for Comfort Plus Original - All Points (No Rods)", - "Device Code": "SE0002076", - "Quantity": 1, - "ADP Price": 342.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - 4 Point Swing Away for Comfort Plus Original - Upper Left Point (No Rods)", - "Device Code": "SE0002077", - "Quantity": 1, - "ADP Price": 404.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Hardware - 4 Point Swing Away for Comfort Plus Original - Both Right Points (No Rods)", - "Device Code": "SE0002078", - "Quantity": 1, - "ADP Price": 465.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Symmetric Designs", - "Device Description": "TWIN Headrest Mounting Hardware", - "Device Code": "SE0001917", - "Quantity": 1, - "ADP Price": 285.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Symmetric Designs", - "Device Description": "TWIN Flip Headrest Hardware with Flip Back Function", - "Device Code": "SE0001918", - "Quantity": 1, - "ADP Price": 455.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Hardware", - "Manufacturer": "Symmetric Designs", - "Device Description": "Dynamic Flip Back TWIN Headrest Mounting Hardware", - "Device Code": "SE0001920", - "Quantity": 1, - "ADP Price": 529.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Custom - ADD Gel Layer to All Positioning Custom Head Pad (13\"x8\", 10\"x7.5\", 9\"x6.5\", 8\"x6.25\", 7\"x6\")", - "Device Code": "SE0002008", - "Quantity": 1, - "ADP Price": 145.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Custom - ADD Gel Layer to Combo Custom Headrest Pad (Back/Left or Right Wing)", - "Device Code": "SE0002009", - "Quantity": 1, - "ADP Price": 59.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Custom - ADD Gel Layer to X-Large Combo Custom Headrest Pad (Back Left or Right Wing)", - "Device Code": "SE0002010", - "Quantity": 1, - "ADP Price": 112.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Custom - ADD Gel Layer to Occipital Custom Pad (Standard/Flat/Curved - All Sizes)", - "Device Code": "SE0002011", - "Quantity": 1, - "ADP Price": 59.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Custom - ADD Gel Layer to Sub-Occipital Custom Pad (Standard/Flat/Curved - All Sizes)", - "Device Code": "SE0002012", - "Quantity": 1, - "ADP Price": 83.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Custom - Comfort Plus/Tri-Comfort Plus Custom Head Pad(_”x ” (6\"x20\" max))", - "Device Code": "SE0002013", - "Quantity": 1, - "ADP Price": 424.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Custom - Combo Custom Head Pad (_”x ” (6\"x20\" max))", - "Device Code": "SE0002014", - "Quantity": 1, - "ADP Price": 629.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Custom - ADD Gel layer to Comfort Plus Custom Head Pad (14\", 10\", 8\",6\")", - "Device Code": "SE0002015", - "Quantity": 1, - "ADP Price": 109.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Add Heavy Duty Arm Reinforcement (pair) - Custom Modification", - "Device Code": "SE0002016", - "Quantity": 1, - "ADP Price": 94.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Custom - i2i Add Custom Modification- Heavy Duty Arm Reinforcement (pair)", - "Device Code": "SE0002037", - "Quantity": 1, - "ADP Price": 94.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Removable Headrest/Neckrest Cover,Any Fabric, UseFor Flat/Contoured Headrest & Neckrest", - "Device Code": "SEMCF001L", - "Quantity": 2, - "ADP Price": 104.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Removable Cover For Complex Headrests, Use For Complex Headrest & Headrest/Neckrest Combinations", - "Device Code": "SEMCF002L", - "Quantity": 2, - "ADP Price": 155.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Simple Extension Pad, Mounted (Maximum 2)", - "Device Code": "SEMCF005L", - "Quantity": 2, - "ADP Price": 173.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Complex Extension Pad, Mounted (Maximum 2)", - "Device Code": "SEMCF006L", - "Quantity": 2, - "ADP Price": 259.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Quickie", - "Device Description": "RELAX HEADREST PAD", - "Device Code": "SE0000119", - "Quantity": 1, - "ADP Price": 235.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Options - Cane & Push Handle Mounting Options - Ottobock Clinical Assembly Set for 15\" to 16½\" wide frames", - "Device Code": "SE0001989", - "Quantity": 1, - "ADP Price": 213.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Options - Cane & Push Handle Mounting Options - Ottobock Clinical Assembly Set for 15¾\" to 21¼\"/20½\" to 24¼\" wide frames", - "Device Code": "SE0001990", - "Quantity": 1, - "ADP Price": 234.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Options - Cane & Push Handle Mounting Options - Ottobock Assembly Set frame without clamp (multiple sizes)", - "Device Code": "SE0001991", - "Quantity": 1, - "ADP Price": 288.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Options - Cane & Push Handle Mounting Options - Ottobock Standard S.T.S Clamp (multiple sizes)", - "Device Code": "SE0001992", - "Quantity": 2, - "ADP Price": 55.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Options - Cane & Push Handle Mounting Options - Ottobock SmallS.T.S Clamp (multiple sizes)", - "Device Code": "SE0001993", - "Quantity": 2, - "ADP Price": 97.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Seat Back Mount- 15mm Square Back Mount", - "Device Code": "SE0002039", - "Quantity": 1, - "ADP Price": 72.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Headrest Hardware - Seat Back Mount- ½\" Square Dove Tail Mount", - "Device Code": "SE0002040", - "Quantity": 1, - "ADP Price": 112.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Accessories - Figure 8 Ring", - "Device Code": "SE0002079", - "Quantity": 2, - "ADP Price": 125.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Accessories - Swing Away Rod 18\" Metric", - "Device Code": "SE0002080", - "Quantity": 4, - "ADP Price": 124.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Accessories - Swing Away Rod 24\" Metric", - "Device Code": "SE0002081", - "Quantity": 4, - "ADP Price": 155.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Accessories - Swing Away Rod (13\", 9\", 6\" Metric)", - "Device Code": "SE0002082", - "Quantity": 4, - "ADP Price": 93.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Accessories - Swing Away Ultra Facial Pad, Metric (6\"x1.5\", 6\"x2\", 4.5\"x2\", 3\"x2\")", - "Device Code": "SE0002083", - "Quantity": 4, - "ADP Price": 66.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Accessories - Swing Away Ultra Facial Pad with Gel (6\"x1.5\", 6\"x2\", 4.5\"x2\", 3\"x2\")", - "Device Code": "SE0002084", - "Quantity": 4, - "ADP Price": 120.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Accessories - Chin Prompt - Extra Small Nino/Small Nino/Small/Medium/Large/Extra Large", - "Device Code": "SE0002085", - "Quantity": 1, - "ADP Price": 94.0, - "SN Required": "No" - }, - { - "Device Type": "Headrest/Neckrest Options", - "Manufacturer": "Stealth Products LLC", - "Device Description": "Accessories - Trachea Chin Prompt - Extra Small Nino/Small Nino/Small/Medium/Large/Extra Large", - "Device Code": "SE0002086", - "Quantity": 1, - "ADP Price": 117.0, - "SN Required": "No" - }, - { - "Device Type": "Heavy Duty Cross Braces & Upholstery", - "Manufacturer": "THOMASHILFEN", - "Device Description": "Heavy Duty Cross Braces & Upholstery", - "Device Code": "WAMC", - "Quantity": 1, - "ADP Price": 536.0, - "SN Required": "No" - }, - { - "Device Type": "Lateral Support Hardware", - "Manufacturer": "Custom Fabricated", - "Device Description": "Fixed Lateral Hardware, Non-Adjustable (Maximum 2)", - "Device Code": "SEICF201L", - "Quantity": 2, - "ADP Price": 52.0, - "SN Required": "No" - }, - { - "Device Type": "Lateral Support Hardware", - "Manufacturer": "Custom Fabricated", - "Device Description": "Hinged Swingaway Lateral Hardware, Height& Width Adjustable (Maximum 2)", - "Device Code": "SEICF202L", - "Quantity": 2, - "ADP Price": 173.0, - "SN Required": "No" - }, - { - "Device Type": "Lateral Support Hardware", - "Manufacturer": "Custom Fabricated", - "Device Description": "Removable Lateral Hardware,Height & Width Adjustable (Maximum 2)", - "Device Code": "SEICF203L", - "Quantity": 2, - "ADP Price": 86.0, - "SN Required": "No" - }, - { - "Device Type": "Lateral Support Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Extra Padding (Maximum 2)", - "Device Code": "SEMCF651L", - "Quantity": 2, - "ADP Price": 52.0, - "SN Required": "No" - }, - { - "Device Type": "Lateral Support(s)", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Fixed Lateral Supports, Each - Includes Padding & Mounting Hardware (Maximum 4)", - "Device Code": "SELND0005", - "Quantity": 4, - "ADP Price": 104.0, - "SN Required": "No" - }, - { - "Device Type": "Lateral Support(s)", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Swingaway Lateral Supports, Each - Includes Padding & Mounting Hardware (Maximum 4)", - "Device Code": "SELND0010", - "Quantity": 4, - "ADP Price": 155.0, - "SN Required": "No" - }, - { - "Device Type": "Lateral Support(s)", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Complex Shape Lateral Supports, Each-Includes Padding & Mounting Hardware (Maximum 4)", - "Device Code": "SELND0015", - "Quantity": 4, - "ADP Price": 166.0, - "SN Required": "No" - }, - { - "Device Type": "Lateral Support(s)", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Shoulder Wings, Each - Includes Padding & Mounting Hardware (Maximum 2)", - "Device Code": "SELND0020", - "Quantity": 2, - "ADP Price": 47.0, - "SN Required": "No" - }, - { - "Device Type": "Lateral Support(s)", - "Manufacturer": "Custom Fabricated", - "Device Description": "Thoracolumbar Supports, Rigid & NonAdjustable,Includes Cover (Maximum 2)", - "Device Code": "SELCF101L", - "Quantity": 2, - "ADP Price": 69.0, - "SN Required": "No" - }, - { - "Device Type": "Lateral Support(s)", - "Manufacturer": "Custom Fabricated", - "Device Description": "Complex Shaped Thoracolumbar Supports, Non Adjustable, Includes Cover (Maximum 2)", - "Device Code": "SELCF102L", - "Quantity": 2, - "ADP Price": 151.0, - "SN Required": "No" - }, - { - "Device Type": "Lateral Support(s)", - "Manufacturer": "Custom Fabricated", - "Device Description": "Shoulder Wings, Non Adjustable, Includes Cover", - "Device Code": "SELCF103L", - "Quantity": 2, - "ADP Price": 82.0, - "SN Required": "No" - }, - { - "Device Type": "Manual Elevating Legrests (pair)", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Manual Elevating Legrests (pair)", - "Device Code": "WEPK", - "Quantity": 1, - "ADP Price": 308.0, - "SN Required": "No" - }, - { - "Device Type": "Manual Recline Option", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Manual Recline Option", - "Device Code": "WEPI", - "Quantity": 1, - "ADP Price": 590.0, - "SN Required": "No" - }, - { - "Device Type": "Midline Control", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Midline Control", - "Device Code": "WE3D", - "Quantity": 1, - "ADP Price": 268.0, - "SN Required": "No" - }, - { - "Device Type": "Multi-function Control Box", - "Manufacturer": "Amylior Inc.", - "Device Description": "Multi-Function Control Box, For UseOnSystems With Multiple FunctionsIncluding Tilt And PowerLegs, Tilt, Recline And Power Legs Etc.", - "Device Code": "SEC4P5005", - "Quantity": 1, - "ADP Price": 1766.0, - "SN Required": "No" - }, - { - "Device Type": "Multi-function Control Box", - "Manufacturer": "Invacare", - "Device Description": "Multi-Function Control Box For UseOnSystems With Multiple Functions.Including TiltAnd Power Legs, Tilt, Recline And Power Legs Etc.", - "Device Code": "SECIN5005", - "Quantity": 1, - "ADP Price": 1588.0, - "SN Required": "No" - }, - { - "Device Type": "Multi-function Control Box", - "Manufacturer": "Motion Concepts", - "Device Description": "Trx Helix / 600 Series Multi-FunctionControl Box (Thmc)For Use On Systems With MultipleFunctions,Including Tilt And Power Legs, Tilt,Recline, Power Legs,Etc. Includes Reduced Drive With Elevate.", - "Device Code": "SECZG5005", - "Quantity": 1, - "ADP Price": 1570.0, - "SN Required": "No" - }, - { - "Device Type": "Multi-function Control Box", - "Manufacturer": "Permobil", - "Device Description": "Multi-Function Control Box - For UseOn SystemsWith Multiple Functions Including, TiltAndPower Legs, Tilt, Recline And Power Legs, Etc.", - "Device Code": "SEC1P1005", - "Quantity": 1, - "ADP Price": 1847.0, - "SN Required": "No" - }, - { - "Device Type": "Multi-function Control Box", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Multi-Function Control Box - Advanced Acutator Module (AAM)", - "Device Code": "SECX15005", - "Quantity": 1, - "ADP Price": 1553.0, - "SN Required": "No" - }, - { - "Device Type": "Multi-function Control Box", - "Manufacturer": "Quickie", - "Device Description": "Multi-Function Control Box For Use On Systems With Multiple Functions, Including Tilt And Power Legrest, Tilt, Recline,Power Legrests Etc.", - "Device Code": "SECQU4005", - "Quantity": 1, - "ADP Price": 2403.0, - "SN Required": "No" - }, - { - "Device Type": "Multi-function Control Box", - "Manufacturer": "Sunrise Medical", - "Device Description": "multi-function control box - for use on systems with multiple functions including tilt and power legs, tilt and power legs, etc", - "Device Code": "WP0000654", - "Quantity": 1, - "ADP Price": 403.0, - "SN Required": "No" - }, - { - "Device Type": "MW - Adjustable Tension Back Upholstery over 18\" Frame Width", - "Manufacturer": "THOMASHILFEN", - "Device Description": "MW - Adjustable Tension Back Upholstery over 18\" Frame Width", - "Device Code": "WAME", - "Quantity": 1, - "ADP Price": 189.0, - "SN Required": "No" - }, - { - "Device Type": "MW - Adjustable Tension Back Upholstery up to 18\" Frame Width", - "Manufacturer": "THOMASHILFEN", - "Device Description": "MW - Adjustable Tension Back Upholstery up to 18\" Frame Width", - "Device Code": "WAMD", - "Quantity": 1, - "ADP Price": 110.0, - "SN Required": "No" - }, - { - "Device Type": "MW - Angle Adjustable Footplates (pair)", - "Manufacturer": "THOMASHILFEN", - "Device Description": "MW - Angle Adjustable Footplates (pair)", - "Device Code": "WAMJ", - "Quantity": 1, - "ADP Price": 102.0, - "SN Required": "No" - }, - { - "Device Type": "MW - Custom Modifications", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "MW - Custom Modifications", - "Device Code": "MWCM", - "Quantity": 1, - "ADP Price": 40.0, - "SN Required": "No" - }, - { - "Device Type": "MW - Heavy Duty Model, Client Weight Exceeds 250 Lbs", - "Manufacturer": "THOMASHILFEN", - "Device Description": "MW - Heavy Duty Model, Client Weight Exceeds 250 Lbs", - "Device Code": "WAMF", - "Quantity": 1, - "ADP Price": 575.0, - "SN Required": "No" - }, - { - "Device Type": "MW - Heavy Duty Model, Client Weight Exceeds 350 Lbs", - "Manufacturer": "THOMASHILFEN", - "Device Description": "MW - Heavy Duty Model, Client Weight Exceeds 350 Lbs", - "Device Code": "WAMG", - "Quantity": 1, - "ADP Price": 781.0, - "SN Required": "No" - }, - { - "Device Type": "MW - Heavy Duty Model, Client Weight Exceeds 400 Lbs", - "Manufacturer": "THOMASHILFEN", - "Device Description": "MW - Heavy Duty Model, Client Weight Exceeds 400 Lbs", - "Device Code": "WAMH", - "Quantity": 1, - "ADP Price": 874.0, - "SN Required": "No" - }, - { - "Device Type": "MW - Oxygen Tank Holder", - "Manufacturer": "THOMASHILFEN", - "Device Description": "MW - Oxygen Tank Holder", - "Device Code": "WAMX", - "Quantity": 1, - "ADP Price": 154.0, - "SN Required": "No" - }, - { - "Device Type": "MW - Seat Depth Required is Greater Than 18\"", - "Manufacturer": "THOMASHILFEN", - "Device Description": "MW - Seat Depth Required is Greater Than 18\"", - "Device Code": "WAMB", - "Quantity": 1, - "ADP Price": 209.0, - "SN Required": "No" - }, - { - "Device Type": "MW - Seat Width Required is Greater Than 18\"", - "Manufacturer": "THOMASHILFEN", - "Device Description": "MW - Seat Width Required is Greater Than 18\"", - "Device Code": "WAMA", - "Quantity": 1, - "ADP Price": 314.0, - "SN Required": "No" - }, - { - "Device Type": "MW - Ventilator Tray", - "Manufacturer": "THOMASHILFEN", - "Device Description": "MW - Ventilator Tray", - "Device Code": "WAMY", - "Quantity": 1, - "ADP Price": 335.0, - "SN Required": "No" - }, - { - "Device Type": "One Arm/Lever Drive", - "Manufacturer": "THOMASHILFEN", - "Device Description": "One Arm/Lever Drive", - "Device Code": "WAML", - "Quantity": 1, - "ADP Price": 824.0, - "SN Required": "No" - }, - { - "Device Type": "One Piece 90/90 Front Riggings", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "One Piece 90/90 Front Riggings", - "Device Code": "WEPL", - "Quantity": 1, - "ADP Price": 168.0, - "SN Required": "No" - }, - { - "Device Type": "Paediatric High Performance Rigid Manual Wheelchair", - "Manufacturer": "TiLite", - "Device Description": "TiLite Z", - "Device Code": "WM0002183", - "Quantity": 1, - "ADP Price": 3354.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Ki Mobility", - "Device Description": "Rogue", - "Device Code": "WM0001044", - "Quantity": 1, - "ADP Price": 3354.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Ki Mobility", - "Device Description": "Little Wave Clik", - "Device Code": "WM0001298", - "Quantity": 1, - "ADP Price": 3354.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Ki Mobility", - "Device Description": "Rogue ALX", - "Device Code": "WMK4KI005", - "Quantity": 1, - "ADP Price": 3354.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Motion Composites", - "Device Description": "Veloce 2018", - "Device Code": "WM0001598", - "Quantity": 1, - "ADP Price": 3354.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie QRi", - "Device Code": "WM0000992", - "Quantity": 1, - "ADP Price": 3354.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Zippie", - "Device Code": "WMK4QU005", - "Quantity": 1, - "ADP Price": 3354.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie Gp", - "Device Code": "WMK4QU010", - "Quantity": 1, - "ADP Price": 3354.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie Ti", - "Device Code": "WMK4QU025", - "Quantity": 1, - "ADP Price": 3354.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie Gt", - "Device Code": "WMK4QU030", - "Quantity": 1, - "ADP Price": 3354.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie Q7, Q7R, Q7RS", - "Device Code": "WMK4QU035", - "Quantity": 1, - "ADP Price": 3354.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Zippie Zone", - "Device Code": "WMK4QU040", - "Quantity": 1, - "ADP Price": 3354.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Rgk Wheelchairs", - "Device Description": "Hi-Lite", - "Device Code": "WMK4RZ005", - "Quantity": 1, - "ADP Price": 3354.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "Sunrise Medical", - "Device Description": "Quickie Nitrum - Paediatric High Perf Rigid", - "Device Code": "WM0001838", - "Quantity": 1, - "ADP Price": 3354.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "TiLite", - "Device Description": "TiLite Twist", - "Device Code": "WM0001187", - "Quantity": 1, - "ADP Price": 3354.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "TiLite", - "Device Description": "TiLite Pilot Manual Wheelchair", - "Device Code": "WM0001818", - "Quantity": 1, - "ADP Price": 3354.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "TiLite", - "Device Description": "Tilite Yr/Tr,Yra/Tra,Trc,Zra/Zr", - "Device Code": "WMK4TZ005", - "Quantity": 1, - "ADP Price": 3354.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric High Performance Rigid Type 4 Wheelchair", - "Manufacturer": "TiLite", - "Device Description": "Tilite Aero Z", - "Device Code": "WMK4TZ010", - "Quantity": 1, - "ADP Price": 3354.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Lightweight Performance Type 4 Wheelchair", - "Manufacturer": "Ki Mobility", - "Device Description": "Catalyst Spark", - "Device Code": "WM0000695", - "Quantity": 1, - "ADP Price": 2310.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Lightweight Performance Type 4 Wheelchair", - "Manufacturer": "Ki Mobility", - "Device Description": "Catalyst 5", - "Device Code": "WM0001313", - "Quantity": 1, - "ADP Price": 2310.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Lightweight Performance Type 4 Wheelchair", - "Manufacturer": "Motion Composites", - "Device Description": "Helio Kids", - "Device Code": "WM0000563", - "Quantity": 1, - "ADP Price": 2310.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Lightweight Performance Type 4 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie Xenon", - "Device Code": "WM0001157", - "Quantity": 1, - "ADP Price": 2310.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Lightweight Performance Type 4 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Zippie 2", - "Device Code": "WMK3QU005", - "Quantity": 1, - "ADP Price": 2310.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Lightweight Performance Type 4 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie 2 (VIP 2)", - "Device Code": "WMK3QU010", - "Quantity": 1, - "ADP Price": 2310.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Lightweight Performance Type 4 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie 2 Hp", - "Device Code": "WMK3QU015", - "Quantity": 1, - "ADP Price": 2310.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Lightweight Performance Type 4 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie 2 Lite", - "Device Code": "WMK3QU020", - "Quantity": 1, - "ADP Price": 2310.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Lightweight Performance Type 4 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Zippie Gs", - "Device Code": "WMK3QU035", - "Quantity": 1, - "ADP Price": 2310.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Lightweight Performance Type 4 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie Gtx", - "Device Code": "WMK3QU040", - "Quantity": 1, - "ADP Price": 2310.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Lightweight Performance Type 4 Wheelchair", - "Manufacturer": "Sunrise Medical", - "Device Description": "Zippie X'Cape", - "Device Code": "WM0001239", - "Quantity": 1, - "ADP Price": 2310.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Lightweight Performance Type 4 Wheelchair", - "Manufacturer": "TiLite", - "Device Description": "TILite AERO X", - "Device Code": "WM0001170", - "Quantity": 1, - "ADP Price": 2310.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Invacare", - "Device Description": "9000 Jymni", - "Device Code": "WMK2IN010", - "Quantity": 1, - "ADP Price": 1596.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie Qx", - "Device Code": "WM0001311", - "Quantity": 1, - "ADP Price": 1596.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Lightweight Standard Type 1 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie Lx", - "Device Code": "WMK2QU020", - "Quantity": 1, - "ADP Price": 1596.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Convaid", - "Device Description": "Safari Tilt", - "Device Code": "WMK5CO040", - "Quantity": 1, - "ADP Price": 2804.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Future Mobility", - "Device Description": "Super Chair For Kids", - "Device Code": "WMK5FM010", - "Quantity": 1, - "ADP Price": 2804.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Hoggi", - "Device Description": "Bingo/Bingo Evolution", - "Device Code": "WMK5K2010", - "Quantity": 1, - "ADP Price": 2804.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Kid Kart", - "Device Description": "Kid Kart Xpress", - "Device Code": "WMK5KT020", - "Quantity": 1, - "ADP Price": 2804.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Ki Mobility", - "Device Description": "Focus CR", - "Device Code": "WM0001161", - "Quantity": 1, - "ADP Price": 2804.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Ki Mobility", - "Device Description": "Little Wave Flip XP", - "Device Code": "WM0001342", - "Quantity": 1, - "ADP Price": 2804.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Ki Mobility", - "Device Description": "Liberty FT", - "Device Code": "WM0001579", - "Quantity": 1, - "ADP Price": 2804.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Ki Mobility", - "Device Description": "Little Wave Arc Tilt P*", - "Device Code": "WM0001901", - "Quantity": 1, - "ADP Price": 2804.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Otto Bock", - "Device Description": "Kimba Spring & Kimba Spring Plus", - "Device Code": "WMK5OB010", - "Quantity": 1, - "ADP Price": 2804.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Physipro", - "Device Description": "NEOX Junior", - "Device Code": "WM0001312", - "Quantity": 1, - "ADP Price": 2804.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Physipro", - "Device Description": "Spiral", - "Device Code": "WM0001600", - "Quantity": 1, - "ADP Price": 2804.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Product Design Group", - "Device Description": "Fuze T50", - "Device Code": "WMK5MV020", - "Quantity": 1, - "ADP Price": 2804.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Quickie SR-45", - "Device Code": "WM0000473", - "Quantity": 1, - "ADP Price": 2804.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Zippie Ts", - "Device Code": "WMK5QU005", - "Quantity": 1, - "ADP Price": 2804.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "Quickie", - "Device Description": "Zippie Iris (Folding & Non Folding)", - "Device Code": "WMK5QU010", - "Quantity": 1, - "ADP Price": 2804.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "THOMASHILFEN", - "Device Description": "Thevo Twist", - "Device Code": "WM0000325", - "Quantity": 1, - "ADP Price": 2804.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Manual Dynamic Tilt Type 5 Wheelchair", - "Manufacturer": "THOMASHILFEN", - "Device Description": "Easy S", - "Device Code": "WM0000326", - "Quantity": 1, - "ADP Price": 2804.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 2", - "Manufacturer": "Motion Concepts", - "Device Description": "Rovi X3 5.0 mph", - "Device Code": "WP0001540", - "Quantity": 1, - "ADP Price": 5507.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 2", - "Manufacturer": "Permobil", - "Device Description": "M1", - "Device Code": "WP0001578", - "Quantity": 1, - "ADP Price": 5507.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 3", - "Manufacturer": "Amylior Inc.", - "Device Description": "Alltrack PM3", - "Device Code": "WP0001771", - "Quantity": 1, - "ADP Price": 5902.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 3", - "Manufacturer": "Amylior Inc.", - "Device Description": "Alltrack PR3", - "Device Code": "WP0001772", - "Quantity": 1, - "ADP Price": 5902.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 3", - "Manufacturer": "Invacare", - "Device Description": "Storm Torque", - "Device Code": "WPK3IN015", - "Quantity": 1, - "ADP Price": 5902.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 3", - "Manufacturer": "LEVO AG", - "Device Description": "LEVO C3", - "Device Code": "WP0001141", - "Quantity": 1, - "ADP Price": 5902.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 3", - "Manufacturer": "Motion Concepts", - "Device Description": "Rovi X3 5.8 or 6.2 mph", - "Device Code": "WP0001443", - "Quantity": 1, - "ADP Price": 5902.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 3", - "Manufacturer": "Permobil", - "Device Description": "M300", - "Device Code": "WP0000987", - "Quantity": 1, - "ADP Price": 5902.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 3", - "Manufacturer": "Permobil", - "Device Description": "F5 / F5 VS Corpus (Paediatric)", - "Device Code": "WP0001257", - "Quantity": 1, - "ADP Price": 5902.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 3", - "Manufacturer": "Permobil", - "Device Description": "F3 Corpus (Paediatric)", - "Device Code": "WP0001259", - "Quantity": 1, - "ADP Price": 5902.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 3", - "Manufacturer": "Permobil", - "Device Description": "M3 Corpus", - "Device Code": "WP0001402", - "Quantity": 1, - "ADP Price": 5902.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 3", - "Manufacturer": "Permobil", - "Device Description": "M5 Corpus", - "Device Code": "WP0001450", - "Quantity": 1, - "ADP Price": 5902.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 3", - "Manufacturer": "Permobil", - "Device Description": "M Corpus VS", - "Device Code": "WP0002129", - "Quantity": 1, - "ADP Price": 5902.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 3", - "Manufacturer": "Permobil", - "Device Description": "C300 Corpus Junior / K300", - "Device Code": "WPK31P010", - "Quantity": 1, - "ADP Price": 5902.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 3", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Quantum Q6 Edge 2.0 (Paediatric)", - "Device Code": "WP0001253", - "Quantity": 1, - "ADP Price": 5902.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 3", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Quantum 4Front 2", - "Device Code": "WP0001442", - "Quantity": 1, - "ADP Price": 5902.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 3", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Quantum Edge 3", - "Device Code": "WP0001576", - "Quantity": 1, - "ADP Price": 5902.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 3", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Quantum Q6 Edge 3 Stretto", - "Device Code": "WP0001807", - "Quantity": 1, - "ADP Price": 5902.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 3", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Quantum R-Trak (P)", - "Device Code": "WP0001988", - "Quantity": 1, - "ADP Price": 5902.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 3", - "Manufacturer": "Quickie", - "Device Description": "Quickie Pulse 6 with SPOT Tilt", - "Device Code": "WP0000638", - "Quantity": 1, - "ADP Price": 5902.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 3", - "Manufacturer": "Quickie", - "Device Description": "Quickie QM-710, 715, 720", - "Device Code": "WP0000687", - "Quantity": 1, - "ADP Price": 5902.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 3", - "Manufacturer": "Quickie", - "Device Description": "Quickie P-222", - "Device Code": "WPK3QU020", - "Quantity": 1, - "ADP Price": 5902.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Power Base Type 3", - "Manufacturer": "Sunrise Medical", - "Device Description": "Q300M Mini with ASAP Seating System", - "Device Code": "WP0001984", - "Quantity": 1, - "ADP Price": 5902.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Specific Specialty Stroller", - "Manufacturer": "Convaid", - "Device Description": "Trekker", - "Device Code": "WM0001374", - "Quantity": 1, - "ADP Price": 1303.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Specific Specialty Stroller", - "Manufacturer": "Convaid", - "Device Description": "Coaster", - "Device Code": "WM0002143", - "Quantity": 1, - "ADP Price": 1303.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Specific Specialty Stroller", - "Manufacturer": "Convaid", - "Device Description": "Cruiser Cx", - "Device Code": "WMK6CO005", - "Quantity": 1, - "ADP Price": 1303.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Specific Specialty Stroller", - "Manufacturer": "Convaid", - "Device Description": "Ez Rider", - "Device Code": "WMK6CO050", - "Quantity": 1, - "ADP Price": 1303.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Specific Specialty Stroller", - "Manufacturer": "Convaid", - "Device Description": "Rodeo Tilt", - "Device Code": "WMK6CO060", - "Quantity": 1, - "ADP Price": 1303.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Specific Specialty Stroller", - "Manufacturer": "Maclaren", - "Device Description": "Buggy", - "Device Code": "WMK6AM005", - "Quantity": 1, - "ADP Price": 1303.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Specific Specialty Stroller", - "Manufacturer": "Ormesa", - "Device Description": "New Bug", - "Device Code": "WM0001271", - "Quantity": 1, - "ADP Price": 1303.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Specific Specialty Stroller", - "Manufacturer": "Otto Bock", - "Device Description": "Kimba Neo", - "Device Code": "WM0001100", - "Quantity": 1, - "ADP Price": 1303.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Specific Specialty Stroller", - "Manufacturer": "Otto Bock", - "Device Description": "Kimba Kruze", - "Device Code": "WM0001302", - "Quantity": 1, - "ADP Price": 1303.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Specific Specialty Stroller", - "Manufacturer": "Quickie", - "Device Description": "Zippie Voyage", - "Device Code": "WM0001083", - "Quantity": 1, - "ADP Price": 1303.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Specific Specialty Stroller", - "Manufacturer": "Synetik ErgoCare", - "Device Description": "Corzo X Country", - "Device Code": "WM0001599", - "Quantity": 1, - "ADP Price": 1303.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Specific Specialty Stroller", - "Manufacturer": "Synetik ErgoCare", - "Device Description": "Piper", - "Device Code": "WM0001601", - "Quantity": 1, - "ADP Price": 1303.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Specific Specialty Stroller", - "Manufacturer": "THOMASHILFEN", - "Device Description": "Thevo Swifty Stroller", - "Device Code": "WM0000316", - "Quantity": 1, - "ADP Price": 1303.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Specific Specialty Stroller", - "Manufacturer": "THOMASHILFEN", - "Device Description": "Swifty Stroller - Paediatric specific specialty stroller type 6", - "Device Code": "WM0000318", - "Quantity": 1, - "ADP Price": 1303.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Specific Walking Frame", - "Manufacturer": "Ora Medical", - "Device Description": "Levity", - "Device Code": "AA0002195", - "Quantity": 1, - "ADP Price": 2578.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 1", - "Manufacturer": "Prime Engineering", - "Device Description": "Up-Right Stander", - "Device Code": "MS12P0015", - "Quantity": 1, - "ADP Price": 1219.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 1", - "Manufacturer": "Sunrise", - "Device Description": "Leckey Totstander", - "Device Code": "AA0001369", - "Quantity": 1, - "ADP Price": 1219.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Altimate Medical", - "Device Description": "Easystand Zing", - "Device Code": "AA0001304", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Altimate Medical", - "Device Description": "Easy Stand Evolv", - "Device Code": "MS2HC0010", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Altimate Medical", - "Device Description": "Easy Stand Bantam", - "Device Code": "MS2HC0015", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "JENX", - "Device Description": "Multistander Size 1 with Base Frame/Abduction, positioning straps, trunk, knee and foot supports, and tray.", - "Device Code": "AA0001866", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "JENX", - "Device Description": "Multistander Size 2 with Base Frame/Abduction, positioning straps, trunk, knee and foot supports, and tray.", - "Device Code": "AA0001867", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "JENX", - "Device Description": "Standz with Base Frame, Abducted/Neutral leg positioning, positioning straps, trunk, knee and foot supports, and tray.", - "Device Code": "AA0001868", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Liw Care Technology", - "Device Description": "Lori Stander", - "Device Code": "AA0002180", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Liw Care Technology", - "Device Description": "Baffin Automatic", - "Device Code": "AA0002181", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Liw Care Technology", - "Device Description": "Baffin Trio", - "Device Code": "AA0002182", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Ormesa", - "Device Description": "Dondolino, Size 1", - "Device Code": "MS2OA0010", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Ormesa", - "Device Description": "Dondolino, Size 2", - "Device Code": "MS2OA0015", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Ormesa", - "Device Description": "Dondolino, Size 3", - "Device Code": "MS2OA0020", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Ormesa", - "Device Description": "Mini Standy", - "Device Code": "MS2OA0030", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Ormesa", - "Device Description": "Standy", - "Device Code": "MS2OA0035", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Prime Engineering", - "Device Description": "Superstand,Small & Youth", - "Device Code": "MS22P0005", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Prime Engineering", - "Device Description": "Kidstand & Grandstand 111", - "Device Code": "MS22P0010", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Prime Engineering", - "Device Description": "Symmetry Standing Frame", - "Device Code": "MS22P0015", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "R82", - "Device Description": "Rabbit Up", - "Device Code": "AA0001572", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "R82", - "Device Description": "Meerkat", - "Device Code": "AA0001581", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "R82", - "Device Description": "Caribou, all sizes", - "Device Code": "MS2R80005", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "R82", - "Device Description": "Gazelle,Size 1", - "Device Code": "MS2R80020", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "R82", - "Device Description": "Gazelle,Size 2", - "Device Code": "MS2R80025", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "R82", - "Device Description": "Gazelle,Size 3", - "Device Code": "MS2R80030", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Sunrise Medical", - "Device Description": "Leckey Mygo Stander", - "Device Code": "AA0000692", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Sunrise Medical", - "Device Description": "Squiggle Stander", - "Device Code": "AA0000700", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Sunrise Medical", - "Device Description": "Leckey Freestander", - "Device Code": "AA0001368", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Sunrise Medical", - "Device Description": "Leckey Pronestander", - "Device Code": "AA0001370", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Sunrise Medical", - "Device Description": "Leckey Horizon Stander", - "Device Code": "AA0001371", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Sunrise Medical", - "Device Description": "Squiggles+", - "Device Code": "AA0001650", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Synetik ErgoCare", - "Device Description": "Vertiflex A1,A2,A3", - "Device Code": "AA0001721", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Synetik ErgoCare", - "Device Description": "SKY Multi-positioning pediatric standing system", - "Device Code": "AA0001985", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Synetik ErgoCare", - "Device Description": "Vertiflex S4-S5-S6", - "Device Code": "AA0002381", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Standing Frame Type 2", - "Manufacturer": "Synetik ErgoCare", - "Device Description": "Vertiflex S1, S2 & S3", - "Device Code": "MS2JP0010", - "Quantity": 1, - "ADP Price": 3285.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Walking Frame", - "Manufacturer": "Can-Dan Rehatec", - "Device Description": "Buddy Roamer", - "Device Code": "AA0001101", - "Quantity": 1, - "ADP Price": 2578.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Walking Frame", - "Manufacturer": "Can-Dan Rehatec", - "Device Description": "Meywalk, Medium & Large", - "Device Code": "MW6CD0040", - "Quantity": 1, - "ADP Price": 2578.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Walking Frame", - "Manufacturer": "Can-Dan Rehatec", - "Device Description": "Meywalk 3, Meywalk 4", - "Device Code": "MW6CD0045", - "Quantity": 1, - "ADP Price": 2578.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Walking Frame", - "Manufacturer": "Can-Dan Rehatec", - "Device Description": "Mini-Meywalk", - "Device Code": "MW6CD0050", - "Quantity": 1, - "ADP Price": 2578.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Walking Frame", - "Manufacturer": "Drive Medical", - "Device Description": "Moxie Gait Trainer", - "Device Code": "AA0001877", - "Quantity": 1, - "ADP Price": 2578.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Walking Frame", - "Manufacturer": "Hoggi", - "Device Description": "Flux Gait Trainer", - "Device Code": "MW6K20005", - "Quantity": 1, - "ADP Price": 2578.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Walking Frame", - "Manufacturer": "Ormesa", - "Device Description": "Grillo", - "Device Code": "MW6OA0005", - "Quantity": 1, - "ADP Price": 2578.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Walking Frame", - "Manufacturer": "Ormesa", - "Device Description": "Dynamico", - "Device Code": "MW6R80055", - "Quantity": 1, - "ADP Price": 2578.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Walking Frame", - "Manufacturer": "Prime Engineering", - "Device Description": "Kidwalk", - "Device Code": "MW62P0005", - "Quantity": 1, - "ADP Price": 2578.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Walking Frame", - "Manufacturer": "R82", - "Device Description": "Mustang Gait Trainer", - "Device Code": "AA0000693", - "Quantity": 1, - "ADP Price": 2578.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Walking Frame", - "Manufacturer": "R82", - "Device Description": "Crocodile Reverse Walker", - "Device Code": "MW6R80070", - "Quantity": 1, - "ADP Price": 2578.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Walking Frame", - "Manufacturer": "Rifton Equipment", - "Device Description": "Pacer Gait Trainer", - "Device Code": "MW6RF0005", - "Quantity": 1, - "ADP Price": 2578.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Walking Frame", - "Manufacturer": "Sunrise Medical", - "Device Description": "My Way (Size 1, Size 2 or Size 3) Includes Frame, 4 Wheels, Harness, Sling or Saddle, Hand grips & supports.", - "Device Code": "AA0001934", - "Quantity": 1, - "ADP Price": 2578.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Wheeled Walker Type 1", - "Manufacturer": "Drive Medical", - "Device Description": "Nimbo Posterior Walker, Large", - "Device Code": "AA0000105", - "Quantity": 1, - "ADP Price": 220.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Wheeled Walker Type 1", - "Manufacturer": "Drive Medical", - "Device Description": "Nimbo Posterior Walker, XSmall", - "Device Code": "AA0000110", - "Quantity": 1, - "ADP Price": 220.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Wheeled Walker Type 1", - "Manufacturer": "Drive Medical", - "Device Description": "Nimbo Posterior Walker, Small", - "Device Code": "AA0000111", - "Quantity": 1, - "ADP Price": 220.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Wheeled Walker Type 1", - "Manufacturer": "Drive Medical", - "Device Description": "Nimbo Posterior Walker, Medium", - "Device Code": "AA0000112", - "Quantity": 1, - "ADP Price": 220.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Wheeled Walker Type 1", - "Manufacturer": "Kaye", - "Device Description": "Child Small 2 Wheels", - "Device Code": "MW4KY0005", - "Quantity": 1, - "ADP Price": 220.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Wheeled Walker Type 1", - "Manufacturer": "Kaye", - "Device Description": "Child Small 4 Wheels", - "Device Code": "MW4KY0010", - "Quantity": 1, - "ADP Price": 220.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Wheeled Walker Type 1", - "Manufacturer": "Kaye", - "Device Description": "Child Small 4 Wheels/Swivel", - "Device Code": "MW4KY0015", - "Quantity": 1, - "ADP Price": 220.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Wheeled Walker Type 1", - "Manufacturer": "Kaye", - "Device Description": "Child 2 Wheels", - "Device Code": "MW4KY0020", - "Quantity": 1, - "ADP Price": 220.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Wheeled Walker Type 1", - "Manufacturer": "Kaye", - "Device Description": "Child 4 Wheels", - "Device Code": "MW4KY0025", - "Quantity": 1, - "ADP Price": 220.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Wheeled Walker Type 1", - "Manufacturer": "Kaye", - "Device Description": "Child 4 Wheels/Swivel", - "Device Code": "MW4KY0030", - "Quantity": 1, - "ADP Price": 220.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Wheeled Walker Type 1", - "Manufacturer": "Kaye", - "Device Description": "Youth 2 Wheels", - "Device Code": "MW4KY0035", - "Quantity": 1, - "ADP Price": 220.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Wheeled Walker Type 1", - "Manufacturer": "Kaye", - "Device Description": "Youth 4 Wheels", - "Device Code": "MW4KY0040", - "Quantity": 1, - "ADP Price": 220.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Wheeled Walker Type 1", - "Manufacturer": "Kaye", - "Device Description": "Youth 4 Wheels/Swivel", - "Device Code": "MW4KY0045", - "Quantity": 1, - "ADP Price": 220.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Wheeled Walker Type 1", - "Manufacturer": "Kaye", - "Device Description": "Pre-Adolescent 2 Wheels", - "Device Code": "MW4KY0050", - "Quantity": 1, - "ADP Price": 220.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Wheeled Walker Type 1", - "Manufacturer": "Kaye", - "Device Description": "Pre-Adolescent 4 Wheels", - "Device Code": "MW4KY0055", - "Quantity": 1, - "ADP Price": 220.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Wheeled Walker Type 1", - "Manufacturer": "Kaye", - "Device Description": "Pre-Adolescent 4 Wheels/Swivel", - "Device Code": "MW4KY0060", - "Quantity": 1, - "ADP Price": 220.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Wheeled Walker Type 1", - "Manufacturer": "Kaye", - "Device Description": "Adolescent 2 Wheels", - "Device Code": "MW4KY0065", - "Quantity": 1, - "ADP Price": 220.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Wheeled Walker Type 1", - "Manufacturer": "Kaye", - "Device Description": "Adolescent 4 Wheels", - "Device Code": "MW4KY0070", - "Quantity": 1, - "ADP Price": 220.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Wheeled Walker Type 1", - "Manufacturer": "Kaye", - "Device Description": "Adolescent 4 Wheels/Swivel", - "Device Code": "MW4KY0075", - "Quantity": 1, - "ADP Price": 220.0, - "SN Required": "Yes" - }, - { - "Device Type": "Paediatric Wheeled Walker Type 2", - "Manufacturer": "Sunrise Medical", - "Device Description": "Gemino S", - "Device Code": "AA0001303", - "Quantity": 1, - "ADP Price": 417.0, - "SN Required": "Yes" - }, - { - "Device Type": "Plastic Coated Handrims", - "Manufacturer": "THOMASHILFEN", - "Device Description": "Plastic Coated Handrims", - "Device Code": "WAMO", - "Quantity": 1, - "ADP Price": 106.0, - "SN Required": "No" - }, - { - "Device Type": "Pommel/Adductors", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Pommel, Flip Down, All Components Including Hardware", - "Device Code": "SESND1043", - "Quantity": 1, - "ADP Price": 259.0, - "SN Required": "No" - }, - { - "Device Type": "Pommel/Adductors", - "Manufacturer": "Custom Fabricated", - "Device Description": "Custom Pommel Without Hardware", - "Device Code": "SEMCF701L", - "Quantity": 1, - "ADP Price": 138.0, - "SN Required": "No" - }, - { - "Device Type": "Pommel/Adductors", - "Manufacturer": "Custom Fabricated", - "Device Description": "Fixed Padded Adductor IncludesCover(Maximum 2)", - "Device Code": "SEMCF702L", - "Quantity": 2, - "ADP Price": 104.0, - "SN Required": "No" - }, - { - "Device Type": "Pommel/Adductors", - "Manufacturer": "Custom Fabricated", - "Device Description": "Removable Padded Adductor IncludesCover(Maximum 2)", - "Device Code": "SEMCF703L", - "Quantity": 2, - "ADP Price": 164.0, - "SN Required": "No" - }, - { - "Device Type": "Pommel Hardware", - "Manufacturer": "Custom Fabricated", - "Device Description": "Hardware For Fixed Pommel", - "Device Code": "SEICF401L", - "Quantity": 1, - "ADP Price": 73.0, - "SN Required": "No" - }, - { - "Device Type": "Pommel Hardware", - "Manufacturer": "Custom Fabricated", - "Device Description": "Hardware For Removable Pommel", - "Device Code": "SEICF402L", - "Quantity": 1, - "ADP Price": 151.0, - "SN Required": "No" - }, - { - "Device Type": "Pommel Hardware", - "Manufacturer": "Custom Fabricated", - "Device Description": "Hardware For Flip-Down Pommel", - "Device Code": "SEICF403L", - "Quantity": 1, - "ADP Price": 259.0, - "SN Required": "No" - }, - { - "Device Type": "Positioning Belts", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Chest Harness For Positioning Only -Any Closure -Includes Padding & Mounting Hardware", - "Device Code": "SERND0001", - "Quantity": 1, - "ADP Price": 121.0, - "SN Required": "No" - }, - { - "Device Type": "Positioning Belts", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Shoulder Straps For Positioning Only -Any Closure - Includes Padding & Mounting Hardware (Maximum 2)", - "Device Code": "SERND0010", - "Quantity": 2, - "ADP Price": 52.0, - "SN Required": "No" - }, - { - "Device Type": "Positioning Belts", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Any 4 Point Strap For Positioning Only- Any Closure -Includes Padding & MountingHardware -Pelvic \"Y\" Strap, \"H\" Leg Strap (Maximum 2)", - "Device Code": "SERND0020", - "Quantity": 2, - "ADP Price": 129.0, - "SN Required": "No" - }, - { - "Device Type": "Positioning Belts", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Any 2 Point Strap For Positioning Only- Any Closure -Includes Padding & MountingHardware -Chest, Hip,Thigh, Calf, Ankle, Foot (Maximum 6)", - "Device Code": "SERND0030", - "Quantity": 6, - "ADP Price": 56.0, - "SN Required": "No" - }, - { - "Device Type": "Positioning Belts", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Non Standard Chest Or Shoulder Harness Required For Positioning Support Only", - "Device Code": "SERND0035", - "Quantity": 1, - "ADP Price": 397.0, - "SN Required": "No" - }, - { - "Device Type": "Positioning Belts", - "Manufacturer": "Custom Fabricated", - "Device Description": "Pelvic \"Y\" Belt Or Groin Strap, Includes Attachments", - "Device Code": "SERCF101L", - "Quantity": 1, - "ADP Price": 52.0, - "SN Required": "No" - }, - { - "Device Type": "Positioning Belts", - "Manufacturer": "Custom Fabricated", - "Device Description": "Custom Chest Support, Includes Attachments", - "Device Code": "SERCF103L", - "Quantity": 1, - "ADP Price": 129.0, - "SN Required": "No" - }, - { - "Device Type": "Positioning Belts", - "Manufacturer": "Custom Fabricated", - "Device Description": "Custom Shoulder Harness, Includes Padding & Attachments", - "Device Code": "SERCF104L", - "Quantity": 1, - "ADP Price": 181.0, - "SN Required": "No" - }, - { - "Device Type": "Positioning Belts", - "Manufacturer": "Custom Fabricated", - "Device Description": "Custom Positioning Belt, IncludesAttachments.Specify Upper &/Or Lower Extremity&/Or Chest(Maximum 12)", - "Device Code": "SERCF105L", - "Quantity": 12, - "ADP Price": 47.0, - "SN Required": "No" - }, - { - "Device Type": "Positioning Belts Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Positioning Support Pads (Maximum 12)", - "Device Code": "SEMCF501L", - "Quantity": 12, - "ADP Price": 47.0, - "SN Required": "No" - }, - { - "Device Type": "Positioning Belts Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Positioning Control Pads (Maximum 12)", - "Device Code": "SEMCF502L", - "Quantity": 12, - "ADP Price": 47.0, - "SN Required": "No" - }, - { - "Device Type": "Positioning Belts Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Complex Control Pads (Maximum 4)", - "Device Code": "SEMCF503L", - "Quantity": 4, - "ADP Price": 142.0, - "SN Required": "No" - }, - { - "Device Type": "Power Add-On Device", - "Manufacturer": "Alber Gmbh", - "Device Description": "alber e.Motion M25", - "Device Code": "WPS1DO005", - "Quantity": 1, - "ADP Price": 4831.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Add-On Device", - "Manufacturer": "Cheelcare", - "Device Description": "Companion Plus", - "Device Code": "WM0001927", - "Quantity": 1, - "ADP Price": 4831.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Add-On Device", - "Manufacturer": "Magicwheels", - "Device Description": "Magicwheels", - "Device Code": "WPS1WS005", - "Quantity": 1, - "ADP Price": 4831.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Add-On Device", - "Manufacturer": "Max Mobility", - "Device Description": "Smart Drive", - "Device Code": "WM0001081", - "Quantity": 1, - "ADP Price": 4831.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Add-On Device", - "Manufacturer": "Quickie", - "Device Description": "Quickie Xtender", - "Device Code": "WPS1QU005", - "Quantity": 1, - "ADP Price": 4831.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Add-On Device", - "Manufacturer": "Sunrise Medical", - "Device Description": "Quickie Empulse R90", - "Device Code": "WM0002168", - "Quantity": 1, - "ADP Price": 4831.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Elevating Footrests", - "Manufacturer": "Amylior Inc.", - "Device Description": "Power Elevating & Articulating Legrests or Center mount foot platform", - "Device Code": "SEF4P0005", - "Quantity": 1, - "ADP Price": 2250.0, - "SN Required": "No" - }, - { - "Device Type": "Power Elevating Footrests", - "Manufacturer": "Motion Concepts", - "Device Description": "Power Elevating Legrests For Invacare,Quantum, AndQuickie Bases. Includes Legrests And Actuators.", - "Device Code": "SEFZG0005", - "Quantity": 1, - "ADP Price": 2214.0, - "SN Required": "No" - }, - { - "Device Type": "Power Elevating Footrests", - "Manufacturer": "Permobil", - "Device Description": "Power Elevating Articulating Leg Rests", - "Device Code": "SEF1P0005", - "Quantity": 1, - "ADP Price": 2274.0, - "SN Required": "No" - }, - { - "Device Type": "Power Elevating Footrests", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Power Elevating Articulating Leg Rests", - "Device Code": "SEFX13005", - "Quantity": 1, - "ADP Price": 2193.0, - "SN Required": "No" - }, - { - "Device Type": "Power Elevating Footrests", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Articulating Foot Platform", - "Device Code": "SEFX13010", - "Quantity": 1, - "ADP Price": 2411.0, - "SN Required": "No" - }, - { - "Device Type": "Power Elevating Footrests", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Tru-Balance 4 Power Articulating Foot Platform", - "Device Code": "WP0001926", - "Quantity": 1, - "ADP Price": 3125.0, - "SN Required": "No" - }, - { - "Device Type": "Power Elevating Footrests", - "Manufacturer": "Quickie", - "Device Description": "Power Elevating/Articulating Leg Rests", - "Device Code": "SEFQU0005", - "Quantity": 1, - "ADP Price": 2250.0, - "SN Required": "No" - }, - { - "Device Type": "Power Elevating Footrests", - "Manufacturer": "Sunrise Medical", - "Device Description": "Power elevating and articulating legrests", - "Device Code": "WP0000653", - "Quantity": 1, - "ADP Price": 2415.0, - "SN Required": "No" - }, - { - "Device Type": "Power Recline Only", - "Manufacturer": "Amylior Inc.", - "Device Description": "Power Recline With Integrated Shear Reduction (Isr)", - "Device Code": "SEC4P0045", - "Quantity": 1, - "ADP Price": 6436.0, - "SN Required": "No" - }, - { - "Device Type": "Power Recline Only", - "Manufacturer": "Motion Concepts", - "Device Description": "Bariatric POWER RECLINE SYSTEM WITH ESR FOR INVACARE, QUICKIE, AND QUANTUM BASES.", - "Device Code": "SECZG1010", - "Quantity": 1, - "ADP Price": 8223.0, - "SN Required": "No" - }, - { - "Device Type": "Power Recline Only", - "Manufacturer": "Motion Concepts", - "Device Description": "Ultra Low Maxx Power Recline", - "Device Code": "WP0001296", - "Quantity": 1, - "ADP Price": 7245.0, - "SN Required": "No" - }, - { - "Device Type": "Power Recline Only", - "Manufacturer": "Permobil", - "Device Description": "Corpus Power Positioning System With Power Recline Only", - "Device Code": "SEC1P0010", - "Quantity": 1, - "ADP Price": 6001.0, - "SN Required": "No" - }, - { - "Device Type": "Power Recline Only", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Quantum TRU-Balance 3 Redesigned Power Recline", - "Device Code": "WP0001163", - "Quantity": 1, - "ADP Price": 5434.0, - "SN Required": "No" - }, - { - "Device Type": "Power Recline Only", - "Manufacturer": "Quickie", - "Device Description": "Recline with Power Shear Reduction", - "Device Code": "WP0001149", - "Quantity": 1, - "ADP Price": 6563.0, - "SN Required": "No" - }, - { - "Device Type": "Power Recline Only", - "Manufacturer": "Sunrise Medical", - "Device Description": "Sedeo Pro Recline (150° Powered Recline w/ Shear Reduction)", - "Device Code": "WP0001632", - "Quantity": 1, - "ADP Price": 7004.0, - "SN Required": "No" - }, - { - "Device Type": "Power Recline Only", - "Manufacturer": "Sunrise Medical", - "Device Description": "Sedeo Pro Recline (130° Powered Semi-Recline)", - "Device Code": "WP0001633", - "Quantity": 1, - "ADP Price": 6521.0, - "SN Required": "No" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Fortress", - "Device Description": "1700fs -3 Wh.", - "Device Code": "WS1FS0015", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Fortress", - "Device Description": "1700fs -4 Wh.", - "Device Code": "WS1FS0020", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Invacare", - "Device Description": "Comet Pro 4 Wheel Scooter", - "Device Code": "WP0000121", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Invacare", - "Device Description": "Pegasus Metro 3-Wheel Scooter", - "Device Code": "WP0000122", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Invacare", - "Device Description": "Pegasus Metro 4-Wheel Scooter", - "Device Code": "WP0000123", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Invacare", - "Device Description": "Comet Ultra Scooter", - "Device Code": "WP0000546", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Invacare", - "Device Description": "Leo Scooter 3 Wheel", - "Device Code": "WP0001019", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Invacare", - "Device Description": "COLIBRI 4 -Wheel 18AH", - "Device Code": "WP0001285", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Invacare", - "Device Description": "Pegasus Pro 3 Wheel Scooter", - "Device Code": "WP0001399", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Invacare", - "Device Description": "Pegasus Pro 4 Wheel Scooter", - "Device Code": "WP0001400", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Invacare", - "Device Description": "Leo Scooter 4 Wheel", - "Device Code": "WS1IN0085", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Go Go Sport - 4 Wheel", - "Device Code": "WP0001075", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Go Go LX 4 Wheel", - "Device Code": "WP0001142", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Pursuit Scooter (Model SC713CA)", - "Device Code": "WP0001262", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Victory LX", - "Device Code": "WP0001273", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Jazzy Zero Turn", - "Device Code": "WP0001567", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Revo 2.0 (3 & 4 wheel)", - "Device Code": "WP0001573", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Go Go Elite Traveller 2", - "Device Code": "WP0002122", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Victory 10 (3 wheel Twin)", - "Device Code": "WS1X10110", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Victory 10.2 (3 & 4 wheel)", - "Device Code": "WS1X10115", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Shoprider/ Pihsiang", - "Device Description": "Cobra 778el -3 Wh.", - "Device Code": "WS1S70020", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Shoprider/ Pihsiang", - "Device Description": "Cobra 778el -4 Wh.", - "Device Code": "WS1S70025", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Shoprider/ Pihsiang", - "Device Description": "Sovereign 888 -4 Wh.", - "Device Code": "WS1S70032", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Shoprider/ Pihsiang", - "Device Description": "Landcruiser 889-3wh.", - "Device Code": "WS1S70035", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Shoprider/ Pihsiang", - "Device Description": "Landcruiser 889xls 4wh.", - "Device Code": "WS1S70036", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Shoprider/ Pihsiang", - "Device Description": "Voyager 778s -3 Wh.", - "Device Code": "WS1S70037", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Shoprider/ Pihsiang", - "Device Description": "Voyager 888sel -4 Wh.", - "Device Code": "WS1S70040", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Shoprider/ Pihsiang", - "Device Description": "Trailblazer 889sel 4wh.", - "Device Code": "WS1S70045", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Shoprider/ Pihsiang", - "Device Description": "Chameleon Gkb - 3 Wh", - "Device Code": "WS1S7005", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Shoprider/ Pihsiang", - "Device Description": "Chameleon Gkb - 4 Wh", - "Device Code": "WS1S7010", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Scooter", - "Manufacturer": "Sunrise Medical", - "Device Description": "S-410", - "Device Code": "WP0002088", - "Quantity": 1, - "ADP Price": 2395.0, - "SN Required": "Yes" - }, - { - "Device Type": "Power Tilt and Recline", - "Manufacturer": "Amylior Inc.", - "Device Description": "Cg Power Tilt & Power Recline WithIntegrated ShearReduction (Isr)", - "Device Code": "SEC4P0050", - "Quantity": 1, - "ADP Price": 9253.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt and Recline", - "Manufacturer": "Amylior Inc.", - "Device Description": "Bariatric CG Power Tilt and Power Recline With Integrated Shear Reduction (Isr)", - "Device Code": "SEC4P0070", - "Quantity": 1, - "ADP Price": 10460.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt and Recline", - "Manufacturer": "Motion Concepts", - "Device Description": "Ultra Low CG POWER TILT AND POWER RECLINE WITH ESR FOR INVACARE, QUANTUM, AND QUICKIE BASES.", - "Device Code": "SECZG0020", - "Quantity": 1, - "ADP Price": 8806.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt and Recline", - "Manufacturer": "Motion Concepts", - "Device Description": "Bariatric POWER TILT AND POWER RECLINE WITH ESR FOR INVACARE, QUICKIE, AND QUANTUM BASES.", - "Device Code": "SECZG1015", - "Quantity": 1, - "ADP Price": 9293.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt and Recline", - "Manufacturer": "Motion Concepts", - "Device Description": "Single Pivot POWER TILT AND POWER RECLINE FOR INVACARE, QUANTUM, AND QUICKIE BASES.", - "Device Code": "SECZG2010", - "Quantity": 1, - "ADP Price": 7647.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt and Recline", - "Manufacturer": "Motion Concepts", - "Device Description": "Single Pivot POWER TILT AND POWER RECLINE WITH ESR FOR INVACARE, QUANTUM, AND QUICKIE BASES.", - "Device Code": "SECZG2015", - "Quantity": 1, - "ADP Price": 8102.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt and Recline", - "Manufacturer": "Motion Concepts", - "Device Description": "Ultra Low Maxx CG Tilt and Power Recline", - "Device Code": "WP0001297", - "Quantity": 1, - "ADP Price": 8855.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt and Recline", - "Manufacturer": "Permobil", - "Device Description": "Corpus Power Positioning SystemWith 45 Deg. Power TiltAnd Power Recline", - "Device Code": "SEC1P0015", - "Quantity": 1, - "ADP Price": 8851.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt and Recline", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Quantum TRU-Balance 3 Power Tilt & Redesigned Recline", - "Device Code": "WP0001164", - "Quantity": 1, - "ADP Price": 9056.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt and Recline", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Tru-Balance 4 Power Tilt and Recline", - "Device Code": "WP0001925", - "Quantity": 1, - "ADP Price": 10875.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt and Recline", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Tru-Balance 4 Power Tilt and Recline - Without iLevel and Anterior Tilt", - "Device Code": "WP0002184", - "Quantity": 1, - "ADP Price": 10875.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt and Recline", - "Manufacturer": "Quickie", - "Device Description": "Smart Seat Tilt & Recline System", - "Device Code": "SECQU2005", - "Quantity": 1, - "ADP Price": 9257.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt and Recline", - "Manufacturer": "Quickie", - "Device Description": "Tilt & Recline with Power Shear Reduction", - "Device Code": "WP0001150", - "Quantity": 1, - "ADP Price": 9440.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt and Recline", - "Manufacturer": "Sunrise Medical", - "Device Description": "Sedeo Pro centre of gravity power tilt plus recline", - "Device Code": "WP0000651", - "Quantity": 1, - "ADP Price": 9096.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt and Recline", - "Manufacturer": "Sunrise Medical", - "Device Description": "Sedeo Pro Tilt & Recline (150° Powered Recline w/ Shear Reduction)", - "Device Code": "WP0001634", - "Quantity": 1, - "ADP Price": 10868.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt and Recline", - "Manufacturer": "Sunrise Medical", - "Device Description": "Sedeo Pro Tilt & Recline (130° Powered Semi-Recline)", - "Device Code": "WP0001635", - "Quantity": 1, - "ADP Price": 10686.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt Only", - "Manufacturer": "Amylior Inc.", - "Device Description": "Cg Power Tilt", - "Device Code": "SEC4P0040", - "Quantity": 1, - "ADP Price": 5228.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt Only", - "Manufacturer": "Amylior Inc.", - "Device Description": "Bariatric CG Power Tilt", - "Device Code": "SEC4P0060", - "Quantity": 1, - "ADP Price": 6436.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt Only", - "Manufacturer": "Motion Concepts", - "Device Description": "Bariatric POWER TILT ONLY FOR INVACARE, QUANTUM, AND QUICKIE BASES.", - "Device Code": "SECZG1005", - "Quantity": 1, - "ADP Price": 6436.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt Only", - "Manufacturer": "Motion Concepts", - "Device Description": "Single Pivot Power Tilt Only For Invacare, Quantum, and Quickie Bases", - "Device Code": "SECZG2005", - "Quantity": 1, - "ADP Price": 4528.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt Only", - "Manufacturer": "Motion Concepts", - "Device Description": "Ultra Low Maxx CG Tilt", - "Device Code": "WP0001295", - "Quantity": 1, - "ADP Price": 5232.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt Only", - "Manufacturer": "Permobil", - "Device Description": "Corpus Power Positioning System With 45 Deg. Power Tilt Only", - "Device Code": "SEC1P0005", - "Quantity": 1, - "ADP Price": 5309.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt Only", - "Manufacturer": "Permobil", - "Device Description": "Corpus Hd Power Positioning SystemWith 30 Deg.Power Tilt Only", - "Device Code": "SEC1P0105", - "Quantity": 1, - "ADP Price": 9173.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt Only", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Tru-Balance Bariatric Power Tilt", - "Device Code": "WP0001022", - "Quantity": 1, - "ADP Price": 5630.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt Only", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Quantum TRU-Balance 3 Power Positioning", - "Device Code": "WP0001162", - "Quantity": 1, - "ADP Price": 5211.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt Only", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Tru-Balance 4 Power Tilt - Without iLevel and Anterior Tilt", - "Device Code": "WP0002185", - "Quantity": 1, - "ADP Price": 6155.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt Only", - "Manufacturer": "Quickie", - "Device Description": "Power C.G. Tilt For Quickie G-424 & S-525", - "Device Code": "SECQU1005", - "Quantity": 1, - "ADP Price": 4684.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt Only", - "Manufacturer": "Quickie", - "Device Description": "Power C.G. Tilt For Quickie S-626", - "Device Code": "SECQU1010", - "Quantity": 1, - "ADP Price": 4684.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt Only", - "Manufacturer": "Quickie", - "Device Description": "Power C.G. Tilt For Quickie P-222se", - "Device Code": "SECQU1015", - "Quantity": 1, - "ADP Price": 4726.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt Only", - "Manufacturer": "Quickie", - "Device Description": "Power C.G. Tilt For Quickie Rhythm", - "Device Code": "SECQU3005", - "Quantity": 1, - "ADP Price": 4745.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt Only", - "Manufacturer": "Quickie", - "Device Description": "SPOT TILT", - "Device Code": "WP0000639", - "Quantity": 1, - "ADP Price": 3466.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt Only", - "Manufacturer": "Quickie", - "Device Description": "Spot Tilt II", - "Device Code": "WP0001148", - "Quantity": 1, - "ADP Price": 5332.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt Only", - "Manufacturer": "Sunrise Medical", - "Device Description": "Sedeo Pro centre of gravity power tilt", - "Device Code": "WP0000650", - "Quantity": 1, - "ADP Price": 5233.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt Only", - "Manufacturer": "Sunrise Medical", - "Device Description": "Sedeo Pro Tilt", - "Device Code": "WP0001631", - "Quantity": 1, - "ADP Price": 7004.0, - "SN Required": "No" - }, - { - "Device Type": "Power Tilt Only", - "Manufacturer": "Sunrise Medical", - "Device Description": "SEDEO Lite Tilt", - "Device Code": "WP0001892", - "Quantity": 1, - "ADP Price": 4137.0, - "SN Required": "No" - }, - { - "Device Type": "Projected Handrims (pair)", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Projected Handrims (pair)", - "Device Code": "WAMQ", - "Quantity": 1, - "ADP Price": 176.0, - "SN Required": "No" - }, - { - "Device Type": "PW - Adjustable Tension Back Upholstery over 18\" Frame Width", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "PW - Adjustable Tension Back Upholstery over 18\" Frame Width", - "Device Code": "WEPE", - "Quantity": 1, - "ADP Price": 189.0, - "SN Required": "No" - }, - { - "Device Type": "PW - Adjustable Tension Back Upholstery up to 18\" Frame Width", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "PW - Adjustable Tension Back Upholstery up to 18\" Frame Width", - "Device Code": "WEPD", - "Quantity": 1, - "ADP Price": 110.0, - "SN Required": "No" - }, - { - "Device Type": "PW - Angle Adjustable Footplates (pair)", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "PW - Angle Adjustable Footplates (pair)", - "Device Code": "WEPJ", - "Quantity": 1, - "ADP Price": 92.0, - "SN Required": "No" - }, - { - "Device Type": "PW - Custom Modifications", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "PW - Custom Modifications", - "Device Code": "PWCM", - "Quantity": 1, - "ADP Price": 40.0, - "SN Required": "No" - }, - { - "Device Type": "PW - Heavy Duty Model, Client Weight Exceeds 250 Lbs", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "PW - Heavy Duty Model, Client Weight Exceeds 250 Lbs", - "Device Code": "WEPF", - "Quantity": 1, - "ADP Price": 438.0, - "SN Required": "No" - }, - { - "Device Type": "PW - Heavy Duty Model, Client Weight Exceeds 350 Lbs", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "PW - Heavy Duty Model, Client Weight Exceeds 350 Lbs", - "Device Code": "WEPG", - "Quantity": 1, - "ADP Price": 525.0, - "SN Required": "No" - }, - { - "Device Type": "PW - Heavy Duty Model, Client Weight Exceeds 400 Lbs", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "PW - Heavy Duty Model, Client Weight Exceeds 400 Lbs", - "Device Code": "WEPH", - "Quantity": 1, - "ADP Price": 771.0, - "SN Required": "No" - }, - { - "Device Type": "PW - Oxygen Tank", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "PW - Oxygen Tank", - "Device Code": "WEPX", - "Quantity": 1, - "ADP Price": 106.0, - "SN Required": "No" - }, - { - "Device Type": "PW - Seat Depth Required is Greater Than 18\"", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "PW - Seat Depth Required is Greater Than 18\"", - "Device Code": "WEPB", - "Quantity": 1, - "ADP Price": 230.0, - "SN Required": "No" - }, - { - "Device Type": "PW - Seat Width Required is Greater Than 18\"", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "PW - Seat Width Required is Greater Than 18\"", - "Device Code": "WEPA", - "Quantity": 1, - "ADP Price": 339.0, - "SN Required": "No" - }, - { - "Device Type": "PW - Ventilator Tray", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "PW - Ventilator Tray", - "Device Code": "WEPY", - "Quantity": 1, - "ADP Price": 1331.0, - "SN Required": "No" - }, - { - "Device Type": "Quick Release Axles (pair)", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Quick Release Axles (pair)", - "Device Code": "WAMU", - "Quantity": 1, - "ADP Price": 87.0, - "SN Required": "No" - }, - { - "Device Type": "Recliner Option", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Recliner Option", - "Device Code": "WAMI", - "Quantity": 1, - "ADP Price": 415.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "5 Minds Mobility Inc.", - "Device Description": "ACe Comfort and ACe Contour Cushions", - "Device Code": "SE0001264", - "Quantity": 1, - "ADP Price": 376.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "5 Minds Mobility Inc.", - "Device Description": "ACe Complete Cushion 16\"x16\", 16\"x18\", 18\"x16\", 18\"x18\"", - "Device Code": "SE0001349", - "Quantity": 1, - "ADP Price": 790.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "5 Minds Mobility Inc.", - "Device Description": "ACe Complete Cushion 16\"x20\", 18\"x20\", 20\"x16\", 20\"x18\"", - "Device Code": "SE0001350", - "Quantity": 1, - "ADP Price": 804.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "5 Minds Mobility Inc.", - "Device Description": "ACe Complete Cushion 20\"x20\"", - "Device Code": "SE0001351", - "Quantity": 1, - "ADP Price": 818.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "5 Minds Mobility Inc.", - "Device Description": "ACe Contour VF Modular Cushion 16\"x16\", 16\"x18\", 18\"x16\", 18\"x18\"", - "Device Code": "SE0001352", - "Quantity": 1, - "ADP Price": 583.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "5 Minds Mobility Inc.", - "Device Description": "ACe Contour VF Modular Cushion 16\"x20\", 18\"x20\", 20\"x16\", 20\"x18\"", - "Device Code": "SE0001353", - "Quantity": 1, - "ADP Price": 597.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "5 Minds Mobility Inc.", - "Device Description": "ACe Contour VF Modular Cushion (Paediatric) 8\"x8\"", - "Device Code": "SE0001416", - "Quantity": 1, - "ADP Price": 535.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "5 Minds Mobility Inc.", - "Device Description": "ACE Comfort II Cushion 16\"x16\", 16\"x18\", 18\"x16\", 18\"x18\"", - "Device Code": "SE0001429", - "Quantity": 1, - "ADP Price": 604.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "5 Minds Mobility Inc.", - "Device Description": "ACe Comfort II Cushion 16\"x20\", 18\"x20\", 20\"x16\", 20\"x18\"", - "Device Code": "SE0001430", - "Quantity": 1, - "ADP Price": 618.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "5 Minds Mobility Inc.", - "Device Description": "ACe Comfort II Cushion 20\"x20\"", - "Device Code": "SE0001431", - "Quantity": 1, - "ADP Price": 631.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "ACTION XACT LP2", - "Device Code": "SE0000329", - "Quantity": 1, - "ADP Price": 598.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "Action Xact LP2 SIZES XP: WIDTH: 16\"/18\"/20\"/22\" DEPTH: 16\"/18\"/20\"", - "Device Code": "SE0000570", - "Quantity": 1, - "ADP Price": 599.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "Action Xact LP2 XP: SIZES: XP 1818 TO 22X20", - "Device Code": "SE0000571", - "Quantity": 1, - "ADP Price": 686.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "Professional Cushion 16x16,16x18,18x16,18x18", - "Device Code": "SESAN1105", - "Quantity": 1, - "ADP Price": 354.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "Professional Cushion 18x20,20x18,20x20", - "Device Code": "SESAN1115", - "Quantity": 1, - "ADP Price": 574.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "Centurian Cushion 16x16,16x81,18x16,18x18", - "Device Code": "SESAN2205", - "Quantity": 1, - "ADP Price": 229.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "Centurian Cushion 18x20,20x18,20x20", - "Device Code": "SESAN2210", - "Quantity": 1, - "ADP Price": 404.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "Pilot Cushion 16x16,16x18,18x16,18x18", - "Device Code": "SESAN3305", - "Quantity": 1, - "ADP Price": 267.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "Pilot Cushion 18x20,20x18,20x20", - "Device Code": "SESAN3310", - "Quantity": 1, - "ADP Price": 372.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "Commuter Cushion 16x16,16x18,18x16,18x18", - "Device Code": "SESAN4405", - "Quantity": 1, - "ADP Price": 207.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "Commuter Cushion 18x20,20x18,20x20", - "Device Code": "SESAN4410", - "Quantity": 1, - "ADP Price": 404.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "Commuter Cushion Small Sizes", - "Device Code": "SESAN4415", - "Quantity": 1, - "ADP Price": 319.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "Commuter Cushion Large Custom Sizes", - "Device Code": "SESAN4425", - "Quantity": 1, - "ADP Price": 396.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "Shear Smart Pad 16x16,16x18,18x16,18x18", - "Device Code": "SESAN5505", - "Quantity": 1, - "ADP Price": 181.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "Shear Smart Pad 18x20, 20x18, 20x20", - "Device Code": "SESAN5510", - "Quantity": 1, - "ADP Price": 216.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "Xact Lite Cushion 16x16 - 18x18", - "Device Code": "SESAN9015", - "Quantity": 1, - "ADP Price": 367.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "Xact Lite Cushion 18x20 - 20x20", - "Device Code": "SESAN9020", - "Quantity": 1, - "ADP Price": 427.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "Xact Classic Cushion 10x10,16x14,17x17,16x20,18x20,20x20", - "Device Code": "SESAN9905", - "Quantity": 1, - "ADP Price": 599.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "Xact Classic Cushion 16x16,16x18,18x16,18x18", - "Device Code": "SESAN9910", - "Quantity": 1, - "ADP Price": 513.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "Xact Individual Cushion All Custom Sizes", - "Device Code": "SESAN9915", - "Quantity": 1, - "ADP Price": 1031.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "Xact Soft Foam Cushion 16x16, 16x18, 18x16, 18x18", - "Device Code": "SESAN9980", - "Quantity": 1, - "ADP Price": 513.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Action Products", - "Device Description": "Xact Soft Foam Cushion 16x20,18x20, 20x16, 20x18, 20x20", - "Device Code": "SESAN9985", - "Quantity": 1, - "ADP Price": 647.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Solid Seat Package W/Universal Or E-Z Mount Hardware.", - "Device Code": "SES2L0005", - "Quantity": 1, - "ADP Price": 467.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Full Width Solid Seat Package With JOr Flush Or Drop Hooks& Hold Downs.", - "Device Code": "SES2L0010", - "Quantity": 1, - "ADP Price": 559.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Solid Seat Insert Package, Li'L Kiddos, 14\" Wide Or Less.", - "Device Code": "SES2L0020", - "Quantity": 1, - "ADP Price": 548.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Solid Seat Insert Package, Li'L Kiddos,Contoured, 14\" WideOr Less.", - "Device Code": "SES2L0025", - "Quantity": 1, - "ADP Price": 708.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Solid Seat Insert, Includes T-Nuts.", - "Device Code": "SES2L1005", - "Quantity": 1, - "ADP Price": 158.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Solid Seat Insert, Includes T-Nuts, Li'LKiddos,14\" Wide Or Less.", - "Device Code": "SES2L1010", - "Quantity": 1, - "ADP Price": 213.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Offset, T Style, I Style, Anti-Thrust OrMedial ThighSupport Solid Seat Insert, Includes T-Nuts.", - "Device Code": "SES2L1015", - "Quantity": 1, - "ADP Price": 232.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Quick Fit Anti-Thrust Or ContourSolid Seat Insert, IncludesT-Nuts.", - "Device Code": "SES2L1020", - "Quantity": 1, - "ADP Price": 423.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Sculptured Solid Set Insert, Includes T-Nuts, Custom.", - "Device Code": "SES2L1025", - "Quantity": 1, - "ADP Price": 862.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Quick-Fit Contoured, Adjustable Split,Or Foam Form SolidSeat Insert, Incudes T-Nuts.", - "Device Code": "SES2L1030", - "Quantity": 1, - "ADP Price": 491.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Adaptive Equipment Systems (Aes)", - "Device Description": "Oversize Upcharge For Seats Over 2o\" But Less Than 28\".", - "Device Code": "SES2L1035", - "Quantity": 1, - "ADP Price": 69.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "AMS AIRpad (All Sizes)", - "Device Code": "SE0001593", - "Quantity": 1, - "ADP Price": 358.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Advanced Mobility Systems Corp", - "Device Description": "Pro-Custom Cushion With Covers", - "Device Code": "SESAO0075", - "Quantity": 1, - "ADP Price": 486.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "CG Air Single or Dual Valve 10 x 10 - 20 x 20 (includes standard covers 2\",3\", 4\" high)", - "Device Code": "SE0001377", - "Quantity": 1, - "ADP Price": 435.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "CG Air Single or Dual Valve 10 x 10 - 20 x 20 (includes 3D mesh or incontinence covers 2\", 3\", 4\" high)", - "Device Code": "SE0001378", - "Quantity": 1, - "ADP Price": 511.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "CG Air Single or Dual Valve 22\" - 24\" wide (includes standard covers 2\", 3\",4\" high)", - "Device Code": "SE0001379", - "Quantity": 1, - "ADP Price": 664.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "CG Air Single or Dual Valve 22\" - 24\" wide (includes 3D mesh or incontinence covers 2\", 3\", 4\" high)", - "Device Code": "SE0001380", - "Quantity": 1, - "ADP Price": 664.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "CG Air Single or Dual Valve 26\"+ (includes standard covers 2\", 3\", 4\" high)", - "Device Code": "SE0001381", - "Quantity": 1, - "ADP Price": 704.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "CG Air Single or Dual Valve 26\"+ wide (includes 3D mesh or incontinence covers 2\", 3\", 4\" high)", - "Device Code": "SE0001382", - "Quantity": 1, - "ADP Price": 733.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "CG Air Deluxe 10 x 10 - 20 x 20 (includes standard covers)", - "Device Code": "SE0001383", - "Quantity": 1, - "ADP Price": 568.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "CG Air Deluxe 10 x 10 - 20 x 20 (includes 3D mesh or incontinence covers)", - "Device Code": "SE0001384", - "Quantity": 1, - "ADP Price": 635.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "CG Air Deluxe 22\" - 24\" wide (including standard covers)", - "Device Code": "SE0001385", - "Quantity": 1, - "ADP Price": 635.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "CG Air Deluxe 22\" - 24\" wide (including 3D mesh or incontinence covers)", - "Device Code": "SE0001386", - "Quantity": 1, - "ADP Price": 664.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "CG Air Deluxe 26\"+ wide (including standard covers)", - "Device Code": "SE0001387", - "Quantity": 1, - "ADP Price": 704.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "CG Air Deluxe 26\"+ wide (includes 3D mesh or incontinence covers)", - "Device Code": "SE0001388", - "Quantity": 1, - "ADP Price": 733.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "Performa CG Air Cushion with Standard Spacer Knit Cover, 14” to 20” wide, Single and Dual Valve", - "Device Code": "SE0002369", - "Quantity": 1, - "ADP Price": 560.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "Performa CG Air Cushion with Standard Spacer Knit Cover, 22”+ wide, Single and Dual Valve", - "Device Code": "SE0002370", - "Quantity": 1, - "ADP Price": 630.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "Performa CG Air Deluxe with Standard Spacer Knit Cover, 10” to 20” wide", - "Device Code": "SE0002371", - "Quantity": 1, - "ADP Price": 744.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "Performa CG Air Deluxe with Standard Spacer Knit Cover, 22” + wide", - "Device Code": "SE0002372", - "Quantity": 1, - "ADP Price": 825.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "Performa CG Air Cushion with External Incontinence Cover, 14” to 20” wide, Single and Dual Valve", - "Device Code": "SE0002373", - "Quantity": 1, - "ADP Price": 631.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "Performa CG Air Cushion with External Incontinence Cover, Single Valve, 22” + wide", - "Device Code": "SE0002374", - "Quantity": 1, - "ADP Price": 668.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "Performa CG Air Deluxe with External Incontinence Cover, 10” to 20” wide", - "Device Code": "SE0002375", - "Quantity": 1, - "ADP Price": 865.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "Performa CG Air Deluxe with External Incontinence Cover, 22” + wide", - "Device Code": "SE0002376", - "Quantity": 1, - "ADP Price": 945.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "Performa CG Air Cushion with 3D Spacer Knit Double Layer Cover, 14” to 20” wide, Single and Dual Valve", - "Device Code": "SE0002377", - "Quantity": 1, - "ADP Price": 591.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "Performa CG Air Cushion with 3D", - "Device Code": "SE0002378", - "Quantity": 1, - "ADP Price": 664.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "Performa CG Air Deluxe with 3D Spacer Knit Double Layer Cover, 10” to 20” wide", - "Device Code": "SE0002379", - "Quantity": 1, - "ADP Price": 825.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "Performa CG Air Deluxe with 3D Spacer Knit Double Layer Cover, 22” + wide", - "Device Code": "SE0002380", - "Quantity": 1, - "ADP Price": 905.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "Contour Seat Cushion, Standard Sizes", - "Device Code": "SES4P0010", - "Quantity": 1, - "ADP Price": 442.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "Contour Seat Cushion, Non-Standard Sizes", - "Device Code": "SES4P0015", - "Quantity": 1, - "ADP Price": 524.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Amylior Inc.", - "Device Description": "Contour Seat Cushion For Heavy Duty", - "Device Code": "SES4P0020", - "Quantity": 1, - "ADP Price": 618.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Blake Medical", - "Device Description": "Zentury, all sizes", - "Device Code": "SE0000996", - "Quantity": 1, - "ADP Price": 242.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Blake Medical", - "Device Description": "PC Cutback (sizes up to 20\")", - "Device Code": "SE0001537", - "Quantity": 1, - "ADP Price": 447.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Blake Medical", - "Device Description": "PC Cutback (size 22\")", - "Device Code": "SE0001538", - "Quantity": 1, - "ADP Price": 500.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Blake Medical", - "Device Description": "Geo-Matrix Bold (26\" and under)", - "Device Code": "SE0001608", - "Quantity": 1, - "ADP Price": 828.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Blake Medical", - "Device Description": "Geo-Matrix Bold (27\" and over)", - "Device Code": "SE0001609", - "Quantity": 1, - "ADP Price": 897.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Blake Medical", - "Device Description": "Geo Matrix Split", - "Device Code": "SE0002186", - "Quantity": 1, - "ADP Price": 604.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Blake Medical", - "Device Description": "Geomatrix Bronze", - "Device Code": "SESG00005", - "Quantity": 1, - "ADP Price": 368.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Blake Medical", - "Device Description": "Geomatrix Silver", - "Device Code": "SESG00010", - "Quantity": 1, - "ADP Price": 483.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Blake Medical", - "Device Description": "Geomatrix Gold, Gold+", - "Device Code": "SESG00015", - "Quantity": 1, - "ADP Price": 529.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Blake Medical", - "Device Description": "Geomatrix Gold, Gold+ Custom Sizes", - "Device Code": "SESG00020", - "Quantity": 1, - "ADP Price": 621.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Blake Medical", - "Device Description": "Geomatrix Platinum", - "Device Code": "SESG00025", - "Quantity": 1, - "ADP Price": 752.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Blake Medical", - "Device Description": "Geomatrix Hybrid Or Hybrid Deep", - "Device Code": "SESG00030", - "Quantity": 1, - "ADP Price": 562.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Broda", - "Device Description": "APP Seat Cushion (16\", 18\" and 20\" Seat Width)", - "Device Code": "SE0001879", - "Quantity": 1, - "ADP Price": 181.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Broda", - "Device Description": "APP Seat Cushion (22\" and 24\" Seat Width)", - "Device Code": "SE0001880", - "Quantity": 1, - "ADP Price": 192.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Broda", - "Device Description": "APP Seat Cushion (For 26\" and 28\" Seat Width)", - "Device Code": "SE0001881", - "Quantity": 1, - "ADP Price": 210.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Broda", - "Device Description": "Seat Pad", - "Device Code": "SESB-0010", - "Quantity": 1, - "ADP Price": 53.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Custom Fabricated", - "Device Description": "Flat Seat/Rigid Base, Includes Cover, Without Hardware", - "Device Code": "SESCF101L", - "Quantity": 1, - "ADP Price": 259.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Custom Fabricated", - "Device Description": "Wedged Seat (Thigh Bar), Includes Cover, Without Hardware", - "Device Code": "SESCF102L", - "Quantity": 1, - "ADP Price": 388.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Custom Fabricated", - "Device Description": "Contoured Seat, Includes Cover, Without Hardware", - "Device Code": "SESCF103L", - "Quantity": 1, - "ADP Price": 518.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Custom Fabricated", - "Device Description": "Sculptured Seat, Includes Cover, Without Hardware", - "Device Code": "SESCF104L", - "Quantity": 1, - "ADP Price": 621.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Custom Fabricated", - "Device Description": "Complex Indirect Molded Seat,Without Cover& Mounting Hardware", - "Device Code": "SESCF105L", - "Quantity": 1, - "ADP Price": 1259.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Drive Medical", - "Device Description": "Balanced Air Adj Cushion, 2\" Low Profile, includes cover", - "Device Code": "SE0001948", - "Quantity": 1, - "ADP Price": 249.55, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Drive Medical", - "Device Description": "Balanced Air Adj Cushion, 4\" High Profile, includes cover", - "Device Code": "SE0001949", - "Quantity": 1, - "ADP Price": 265.65, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "NXT BioFit Seat Cushions, all sizes", - "Device Code": "SE0001037", - "Quantity": 1, - "ADP Price": 411.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "NXT NüFit Seat Cushion, all sizes", - "Device Code": "SE0001038", - "Quantity": 1, - "ADP Price": 376.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "NXT BioFit Seat Cushion (20\"W x 20\"D- 24\"W x 22\"D", - "Device Code": "SE0001434", - "Quantity": 1, - "ADP Price": 431.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Dynamic Health Care Solutions", - "Device Description": "NXT BioFit Seat Cushion 26\" Wide", - "Device Code": "SE0001691", - "Quantity": 1, - "ADP Price": 480.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Serene Prime", - "Device Code": "SE0001225", - "Quantity": 1, - "ADP Price": 97.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Serene Champion", - "Device Code": "SE0001226", - "Quantity": 1, - "ADP Price": 311.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Serene Paramount", - "Device Code": "SE0001227", - "Quantity": 1, - "ADP Price": 311.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Serene Paramount Visco", - "Device Code": "SE0001228", - "Quantity": 1, - "ADP Price": 342.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Serene Paramount Gel", - "Device Code": "SE0001229", - "Quantity": 1, - "ADP Price": 362.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Supreme Cushion 14x14 Through 18x20", - "Device Code": "SESFM0015", - "Quantity": 1, - "ADP Price": 397.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Supreme Cushion 15x16 Through 20x20", - "Device Code": "SESFM0020", - "Quantity": 1, - "ADP Price": 414.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Supreme Cushion Custom Sizes", - "Device Code": "SESFM0025", - "Quantity": 1, - "ADP Price": 473.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Supreme Air Cushion 18x18 Through 20x20", - "Device Code": "SESFM0030", - "Quantity": 1, - "ADP Price": 500.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Supreme Air Cushion 18x19 Through 20x19", - "Device Code": "SESFM0035", - "Quantity": 1, - "ADP Price": 518.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Supreme Air Cushion Custom Sizes", - "Device Code": "SESFM0040", - "Quantity": 1, - "ADP Price": 542.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Ideal Cushion All Sizes", - "Device Code": "SESFM0050", - "Quantity": 1, - "ADP Price": 159.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Elite Cushion 16x16-20x20", - "Device Code": "SESFM0060", - "Quantity": 1, - "ADP Price": 259.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Elite Cushion Custom Sizes", - "Device Code": "SESFM0065", - "Quantity": 1, - "ADP Price": 293.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Supreme Ii Plus Cushion 14x14 Through 18x20", - "Device Code": "SESFM0070", - "Quantity": 1, - "ADP Price": 397.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Supreme Ii Plus Cushion 15x16 Through 20x20", - "Device Code": "SESFM0075", - "Quantity": 1, - "ADP Price": 414.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Supreme Ii Plus Cushion Custom Sizes", - "Device Code": "SESFM0080", - "Quantity": 1, - "ADP Price": 473.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Super Cushion For Kids 10x10 Through 16x16", - "Device Code": "SESFM0090", - "Quantity": 1, - "ADP Price": 397.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Super Cushion For Kids 10x12 Through 16x12", - "Device Code": "SESFM0095", - "Quantity": 1, - "ADP Price": 414.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Super Cushion For Kids Custom Sizes", - "Device Code": "SESFM0100", - "Quantity": 1, - "ADP Price": 473.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Supreme Gel Cushion 14x14 Through 18x20", - "Device Code": "SESFM0110", - "Quantity": 1, - "ADP Price": 466.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Supreme Gel Cushion 15x16 Through 20x20", - "Device Code": "SESFM0115", - "Quantity": 1, - "ADP Price": 483.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Supreme Gel Cushion Custom Sizes", - "Device Code": "SESFM0120", - "Quantity": 1, - "ADP Price": 535.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Future Mobility", - "Device Description": "Prism Supreme Heavy Duty Cushion", - "Device Code": "SESFM0125", - "Quantity": 1, - "ADP Price": 552.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Hoggi", - "Device Description": "Standard Seat Width", - "Device Code": "SE0000463", - "Quantity": 1, - "ADP Price": 132.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Hoggi", - "Device Description": "Non Standard Seat Width", - "Device Code": "SE0000464", - "Quantity": 1, - "ADP Price": 200.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Hoggi", - "Device Description": "Xps Adaptive Seat Cushion", - "Device Code": "SESK20050", - "Quantity": 1, - "ADP Price": 269.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Libra Cushion Stock Sizes up to 20\" wide", - "Device Code": "SE0001212", - "Quantity": 1, - "ADP Price": 514.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Libra Heavy Duty Cushion Stock Sizes greater than or equal to 21\" wide and greater than or equal to 22\" deep", - "Device Code": "SE0001237", - "Quantity": 1, - "ADP Price": 707.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Posture Seat Polymer Mini and Standard Cushion Stock Sizes", - "Device Code": "SE0001583", - "Quantity": 1, - "ADP Price": 445.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Libra Adjust Cushion Stock Sizes up to 20\" wide", - "Device Code": "SE0001692", - "Quantity": 1, - "ADP Price": 680.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Libra Adjust Cushion Stock Sizes greater than or equal to 21\" wide and greater than or equal to 22\" deep", - "Device Code": "SE0001693", - "Quantity": 1, - "ADP Price": 873.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Libra Adjust Heavy Duty Bariatric Cushion - 21\" to 24\" wide x 18\" to 22\" deep (client weight greater than 300 lbs)", - "Device Code": "SE0001694", - "Quantity": 1, - "ADP Price": 873.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Posture Seat Polymer Heavy Duty Bariatric Cushion Stock Sizes 22\"+ wide (600 lbs weight capacity)", - "Device Code": "SE0001888", - "Quantity": 1, - "ADP Price": 687.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Posture Seat Polymer Heavy Duty Bariatric Cushion Custom Sizes (specify width/depth, 600 lbs weight capacity)", - "Device Code": "SE0001889", - "Quantity": 1, - "ADP Price": 894.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Vi Cushion Stock Sizes up to 18\" wide", - "Device Code": "SES1M0005", - "Quantity": 1, - "ADP Price": 475.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Vi Heavy Duty Bariatric Cushion Custom Sizes (specify width/depth, 600 lbs weight capacity)", - "Device Code": "SES1M0011", - "Quantity": 1, - "ADP Price": 640.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Kidabra Cushion Stock Sizes", - "Device Code": "SES1M0015", - "Quantity": 1, - "ADP Price": 439.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Posture Seat Cushion Stock Sizes", - "Device Code": "SES1M0060", - "Quantity": 1, - "ADP Price": 383.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Posture Seat Mini Cushion Stock Sizes", - "Device Code": "SES1M0065", - "Quantity": 1, - "ADP Price": 382.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Invacare - Matrx Seating", - "Device Description": "Matrx Posture Seat Heavy Duty Bariatric Cushion Stock Sizes 22\" + wide (600 lbs weight capacity)", - "Device Code": "SES1M0066", - "Quantity": 1, - "ADP Price": 687.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Go Cushion Adult and PaediatricJGO14x14 to 18X24", - "Device Code": "SE0000323", - "Quantity": 1, - "ADP Price": 173.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Go - 19X15 to 24X24", - "Device Code": "SE0000324", - "Quantity": 1, - "ADP Price": 193.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay ION", - "Device Code": "SE0000348", - "Quantity": 1, - "ADP Price": 379.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay GO", - "Device Code": "SE0000350", - "Quantity": 1, - "ADP Price": 172.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Union Cushion 14X14 TO 18X18", - "Device Code": "SE0000352", - "Quantity": 1, - "ADP Price": 440.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Union Cushion 18X19 TO 24X24", - "Device Code": "SE0000353", - "Quantity": 1, - "ADP Price": 465.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Union Cushion with additional cover size 14X14 TO 18X18", - "Device Code": "SE0000354", - "Quantity": 1, - "ADP Price": 475.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Union Cushion with additional cover size 18X19 TO 24X24", - "Device Code": "SE0000355", - "Quantity": 1, - "ADP Price": 499.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Fusion Cushion regular size", - "Device Code": "SE0000950", - "Quantity": 1, - "ADP Price": 604.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Fusion Cushion Fluid width of 22\" or more OR Jay Fusion Cushion Fluid depth of 22\" or more", - "Device Code": "SE0000951", - "Quantity": 1, - "ADP Price": 677.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Fusion Cushion Fluid width and depth of 22\" or more", - "Device Code": "SE0000952", - "Quantity": 1, - "ADP Price": 750.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Fusion Air Single Valve Regular size", - "Device Code": "SE0000953", - "Quantity": 1, - "ADP Price": 604.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Fusion Air Single Valve width of 22\" or more OR Jay Fusion Air Single Valve depth of 22\" or more", - "Device Code": "SE0000954", - "Quantity": 1, - "ADP Price": 677.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Fusion Cushion Air Single Valve with width AND depth greater than 22\"", - "Device Code": "SE0000955", - "Quantity": 1, - "ADP Price": 750.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Fusion Cushion AIR Dual Valve regular size", - "Device Code": "SE0000956", - "Quantity": 1, - "ADP Price": 614.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Fusion Cushion AIr Dual Valve width of 22\" or more OR Jay Fusion Cushion AIr Dual Valve depth of 22\" or more", - "Device Code": "SE0000957", - "Quantity": 1, - "ADP Price": 688.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Fusion Cushion AIr Dual Valve with width AND depth greater than 22\"", - "Device Code": "SE0000958", - "Quantity": 1, - "ADP Price": 762.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Basic Pro Cushion", - "Device Code": "SE0001016", - "Quantity": 1, - "ADP Price": 121.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 Cushion 18x16, 18x18 With Standard Cover", - "Device Code": "SESJA0400", - "Quantity": 1, - "ADP Price": 471.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 Cushion 20x20 With Standard Cover", - "Device Code": "SESJA0405", - "Quantity": 1, - "ADP Price": 618.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 Cushion18x20, 15.5x20 With Standard Cover", - "Device Code": "SESJA0410", - "Quantity": 1, - "ADP Price": 543.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 Cushion 24x20 With Standard Cover", - "Device Code": "SESJA0415", - "Quantity": 1, - "ADP Price": 685.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 Cushion 15.5x 16, 15.5 X 18 With Standard Cover", - "Device Code": "SESJA0420", - "Quantity": 1, - "ADP Price": 471.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 Cushion 14x16 With Standard Cover", - "Device Code": "SESJA0425", - "Quantity": 1, - "ADP Price": 471.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 Standard Sizes With Air Exchange Cover", - "Device Code": "SESJA0440", - "Quantity": 1, - "ADP Price": 481.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 20x16, 20x18 With Air Exchange Cover", - "Device Code": "SESJA0441", - "Quantity": 1, - "ADP Price": 552.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 17x17 With Air Exchange Cover", - "Device Code": "SESJA0442", - "Quantity": 1, - "ADP Price": 481.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 20x20 With Air Exchange Cover", - "Device Code": "SESJA0445", - "Quantity": 1, - "ADP Price": 636.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 18x20, 15.5x20 With Air Exchange Cover", - "Device Code": "SESJA0450", - "Quantity": 1, - "ADP Price": 552.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 24x20 With Air Exchange Cover", - "Device Code": "SESJA0455", - "Quantity": 1, - "ADP Price": 681.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 Standard Sizes With Incontinent Cover", - "Device Code": "SESJA0460", - "Quantity": 1, - "ADP Price": 474.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 20x16, 20x18 With Incontinent Cover", - "Device Code": "SESJA0461", - "Quantity": 1, - "ADP Price": 543.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 17x17 With Incontinent Cover", - "Device Code": "SESJA0462", - "Quantity": 1, - "ADP Price": 474.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 20x20 With Incontinent Cover", - "Device Code": "SESJA0465", - "Quantity": 1, - "ADP Price": 628.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 18x20, 15.5x20 With Incontinent Cover", - "Device Code": "SESJA0470", - "Quantity": 1, - "ADP Price": 543.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 24x20 With Incontinent Cover", - "Device Code": "SESJA0475", - "Quantity": 1, - "ADP Price": 676.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 20x16", - "Device Code": "SESJA0480", - "Quantity": 1, - "ADP Price": 543.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 17x17", - "Device Code": "SESJA0485", - "Quantity": 1, - "ADP Price": 471.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 20x18", - "Device Code": "SESJA0490", - "Quantity": 1, - "ADP Price": 533.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 Deep Contour Standard Sizes", - "Device Code": "SESJA0500", - "Quantity": 1, - "ADP Price": 492.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 Deep Contour 20x16, 20x18, 16x20, 18x20", - "Device Code": "SESJA0505", - "Quantity": 1, - "ADP Price": 535.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 Deep Contour 20x20, 22x16, 22x18", - "Device Code": "SESJA0507", - "Quantity": 1, - "ADP Price": 619.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 Deep Contour 24x18", - "Device Code": "SESJA0510", - "Quantity": 1, - "ADP Price": 654.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 Deep Contourn with Solid Drop Seat Standard Sizes With Solid Drop Seat", - "Device Code": "SESJA0600", - "Quantity": 1, - "ADP Price": 516.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 Deep Contourn with Solid Drop Seat 20x16, 20x18, 16x20, 18x20, Solid Drop Seat Attached", - "Device Code": "SESJA0605", - "Quantity": 1, - "ADP Price": 574.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 2 Deep Contourn with Solid Drop Seat 20x20, 22x16, 22x18, Solid Drop Seat Attached", - "Device Code": "SESJA0610", - "Quantity": 1, - "ADP Price": 629.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "J-Gel Cushion 16\" & 18\" Deep", - "Device Code": "SESJA0700", - "Quantity": 1, - "ADP Price": 370.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "J-Gel Cushion 20\" Deep", - "Device Code": "SESJA0705", - "Quantity": 1, - "ADP Price": 370.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "J2 Plus Cushion, Ae Cover With Foam Kit", - "Device Code": "SESJA0750", - "Quantity": 1, - "ADP Price": 566.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "J2 Plus Cushion, Ae Cover With Custom Foam Kit", - "Device Code": "SESJA0755", - "Quantity": 1, - "ADP Price": 595.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "J2 Plus Cushion, Ae Cover With Fluid Pad", - "Device Code": "SESJA0760", - "Quantity": 1, - "ADP Price": 745.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "J2 Plus Cushion, Ls Inc. Cover With Foam Kit", - "Device Code": "SESJA0765", - "Quantity": 1, - "ADP Price": 609.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "J2 Plus Cushion, Ls Inc. Cover With Custom Foam Kit", - "Device Code": "SESJA0770", - "Quantity": 1, - "ADP Price": 597.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "J2 Plus Cushion, Ls Inc. Cover With Fluid Pad", - "Device Code": "SESJA0775", - "Quantity": 1, - "ADP Price": 745.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "J3 Cushion", - "Device Code": "SESJA0800", - "Quantity": 1, - "ADP Price": 604.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Combi Cushion 18x16 To 15.5x20", - "Device Code": "SESJA3010", - "Quantity": 1, - "ADP Price": 194.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Combi Cushion 20x18 With Back Support", - "Device Code": "SESJA3100", - "Quantity": 1, - "ADP Price": 183.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Combi Cushion 14x14/12x12 With Back Support", - "Device Code": "SESJA3200", - "Quantity": 1, - "ADP Price": 194.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Combi With Lumbar Support,RegularAdult Short 18x16", - "Device Code": "SESJA3310", - "Quantity": 1, - "ADP Price": 183.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Combi With Lumbar Support, Regular Adult", - "Device Code": "SESJA3315", - "Quantity": 1, - "ADP Price": 183.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Combi With Lumbar Support 20x18", - "Device Code": "SESJA3316", - "Quantity": 1, - "ADP Price": 179.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Combi With Lumbar Support 18x20, 16x20", - "Device Code": "SESJA3317", - "Quantity": 1, - "ADP Price": 179.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Combi With Lumbar Support,NarrowAdult Soft 15.5x16", - "Device Code": "SESJA3320", - "Quantity": 1, - "ADP Price": 183.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Combi With Lumbar Support 14x14, 12x12", - "Device Code": "SESJA3326", - "Quantity": 1, - "ADP Price": 153.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Combi Without Lumbar Support,RegularAdult Short 18x16", - "Device Code": "SESJA3330", - "Quantity": 1, - "ADP Price": 154.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Combi Without Lumbar Support, RegularAdult Soft 18x18", - "Device Code": "SESJA3335", - "Quantity": 1, - "ADP Price": 154.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Combi Without Lumbar Support 20x18", - "Device Code": "SESJA3336", - "Quantity": 1, - "ADP Price": 154.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Combi Without Lumbar Support 16x20, 18x20", - "Device Code": "SESJA3337", - "Quantity": 1, - "ADP Price": 154.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Combi Without Lumbar Support,NarrowAdult Short 15.5x16", - "Device Code": "SESJA3340", - "Quantity": 1, - "ADP Price": 154.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Combi Without Lumbar Support, Narrow Adult 15.5x18", - "Device Code": "SESJA3345", - "Quantity": 1, - "ADP Price": 154.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Combi Without Lumbar Support 14x14, 12x12", - "Device Code": "SESJA3346", - "Quantity": 1, - "ADP Price": 154.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay GS 10x13,12x15,14x17,16x19,18x20", - "Device Code": "SESJA5000", - "Quantity": 1, - "ADP Price": 512.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay GS Cushion Pressure Relief Pad With Incontinent Cover", - "Device Code": "SESJA5005", - "Quantity": 1, - "ADP Price": 605.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay GS Cushion Pressure Relief Pad With Air Exchange Cover", - "Device Code": "SESJA5010", - "Quantity": 1, - "ADP Price": 594.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Zip Cushion, All Sizes", - "Device Code": "SESJA5550", - "Quantity": 1, - "ADP Price": 411.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "J2 Base Standard Sizes", - "Device Code": "SESJA6800", - "Quantity": 1, - "ADP Price": 179.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "J2 Base Large Sizes", - "Device Code": "SESJA6810", - "Quantity": 1, - "ADP Price": 226.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "J-Gel Base", - "Device Code": "SESJA6830", - "Quantity": 1, - "ADP Price": 186.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "J2 Plus Cushion Foam Base", - "Device Code": "SESJA6835", - "Quantity": 1, - "ADP Price": 143.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Duo Cushion 16x16,16x18, 18x16,18x18Includes Solid Seat, 2 Covers & Hardware", - "Device Code": "SESJA8005", - "Quantity": 1, - "ADP Price": 354.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Duo Cushion Large Adult 20x18 Includes Solid Seat, 2 Covers & Hardware", - "Device Code": "SESJA8010", - "Quantity": 1, - "ADP Price": 392.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Duo Cushion 20x16 Includes Solid Seat, 2 Covers & Hardware", - "Device Code": "SESJA8015", - "Quantity": 1, - "ADP Price": 400.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Duo Cushion 17x16, 17x18 Includes Solid Seat, 2 Covers & Hardware", - "Device Code": "SESJA8017", - "Quantity": 1, - "ADP Price": 354.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Duo Cushion Narrow Pan 16x16,16x18, 18x16, 18x18Includes Cushion, 2 Covers & Hardware", - "Device Code": "SESJA8020", - "Quantity": 1, - "ADP Price": 347.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Duo Cushion Narrow Pan 20x16 Includes Solid Seat, 2 Covers & Hardware", - "Device Code": "SESJA8025", - "Quantity": 1, - "ADP Price": 392.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Duo Cushion Narrow Pan 17x16,17x18Includes Solid Seat, 2 Covers & Hardware", - "Device Code": "SESJA8027", - "Quantity": 1, - "ADP Price": 354.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Duo Cushion Narrow Pan 20x18Includes Cushion, 2 Covers & Hardware", - "Device Code": "SESJA8030", - "Quantity": 1, - "ADP Price": 392.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Duo Cushion Foam Cushion 16x16, 16x18, 18x16, 18x18", - "Device Code": "SESJA8040", - "Quantity": 1, - "ADP Price": 165.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Duo Cushion Foam Cushion 20x18", - "Device Code": "SESJA8050", - "Quantity": 1, - "ADP Price": 194.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Duo Cushion Foam Cushion 20x16", - "Device Code": "SESJA8055", - "Quantity": 1, - "ADP Price": 194.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Duo Cushion Foam Cushion 17x16, 17x18", - "Device Code": "SESJA8057", - "Quantity": 1, - "ADP Price": 165.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Fit Cushion Adjustable Contour Seat For 10\" Or 12\" Frame Width, Various Seat Depths", - "Device Code": "SESJA9700", - "Quantity": 1, - "ADP Price": 308.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Fit Cushion Adjustable Contour Seat For 14\" Or 16\" Frame Width, Various Seat Depths", - "Device Code": "SESJA9705", - "Quantity": 1, - "ADP Price": 343.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Fit Cushion Adjustable ContourSeat For 18\" Frame Width,Various Seat Depths", - "Device Code": "SESJA9710", - "Quantity": 1, - "ADP Price": 381.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Easy Cushion With Flat Or Curved Bottom Sizes 14x16 Through 18x18", - "Device Code": "SESJA9805", - "Quantity": 1, - "ADP Price": 387.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Easy Cushion With Flat Or Curved Bottom Sizes 18x20 Through 20x20", - "Device Code": "SESJA9810", - "Quantity": 1, - "ADP Price": 405.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Easy Foam Base With Flat Or Curved Bottom Sizes 14x16 Through 18x18", - "Device Code": "SESJA9815", - "Quantity": 1, - "ADP Price": 102.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay Easy Foam Base With Flat Or Curved Bottom Sizes 18x20 Through 20x20", - "Device Code": "SESJA9820", - "Quantity": 1, - "ADP Price": 116.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 3 Air Cushion - Single Valve", - "Device Code": "SESJA9905", - "Quantity": 1, - "ADP Price": 607.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 3 Air Cushion - Dual Valve", - "Device Code": "SESJA9910", - "Quantity": 1, - "ADP Price": 618.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 3 Air Cushion -Width X Depth Greater Than 21 Inches", - "Device Code": "SESJA9915", - "Quantity": 1, - "ADP Price": 752.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Jay 3 Air Cushion- Dual Valve -Width X Depth .gt.21 Inches", - "Device Code": "SESJA9920", - "Quantity": 1, - "ADP Price": 762.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Jay Medical", - "Device Description": "Xpress Standard Seat Cushion - Specify Short (900020/1) Or Long (900022/3)", - "Device Code": "SESKT2020", - "Quantity": 1, - "ADP Price": 173.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Kaji Corporation", - "Device Description": "Exgel OWL Cushion Regular (all sizes)", - "Device Code": "SE0001476", - "Quantity": 1, - "ADP Price": 604.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Kaji Corporation", - "Device Description": "Exgel OWL Cushion High (all sizes)", - "Device Code": "SE0001477", - "Quantity": 1, - "ADP Price": 638.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Kaji Corporation", - "Device Description": "Exgel OWL Cushion Contour (all sizes)", - "Device Code": "SE0001478", - "Quantity": 1, - "ADP Price": 620.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Kaji Corporation", - "Device Description": "Exgel OWL Cushion Deep Contour (all sizes)", - "Device Code": "SE0001479", - "Quantity": 1, - "ADP Price": 620.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Kaji Corporation", - "Device Description": "Exgel OWL Cushion Deep Contour Slim (all sizes)", - "Device Code": "SE0001480", - "Quantity": 1, - "ADP Price": 638.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Kaji Corporation", - "Device Description": "Exgel OWL Kids", - "Device Code": "SE0001518", - "Quantity": 1, - "ADP Price": 742.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Kaji Corporation", - "Device Description": "Exgel Standard Cushion (regular, all sizes)", - "Device Code": "SE0001519", - "Quantity": 1, - "ADP Price": 587.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Kaji Corporation", - "Device Description": "Exgel Standard Cushion (high, all sizes)", - "Device Code": "SE0001520", - "Quantity": 1, - "ADP Price": 604.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Kaji Corporation", - "Device Description": "Exgel Standard Cushion (anti-thrust, all sizes)", - "Device Code": "SE0001521", - "Quantity": 1, - "ADP Price": 638.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Kaji Corporation", - "Device Description": "OWL Kids Adjustable (all sizes)", - "Device Code": "SE0001616", - "Quantity": 1, - "ADP Price": 845.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Kaji Corporation", - "Device Description": "Exgel OWL Active Cushion (all sizes)", - "Device Code": "SE0001642", - "Quantity": 1, - "ADP Price": 949.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Kid Kart", - "Device Description": "Xpress Wedge Seat Cushion - Specify Short (900024/5) Or Long (900026/7)", - "Device Code": "SESKT2025", - "Quantity": 1, - "ADP Price": 66.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Kid Kart", - "Device Description": "Xpress Ledge Seat Cushion - Specify Short (900028/9) Or Long (900030/1)", - "Device Code": "SESKT2026", - "Quantity": 1, - "ADP Price": 319.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Kid Kart", - "Device Description": "Xpress Contour Adjustable Cushion - Specify Short (900312-28) Or Long (900329-36)", - "Device Code": "SESKT2030", - "Quantity": 1, - "ADP Price": 348.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom G Cushion 14 x 14 - 20 x 20", - "Device Code": "SE0001389", - "Quantity": 1, - "ADP Price": 135.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom P Cushion 14 x 14 - 20 x 20", - "Device Code": "SE0001391", - "Quantity": 1, - "ADP Price": 397.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom P Cushion 22 x 18 - 22 x 20", - "Device Code": "SE0001392", - "Quantity": 1, - "ADP Price": 480.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom S Cushion 14 x 14 - 20 x 20", - "Device Code": "SE0001393", - "Quantity": 1, - "ADP Price": 186.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom S Cushion 22 x 18 - 22 x 20", - "Device Code": "SE0001394", - "Quantity": 1, - "ADP Price": 276.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom SP Cushion Fluid 14 x 14 - 20 x 20", - "Device Code": "SE0001395", - "Quantity": 1, - "ADP Price": 480.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom SP Cushion Fluid 21 x 18 - 22 x 20", - "Device Code": "SE0001396", - "Quantity": 1, - "ADP Price": 573.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom SP Cushion Visco 14 x 14 - 20 x 20", - "Device Code": "SE0001397", - "Quantity": 1, - "ADP Price": 442.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom SP Cushion Visco 21 x 18 - 22 x 20", - "Device Code": "SE0001398", - "Quantity": 1, - "ADP Price": 535.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom CS Solid Seat Cushion", - "Device Code": "SE0001716", - "Quantity": 1, - "ADP Price": 271.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom CS Pediatric Solid Seat Cushion", - "Device Code": "SE0001717", - "Quantity": 1, - "ADP Price": 261.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom CS Solid Seat Interface", - "Device Code": "SE0001718", - "Quantity": 1, - "ADP Price": 247.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom CS Pediatric Solid Seat Interface", - "Device Code": "SE0001719", - "Quantity": 1, - "ADP Price": 247.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom CS Seat Cushion", - "Device Code": "SE0001720", - "Quantity": 1, - "ADP Price": 242.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom CS Cushion (Contoured)", - "Device Code": "SE0001781", - "Quantity": 1, - "ADP Price": 616.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom AS Cushion Standard sizes", - "Device Code": "SE0001930", - "Quantity": 1, - "ADP Price": 749.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom AS Cushion Plus Sizes up to 20x22", - "Device Code": "SE0001931", - "Quantity": 1, - "ADP Price": 797.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom ASP Cushion Standard Sizes", - "Device Code": "SE0001932", - "Quantity": 1, - "ADP Price": 776.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom ASP Cushion Plus Sizes up to 20x22", - "Device Code": "SE0001933", - "Quantity": 1, - "ADP Price": 825.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom Kids P - (PXP 08\"-16\")", - "Device Code": "SE0002126", - "Quantity": 1, - "ADP Price": 464.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ki Mobility", - "Device Description": "Axiom Kids SP - (PXSP 08\" - 16\")", - "Device Code": "SE0002127", - "Quantity": 1, - "ADP Price": 514.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Lpa Medical Inc.", - "Device Description": "Contour Seat Cushion With Perineal Abductor", - "Device Code": "SESO12005", - "Quantity": 1, - "ADP Price": 93.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Lpa Medical Inc.", - "Device Description": "Pre-Cure Cushion", - "Device Code": "SESO12010", - "Quantity": 1, - "ADP Price": 155.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "ML Cozy", - "Device Code": "SE0001090", - "Quantity": 1, - "ADP Price": 331.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "ML Extreme Comfort", - "Device Code": "SE0001091", - "Quantity": 1, - "ADP Price": 431.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Maple Leaf Wheelchair", - "Device Description": "ML Bariatric", - "Device Code": "SE0001092", - "Quantity": 1, - "ADP Price": 541.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Motion Concepts", - "Device Description": "Invacare Matrx Multi Cushion (16x16/18/20, 17x16/18/20, 18x16/18/20, 20x16/18/20)", - "Device Code": "SE0001941", - "Quantity": 1, - "ADP Price": 514.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Motion Concepts", - "Device Description": "Matrx Multi Heavy Duty Cushion (22x16/18/20/22) - Posture Seat with Gel Foam", - "Device Code": "SE0002007", - "Quantity": 1, - "ADP Price": 687.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Motion Concepts", - "Device Description": "Trx Onyx Seat 16-19\" Width", - "Device Code": "SESZG0005", - "Quantity": 1, - "ADP Price": 555.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Motion Concepts", - "Device Description": "Trx Onyx Seat 20-22\" Width", - "Device Code": "SESZG0010", - "Quantity": 1, - "ADP Price": 599.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Nighthawk", - "Device Description": "Upcharge For Custom Sized Or Oversized Cushions", - "Device Code": "SESNM0000", - "Quantity": 1, - "ADP Price": 42.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Nighthawk", - "Device Description": "Med Foam 1\" Thru 4\" With Cover", - "Device Code": "SESNM0010", - "Quantity": 1, - "ADP Price": 221.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Nighthawk", - "Device Description": "2\" Standard Foam With Cover", - "Device Code": "SESNM2000", - "Quantity": 1, - "ADP Price": 82.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Nighthawk", - "Device Description": "Superior Cushion With Cover", - "Device Code": "SESNM2050", - "Quantity": 1, - "ADP Price": 372.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Nova Seating", - "Device Description": "Nova Shape Seat - Custom Molded Seat Cushion", - "Device Code": "SE0001834", - "Quantity": 1, - "ADP Price": 1875.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Otto Bock", - "Device Description": "Terra Cushion 15\"x16\" to 20\"x18\"", - "Device Code": "SE0000689", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Otto Bock", - "Device Description": "Seat Finished With Spray Coating,Cover,Sewing Pattern", - "Device Code": "SESOB7100", - "Quantity": 1, - "ADP Price": 1710.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Otto Bock", - "Device Description": "Seat-Itemized Cushion (Unfinished)", - "Device Code": "SESOB7105", - "Quantity": 1, - "ADP Price": 1253.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Otto Bock", - "Device Description": "Standard Sizes", - "Device Code": "SESOB8040", - "Quantity": 1, - "ADP Price": 541.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Corpus Ergo Air", - "Device Code": "SE0001267", - "Quantity": 1, - "ADP Price": 325.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "M2 Cushion (Standard Sizes)", - "Device Code": "SE0001695", - "Quantity": 1, - "ADP Price": 404.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "M2 Cushion (Paediatric Sizes)", - "Device Code": "SE0001696", - "Quantity": 1, - "ADP Price": 380.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "M2 Cushion (Bariatric Sizes)", - "Device Code": "SE0001697", - "Quantity": 1, - "ADP Price": 469.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "M2 Cushion (Custom Sizes)", - "Device Code": "SE0001698", - "Quantity": 1, - "ADP Price": 483.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "M2 Cushion w/ Glidewear (Standard Sizes)", - "Device Code": "SE0001699", - "Quantity": 1, - "ADP Price": 424.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "M2 Cushion w/ Glidewear (Paediatric Sizes)", - "Device Code": "SE0001700", - "Quantity": 1, - "ADP Price": 414.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "M2 Cushion w/ Glidewear (Bariatric Sizes)", - "Device Code": "SE0001701", - "Quantity": 1, - "ADP Price": 483.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "M2 Cushion w/ Glidewear (Custom Sizes)", - "Device Code": "SE0001702", - "Quantity": 1, - "ADP Price": 497.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "M2 ATI Cushion (Standard Sizes)", - "Device Code": "SE0001703", - "Quantity": 1, - "ADP Price": 542.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "M2 ATI Cushion (Paediatric Sizes)", - "Device Code": "SE0001704", - "Quantity": 1, - "ADP Price": 528.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "M2 ATI Cushion (Bariatric Sizes)", - "Device Code": "SE0001705", - "Quantity": 1, - "ADP Price": 621.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "M2 ATI Cushion (Custom Sizes)", - "Device Code": "SE0001706", - "Quantity": 1, - "ADP Price": 635.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "M2 ATI Cushion w/ Glidewear (Standard Sizes)", - "Device Code": "SE0001707", - "Quantity": 1, - "ADP Price": 573.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "M2 ATI Cushion w/ Glidewear (Paediatric Sizes)", - "Device Code": "SE0001708", - "Quantity": 1, - "ADP Price": 562.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "M2 ATI Cushion w/ Glidewear (Bariatric Sizes)", - "Device Code": "SE0001709", - "Quantity": 1, - "ADP Price": 638.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "M2 ATI Cushion w/ Glidewear (Custom Sizes)", - "Device Code": "SE0001710", - "Quantity": 1, - "ADP Price": 656.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Roho Hybrid Select Seat Cushion withCover: SIZES:WIDTH: 14\"/15\"/16\"/17\"/18\"/19\"DEPTH: 14\"/15\"/16\"/17\"/18\"/20\"", - "Device Code": "SE0001854", - "Quantity": 1, - "ADP Price": 755.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Roho Hybrid Select Seat Cushion with Cover: SIZES: WIDTH: 20\"/22\" DEPTH: 16\"/17\"/18\"/20\"", - "Device Code": "SE0001855", - "Quantity": 1, - "ADP Price": 893.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Saddle 7 (Bariatric - All sizes)", - "Device Code": "SE0001907", - "Quantity": 1, - "ADP Price": 538.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Saddle 7 (Bariatric with Quadragel 3D- All sizes)", - "Device Code": "SE0001908", - "Quantity": 1, - "ADP Price": 745.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Ascent (Comfort-Tek or Stretch Air - Standard)", - "Device Code": "SE0001909", - "Quantity": 1, - "ADP Price": 276.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Ascent (Comfort-Tek or Stretch Air - Bariatric)", - "Device Code": "SE0001910", - "Quantity": 1, - "ADP Price": 379.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "ACTA-Embrace Cushion W/ATI, Ww\" X Dd\", Anti-Thrust, Comfort-Tek Cover", - "Device Code": "SE0002018", - "Quantity": 1, - "ADP Price": 514.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "ACTA-Embrace Cushion W/ATI, Ww\" X Dd\", Bar, Anti-Thrust, Comfort-Tek Cover", - "Device Code": "SE0002019", - "Quantity": 1, - "ADP Price": 647.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "ACTA-Embrace Cushion W/ATI, Ww\" X Dd\", Anti-Thrust, Comfort-Tek W/Glidewear Cover", - "Device Code": "SE0002020", - "Quantity": 1, - "ADP Price": 533.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "ACTA-Embrace Cushion W/ATI, Ww\" X Dd\", Bar, Anti-Thrust, Comfort-Tek W/Glidewear Cover", - "Device Code": "SE0002021", - "Quantity": 1, - "ADP Price": 667.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "ACTA-Embrace Cushion W/ATI, Ww\" X Dd\", Zero Elevation, Comfort-Tek W/Glidewear Cover", - "Device Code": "SE0002022", - "Quantity": 1, - "ADP Price": 533.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "ACTA-Embrace Cushion W/ATI, Ww\" X Dd\", Bar, Zero Elevation, Comfort-Tek W/Glidewear Cover", - "Device Code": "SE0002023", - "Quantity": 1, - "ADP Price": 667.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "ACTA-Embrace Cushion W/ATI, Ww\" X Dd\", Zero Elevation, Comfort-Tek Cover", - "Device Code": "SE0002024", - "Quantity": 1, - "ADP Price": 514.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "ACTA-Embrace Cushion W/ ATI, Ww\" X Dd\", Bar, Zero Elevation, Comfort-Tek Cover", - "Device Code": "SE0002025", - "Quantity": 1, - "ADP Price": 647.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "ACTA-Embrace Cushion W/ ATI, Ww\" X Dd\", Anti-Thrust, Stretch-Air Cover", - "Device Code": "SE0002026", - "Quantity": 1, - "ADP Price": 514.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "ACTA-Embrace Cushion W/ ATI, Ww\" X Dd\", Bar, Anti-Thrust, Stretch-Air Cover", - "Device Code": "SE0002027", - "Quantity": 1, - "ADP Price": 647.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "ACTA-Embrace Cushion W/ATI, Ww\" X Dd\", Anti-Thrust, Stretch-Air W/Glidewear Cover", - "Device Code": "SE0002028", - "Quantity": 1, - "ADP Price": 533.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "ACTA-Embrace Cushion W/ATI, Ww\" X Dd\", Bar, Anti-Thrust, Stretch-Air W/Glidewear Cover", - "Device Code": "SE0002029", - "Quantity": 1, - "ADP Price": 667.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "ACTA-Embrace Cushion W/ATI, Ww\" X Dd\", Zero Elevation, Stretch-Air W/Glidewear Cover", - "Device Code": "SE0002030", - "Quantity": 1, - "ADP Price": 533.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "ACTA-Embrace Cushion W/ATI, Ww\" X Dd\", Bar, Zero Elevation, Stretch-Air W/Glidewear Cover", - "Device Code": "SE0002031", - "Quantity": 1, - "ADP Price": 667.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "ACTA-Embrace Cushion W/ATI, Ww\" X Dd\", Zero Elevation, Stretch-Air Cover", - "Device Code": "SE0002032", - "Quantity": 1, - "ADP Price": 514.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "ACTA-Embrace Cushion W/ ATI, Ww\" X Dd\", Bar, Zero Elevation, Stretch-Air Cover", - "Device Code": "SE0002033", - "Quantity": 1, - "ADP Price": 647.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Incontinence Liner - Ordered With Cushion", - "Device Code": "SE0002034", - "Quantity": 1, - "ADP Price": 39.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Flat Bttm Rail Cuts", - "Device Code": "SE0002035", - "Quantity": 1, - "ADP Price": 40.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD) - Standard: Up To 20x18, W/Incontinence Liner, No Ischial Insert", - "Device Code": "SE0002095", - "Quantity": 1, - "ADP Price": 914.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Standard: Up To 20x18, W/Incontinence Liner, VISCO Foam Insert", - "Device Code": "SE0002096", - "Quantity": 1, - "ADP Price": 1004.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Standard: Up To 20x18, W/Incontinence Liner, Gel Insert", - "Device Code": "SE0002097", - "Quantity": 1, - "ADP Price": 1045.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Standard: Up To 20x18, W/Incontinence Liner, ROHO Insert", - "Device Code": "SE0002098", - "Quantity": 1, - "ADP Price": 1363.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Standard: Up To 20x18, W/Incontinence Liner, No Ischial Insert, ATI", - "Device Code": "SE0002099", - "Quantity": 1, - "ADP Price": 1194.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Standard: Up To 20x18, W/Incontinence Liner, VISCO Foam Insert, ATI", - "Device Code": "SE0002100", - "Quantity": 1, - "ADP Price": 1283.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Standard: Up To 20x18, W/Incontinence Liner, Gel Insert, ATI", - "Device Code": "SE0002101", - "Quantity": 1, - "ADP Price": 1321.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Standard: Up To 20x18, W/Incontinence Liner, ROHO Insert, ATI", - "Device Code": "SE0002102", - "Quantity": 1, - "ADP Price": 1642.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Non-standard: Up To 24x22, W/Incontinence Liner, No Ischial Insert", - "Device Code": "SE0002103", - "Quantity": 1, - "ADP Price": 1076.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Non-standard: Up To 24x22, W/Incontinence Liner, VISCO Foam Insert", - "Device Code": "SE0002104", - "Quantity": 1, - "ADP Price": 1166.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Non-standard: Up To 24x22, W/Incontinence Liner, Gel Insert", - "Device Code": "SE0002105", - "Quantity": 1, - "ADP Price": 1208.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Non-standard: Up To 24x22, W/Incontinence Liner, ROHO Insert", - "Device Code": "SE0002106", - "Quantity": 1, - "ADP Price": 1528.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Non-standard: Up To 24x22, W/Incontinence Liner, No Ischial Insert, ATI", - "Device Code": "SE0002107", - "Quantity": 1, - "ADP Price": 1356.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Non-standard: Up To 24x22, W/Incontinence Liner, VISCO Foam Insert, ATI", - "Device Code": "SE0002108", - "Quantity": 1, - "ADP Price": 1446.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Non-standard: Up To 24x22, W/Incontinence Liner, Gel Insert, ATI", - "Device Code": "SE0002109", - "Quantity": 1, - "ADP Price": 1487.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Non-standard: Up To 24x22, W/Incontinence Liner, ROHO Insert, ATI", - "Device Code": "SE0002110", - "Quantity": 1, - "ADP Price": 1814.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Bariatric: Over 24w, W/Incontinence Liner, No Ischial Insert", - "Device Code": "SE0002111", - "Quantity": 1, - "ADP Price": 1784.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Bariatric: Over 24w, W/Incontinence Liner, VISCO Foam Insert", - "Device Code": "SE0002112", - "Quantity": 1, - "ADP Price": 1873.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Bariatric: Over 24w, W/Incontinence Liner, Gel Insert", - "Device Code": "SE0002113", - "Quantity": 1, - "ADP Price": 1911.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Bariatric: Over 24w, W/Incontinence Liner, ROHO Insert", - "Device Code": "SE0002114", - "Quantity": 1, - "ADP Price": 2232.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Bariatric: Over 24w, W/Incontinence Liner, No Ischial Insert, ATI", - "Device Code": "SE0002115", - "Quantity": 1, - "ADP Price": 2062.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Bariatric: Over 24w, W/Incontinence Liner, VISCO Foam Insert, ATI", - "Device Code": "SE0002116", - "Quantity": 1, - "ADP Price": 2149.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Bariatric: Over 24w, W/Incontinence Liner, Gel Insert, ATI", - "Device Code": "SE0002117", - "Quantity": 1, - "ADP Price": 2191.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Custom Inception Seat Cushion (WW X DD)- Bariatric: Over 24w, W/Incontinence Liner, ROHO Insert, ATI", - "Device Code": "SE0002118", - "Quantity": 1, - "ADP Price": 2512.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Vicair O2 XXTRA Bariatric 500 Kg withIncotec Cover22\"x18\" -26\", 24\"x18\"-26\",26\"x18\"-26\",28\"x18\"-20\", 30\"x18\"", - "Device Code": "SE0002130", - "Quantity": 1, - "ADP Price": 828.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Vicair O2 XXTRA Bariatric 500 Kg withIncotec Cover30\"x20\"", - "Device Code": "SE0002131", - "Quantity": 1, - "ADP Price": 1000.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Vicair O2 XXTRA Bariatric 500 Kg with Air Exchange Cover 22\"x18\" -26\", 24\"x18\"-26\",26\"x18\"-26\",28\"x18\"-20\", 30\"x18\"", - "Device Code": "SE0002132", - "Quantity": 1, - "ADP Price": 807.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Vicair O2 XXTRA Bariatric 500 Kg withAir Exchange Cover30\"x20\"", - "Device Code": "SE0002133", - "Quantity": 1, - "ADP Price": 979.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Permobil", - "Device Description": "Ergo Seat - All Sizes", - "Device Code": "SES1P0005", - "Quantity": 1, - "ADP Price": 351.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Physipro", - "Device Description": "Ultra Cushion - All Sizes", - "Device Code": "SE0001120", - "Quantity": 1, - "ADP Price": 254.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Physipro", - "Device Description": "Contour Insert - All Sizes", - "Device Code": "SE0001610", - "Quantity": 1, - "ADP Price": 714.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Physipro", - "Device Description": "Contour Insert (Bariatric) - All Sizes", - "Device Code": "SE0001611", - "Quantity": 1, - "ADP Price": 759.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Physipro", - "Device Description": "Physiair - All Sizes", - "Device Code": "SE0001612", - "Quantity": 1, - "ADP Price": 638.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Physipro", - "Device Description": "Physiair (Bariatric) - All Sizes", - "Device Code": "SE0001613", - "Quantity": 1, - "ADP Price": 690.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Physipro", - "Device Description": "Siliko - All Sizes", - "Device Code": "SE0001614", - "Quantity": 1, - "ADP Price": 552.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Physipro", - "Device Description": "Siliko (Bariatric) - All Sizes", - "Device Code": "SE0001615", - "Quantity": 1, - "ADP Price": 759.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Physipro", - "Device Description": "Brio Seat Cushion Std. Sizes 14\" x 14\", 16\" x 16\", 16 x 18\", 18\" x 16\", 18\" x18\", 20\" x 20'", - "Device Code": "SE0001804", - "Quantity": 1, - "ADP Price": 289.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Physipro", - "Device Description": "Brio Seat Cushion Non Std. 21\" and less", - "Device Code": "SE0001805", - "Quantity": 1, - "ADP Price": 341.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Physipro", - "Device Description": "3D-Moulded Seat Cushion - Custom", - "Device Code": "SE0002148", - "Quantity": 1, - "ADP Price": 2210.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Positech Innovation Inc.", - "Device Description": "STOPUS anti-slip seat waterproof cushion multidensity foam (all sizes)", - "Device Code": "SE0001444", - "Quantity": 1, - "ADP Price": 650.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Positech Innovation Inc.", - "Device Description": "STOPUS (oversize) anti-slip waterproof seat cushion multidensity foam (all sizes)", - "Device Code": "SE0001445", - "Quantity": 1, - "ADP Price": 750.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Relax AirFlow Single & Dual Valve Cushion (All Sizes)", - "Device Code": "SE0001669", - "Quantity": 1, - "ADP Price": 587.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Relax Comfy", - "Device Code": "SESWM0030", - "Quantity": 1, - "ADP Price": 538.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Relax Firm", - "Device Code": "SESWM0040", - "Quantity": 1, - "ADP Price": 676.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Power Plus Mobility", - "Device Description": "Relax Soft", - "Device Code": "SESWM0050", - "Quantity": 1, - "ADP Price": 414.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Precision Rehab Manufacturing Inc.", - "Device Description": "Contoured-Fit (Moderate PositioningVisco-Foam)12X12 20X20", - "Device Code": "SE0000755", - "Quantity": 1, - "ADP Price": 446.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Precision Rehab Manufacturing Inc.", - "Device Description": "Contoured-Fit (Moderate PositioningGel Option)12x12 to 20x20", - "Device Code": "SE0000756", - "Quantity": 1, - "ADP Price": 446.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Precision Rehab Manufacturing Inc.", - "Device Description": "Contoured-Fit (Moderate PositioningAir Option)12x12 to 20x20", - "Device Code": "SE0000757", - "Quantity": 1, - "ADP Price": 567.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Precision Rehab Manufacturing Inc.", - "Device Description": "Contoured-Fit Agressive PositioningVisco-Foam12x12 to 20x20", - "Device Code": "SE0000758", - "Quantity": 1, - "ADP Price": 446.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Precision Rehab Manufacturing Inc.", - "Device Description": "Contoured-Fit Agressive PositioningGel Option12x12 to 20x20", - "Device Code": "SE0000759", - "Quantity": 1, - "ADP Price": 446.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Precision Rehab Manufacturing Inc.", - "Device Description": "Contoured-Fit Aggressive Positioning Air Option 12x12 to 20x20", - "Device Code": "SE0000760", - "Quantity": 1, - "ADP Price": 567.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Precision Rehab Manufacturing Inc.", - "Device Description": "Base Cushion Seat Waterproof Foam", - "Device Code": "SESWB0010", - "Quantity": 1, - "ADP Price": 1476.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Precision Rehab Manufacturing Inc.", - "Device Description": "Base Cushion Seat With All Modifications", - "Device Code": "SESWB0015", - "Quantity": 1, - "ADP Price": 1793.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Precision Rehab Manufacturing Inc.", - "Device Description": "Precision-Fit Cushion, Subtle, Moderate Or Aggressive Positioning. Includes Shape Adjustments, Inner Cover, Outer Cover.", - "Device Code": "SESWB0020", - "Quantity": 1, - "ADP Price": 931.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Precision Rehab Manufacturing Inc.", - "Device Description": "Precision-Fit Cushion Upcharge, Extra Seat Width 20\"-24\"", - "Device Code": "SESWB0022", - "Quantity": 1, - "ADP Price": 264.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Precision Rehab Manufacturing Inc.", - "Device Description": "Precision-Fit Cushion Upcharge, Extra Seat Depth 20\"-24\"", - "Device Code": "SESWB0024", - "Quantity": 1, - "ADP Price": 264.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth Solution SPP Cushion with liner - 10\"x10\" to 20\"x22\"", - "Device Code": "SE0002332", - "Quantity": 1, - "ADP Price": 462.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth Solution SPP Cushion with liner - 22\"x18\" - 24\"x24\"", - "Device Code": "SE0002333", - "Quantity": 1, - "ADP Price": 507.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth Essence Plus SPP with liner - up to 20\" width", - "Device Code": "SE0002334", - "Quantity": 1, - "ADP Price": 562.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth Essence Plus SPP with liner - above 20\" width", - "Device Code": "SE0002335", - "Quantity": 1, - "ADP Price": 596.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth Essence SPP Cushion with liner - up to 20\" width", - "Device Code": "SE0002336", - "Quantity": 1, - "ADP Price": 396.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth Essence SPP Cushion with liner - above 20\" width", - "Device Code": "SE0002337", - "Quantity": 1, - "ADP Price": 431.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth TRU Comfort 2 SPP Cushion with liner - 14\"x14\" to 20\"x24\"", - "Device Code": "SE0002338", - "Quantity": 1, - "ADP Price": 417.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth TRU Comfort 2 SPP Cushion with liner - 21\"x18\" to 24\"x24\"", - "Device Code": "SE0002339", - "Quantity": 1, - "ADP Price": 504.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth Glacial SP Cushion with liner - up to 15\" width", - "Device Code": "SE0002341", - "Quantity": 1, - "ADP Price": 244.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth Glacial SP Cushion with liner - 16\" to 20\" width", - "Device Code": "SE0002342", - "Quantity": 1, - "ADP Price": 331.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth Glacial SP Cushion with liner - 21\" width and above", - "Device Code": "SE0002343", - "Quantity": 1, - "ADP Price": 427.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth Spectrum Foam SPP Cushion with liner - 14\"x18\"", - "Device Code": "SE0002344", - "Quantity": 1, - "ADP Price": 462.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth Spectrum Foam SPP Cushion with liner - 16\"x15\" to 20\"x24\"", - "Device Code": "SE0002345", - "Quantity": 1, - "ADP Price": 496.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth Spectrum Foam SPP Cushion with liner - 22\"x16\" to 32\"x28\"", - "Device Code": "SE0002346", - "Quantity": 1, - "ADP Price": 724.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth Spectrum Gel SPP Cushion with liner - 14\"x18\"", - "Device Code": "SE0002347", - "Quantity": 1, - "ADP Price": 462.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth Spectrum Gel SPP Cushion with liner - 16\"x15\" to 20\"x24\"", - "Device Code": "SE0002348", - "Quantity": 1, - "ADP Price": 496.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth Spectrum Gel SPP Cushion with liner - 22\"x16\" to 24\"x26\"", - "Device Code": "SE0002349", - "Quantity": 1, - "ADP Price": 724.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth Zen SP Cushion with liner - up to 15” width", - "Device Code": "SE0002350", - "Quantity": 1, - "ADP Price": 376.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth Zen SP Cushion with liner - 16\" to 20\" width", - "Device Code": "SE0002351", - "Quantity": 1, - "ADP Price": 479.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth Zen SP Cushion with liner - 21\" width and above", - "Device Code": "SE0002352", - "Quantity": 1, - "ADP Price": 590.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth Premier P Cushion - width 20 inches and under", - "Device Code": "SE0002355", - "Quantity": 1, - "ADP Price": 466.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Pride Mobility Products", - "Device Description": "Stealth Premier P Cushion - width over 20 inches", - "Device Code": "SE0002356", - "Quantity": 1, - "ADP Price": 566.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Quickie", - "Device Description": "JAY X2 with cover", - "Device Code": "SE0001155", - "Quantity": 1, - "ADP Price": 580.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Quickie", - "Device Description": "2\", 3\" Or 4\" Cushion With Cover", - "Device Code": "SESQU0355", - "Quantity": 1, - "ADP Price": 105.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Quickie", - "Device Description": "Contour Seat - Tilt Fx", - "Device Code": "SESQU0400", - "Quantity": 1, - "ADP Price": 338.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ride Designs", - "Device Description": "Ride Java", - "Device Code": "SE0001223", - "Quantity": 1, - "ADP Price": 524.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ride Designs", - "Device Description": "Ride Custom Cushion 2", - "Device Code": "SE0001358", - "Quantity": 1, - "ADP Price": 1456.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ride Designs", - "Device Description": "Ride Custom AccuSoft Cushion", - "Device Code": "SE0001606", - "Quantity": 1, - "ADP Price": 1806.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ride Designs", - "Device Description": "Ride Custom Cushion 2 Bundle", - "Device Code": "SE0001873", - "Quantity": 1, - "ADP Price": 2332.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ride Designs", - "Device Description": "Ride Custom Accusoft Cushion Bundle", - "Device Code": "SE0001874", - "Quantity": 1, - "ADP Price": 2349.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Ride Designs", - "Device Description": "Ride Forward Cushion - All Sizes", - "Device Code": "SESR41020", - "Quantity": 1, - "ADP Price": 407.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "Custom (Made To Order) Cushion W/Cover", - "Device Code": "SESRO030L", - "Quantity": 2, - "ADP Price": 663.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "Adaptor 9x13x1\" (Maximum 5)", - "Device Code": "SESRO1105", - "Quantity": 5, - "ADP Price": 180.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "Mid-Profile, All Standard Adult & Paediatric Sizes Including Cover", - "Device Code": "SESRO2005", - "Quantity": 1, - "ADP Price": 568.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "Mid-Profile, Custom Sizes Including Cover", - "Device Code": "SESRO2010", - "Quantity": 1, - "ADP Price": 637.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "High-Profile, All Standard Adult & Paediatric Sizes Including Cover", - "Device Code": "SESRO3005", - "Quantity": 1, - "ADP Price": 561.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "High-Profile, Custom Sizes Including Cover", - "Device Code": "SESRO3010", - "Quantity": 1, - "ADP Price": 625.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "High-Profile - LTC Cushion, Including Cover", - "Device Code": "SESRO3015", - "Quantity": 1, - "ADP Price": 632.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "Low-Profile, All Standard Adult & Pediatric Sizes Including Cover", - "Device Code": "SESRO3105", - "Quantity": 1, - "ADP Price": 561.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "Low-Profile, Custom Sizes Including Cover", - "Device Code": "SESRO3110", - "Quantity": 1, - "ADP Price": 625.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "Low-Profile, LTC Cushion, Including Cover", - "Device Code": "SESRO3115", - "Quantity": 1, - "ADP Price": 632.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "Mini-Max Cushion, Standard Sizes (Does Not Include Cover)", - "Device Code": "SESRO4005", - "Quantity": 1, - "ADP Price": 513.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "Quatro Select, Low Or High Profile Cushion With Cover, Standard Sizes", - "Device Code": "SESRO7035", - "Quantity": 1, - "ADP Price": 620.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "Quatro Select Low Or High Profile Cushion, Custom Sizes With Cover", - "Device Code": "SESRO7040", - "Quantity": 1, - "ADP Price": 663.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "Quatro Select LTC Cushion, Including Cover", - "Device Code": "SESRO7055", - "Quantity": 1, - "ADP Price": 687.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "Enhancer, Standard Adult & Paediatric Sizes, Dual Valve, With Cover", - "Device Code": "SESRO8005", - "Quantity": 1, - "ADP Price": 561.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "Enhancer, Custom Sizes,Dual Valve,Cover", - "Device Code": "SESRO8010", - "Quantity": 1, - "ADP Price": 625.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "Airlite Cushion With Built In Cover All Sizes", - "Device Code": "SESRO9005", - "Quantity": 1, - "ADP Price": 388.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "Contour Select Cushion Standard Sizes", - "Device Code": "SESRO9020", - "Quantity": 1, - "ADP Price": 620.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "Contour Select Cushion Custom Sizes", - "Device Code": "SESRO9025", - "Quantity": 1, - "ADP Price": 663.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "Hybrid Elite/Hybrid Elite LTC Cushion, Single Valve With Cover, Sizes 14x14 , 20x20", - "Device Code": "SESRO9501", - "Quantity": 1, - "ADP Price": 640.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "Hybride Elite/Hybrid Elite LTC Cushion, Single Valve With Cover, Sizes 22x18, 24x20", - "Device Code": "SESRO9502", - "Quantity": 1, - "ADP Price": 652.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "Hybrid Elite/Hybrid Elite LTC Cushion, Dual Valve, With Cover Sizes14x14 ,20x20", - "Device Code": "SESRO9503", - "Quantity": 1, - "ADP Price": 681.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Roho", - "Device Description": "Hybrid Elite/Hybrid Elite LTC Cushion, Dual Valve, With Cover, Sizes 22x18, 24x20", - "Device Code": "SESRO9504", - "Quantity": 1, - "ADP Price": 693.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Star", - "Device Description": "Star Standard Air 2\" & 4\" Cushion Standard Sizes", - "Device Code": "SE0001545", - "Quantity": 1, - "ADP Price": 555.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Star", - "Device Description": "Star Standard Air 2\" & 4\" Cushion Custom Sizes (up to 21\" x 21\")", - "Device Code": "SE0001546", - "Quantity": 1, - "ADP Price": 620.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Star", - "Device Description": "Star Standard Air 3¿ Cushion Standard Sizes", - "Device Code": "SE0001547", - "Quantity": 1, - "ADP Price": 602.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Star", - "Device Description": "Star Standard Air 3\" Cushion Custom Sizes (up to 21\" x 21\")", - "Device Code": "SE0001548", - "Quantity": 1, - "ADP Price": 667.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Star", - "Device Description": "Star MAX Immerse Standard Air 5¿ Cushion Standard Sizes", - "Device Code": "SE0001549", - "Quantity": 1, - "ADP Price": 707.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Star", - "Device Description": "Star MAX Immerse Standard Air 5\" Cushion Custom Sizes (up to 21\" x 21\")", - "Device Code": "SE0001550", - "Quantity": 1, - "ADP Price": 772.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Star", - "Device Description": "Star Stabil-Air 2\" & 4¿ Cushion Standard Sizes", - "Device Code": "SE0001551", - "Quantity": 1, - "ADP Price": 727.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Star", - "Device Description": "Star Stabil-Air 2\" & 4\" Cushion Custom Sizes (up to 21\" x 21\")", - "Device Code": "SE0001552", - "Quantity": 1, - "ADP Price": 792.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Star", - "Device Description": "Star Stabil-Air 3¿ Cushion Standard Sizes", - "Device Code": "SE0001553", - "Quantity": 1, - "ADP Price": 776.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Star", - "Device Description": "Star Stabil-Air 3\" Cushion Custom Sizes (up to 21\" x 21\")", - "Device Code": "SE0001554", - "Quantity": 1, - "ADP Price": 841.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Star", - "Device Description": "Star Stabil-Air 5¿ Cushion Standard Sizes", - "Device Code": "SE0001555", - "Quantity": 1, - "ADP Price": 900.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Star", - "Device Description": "Star Stabil-Air 5\" Cushion Custom Sizes (up to 21\" x 21\")", - "Device Code": "SE0001556", - "Quantity": 1, - "ADP Price": 964.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Star", - "Device Description": "Star StarLock 5\" Cushion Standard Sizes", - "Device Code": "SE0001557", - "Quantity": 1, - "ADP Price": 731.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Star", - "Device Description": "Star StarLock 5\" Cushion Custom Sizes (up to 21\" x 21\")", - "Device Code": "SE0001558", - "Quantity": 1, - "ADP Price": 795.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Star", - "Device Description": "Star GUARD Standard Air 2\", 3\" & 4\" Cushion Standard Sizes", - "Device Code": "SE0001559", - "Quantity": 1, - "ADP Price": 817.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Star", - "Device Description": "Star GUARD Standard Air 2\", 3\" & 4\" Cushion Custom Sizes (up to 21\" x 21\")", - "Device Code": "SE0001560", - "Quantity": 1, - "ADP Price": 880.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Star", - "Device Description": "Star GUARD Standard Air 5\" Cushion All Sizes", - "Device Code": "SE0001561", - "Quantity": 1, - "ADP Price": 906.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Star", - "Device Description": "Star GUARD Stabil-Air 2\", 3\" & 4\" Cushion All Sizes", - "Device Code": "SE0001562", - "Quantity": 1, - "ADP Price": 1031.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Star", - "Device Description": "Star GUARD Stabil-Air 5\" Cushion All Sizes", - "Device Code": "SE0001563", - "Quantity": 1, - "ADP Price": 1057.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Star", - "Device Description": "Star GUARD StarLock 2\", 3\" & 4\" Cushion All Sizes", - "Device Code": "SE0001564", - "Quantity": 1, - "ADP Price": 992.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Star", - "Device Description": "Star GUARD StarLock 5\" Cushion All Sizes", - "Device Code": "SE0001565", - "Quantity": 1, - "ADP Price": 1031.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Essence Basic (sizes up to 20\" X 20\")", - "Device Code": "SE0001481", - "Quantity": 1, - "ADP Price": 335.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Essence Basic (sizes greater than 20\" X 20\")", - "Device Code": "SE0001482", - "Quantity": 1, - "ADP Price": 376.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Essence Low Contour (sizes greater than 20\" x 20\")", - "Device Code": "SE0001484", - "Quantity": 1, - "ADP Price": 414.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Essence Plus (sizes up to 20\" X 20\")", - "Device Code": "SE0001487", - "Quantity": 1, - "ADP Price": 500.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Essence Plus (sizes greater than to 20\" X 20\")", - "Device Code": "SE0001488", - "Quantity": 1, - "ADP Price": 562.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth Simplicity G (sizes up to 20\"x20\")", - "Device Code": "SE0001522", - "Quantity": 1, - "ADP Price": 214.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth Simplicity G (sizes greater than 20\"x20\")", - "Device Code": "SE0001523", - "Quantity": 1, - "ADP Price": 255.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth Tru Comfort 2 SPP (sizes up to 20\"x20\")", - "Device Code": "SE0001524", - "Quantity": 1, - "ADP Price": 355.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth Tru Comfort 2 SPP (sizes greater than 20\"x20\")", - "Device Code": "SE0001525", - "Quantity": 1, - "ADP Price": 397.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth Solution SPP (sizes up to 20\"x20\")", - "Device Code": "SE0001526", - "Quantity": 1, - "ADP Price": 400.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth Solution SPP (sizes greater than 20\"x20\")", - "Device Code": "SE0001527", - "Quantity": 1, - "ADP Price": 445.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth Spectrum Foam SPP (sizes up to 20\"x20\")", - "Device Code": "SE0001528", - "Quantity": 1, - "ADP Price": 400.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth Spectrum Foam SPP (sizes greater than 20\"x20\")", - "Device Code": "SE0001529", - "Quantity": 1, - "ADP Price": 435.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth Spectrum Gel SPP (sizes up to 20\"x20\")", - "Device Code": "SE0001530", - "Quantity": 1, - "ADP Price": 400.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth Spectrum Gel SPP (sizes greater than 20\"x20\")", - "Device Code": "SE0001531", - "Quantity": 1, - "ADP Price": 449.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth Glacial SP (up to 15\" wide)", - "Device Code": "SE0001619", - "Quantity": 1, - "ADP Price": 183.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth Glacial SP (16\" to 19\" wide)", - "Device Code": "SE0001620", - "Quantity": 1, - "ADP Price": 269.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth Glacial SP (20\" to 24\" wide)", - "Device Code": "SE0001621", - "Quantity": 1, - "ADP Price": 366.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth Premiere P (16\" to 20\" wide)", - "Device Code": "SE0001622", - "Quantity": 1, - "ADP Price": 404.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth Premiere P (greater than 20\" wide)", - "Device Code": "SE0001623", - "Quantity": 1, - "ADP Price": 504.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth Zen SP Cushion (sizes 10\" - 15\")", - "Device Code": "SE0001651", - "Quantity": 1, - "ADP Price": 314.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth Zen SP Cushion (sizes 16\" - 20\")", - "Device Code": "SE0001652", - "Quantity": 1, - "ADP Price": 417.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Stealth Products", - "Device Description": "Stealth Zen SP Cushion (sizes 21\" - 24\")", - "Device Code": "SE0001653", - "Quantity": 1, - "ADP Price": 528.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Sunrise Medical", - "Device Description": "Spex High-Contour sizes up to 14\"x16\"", - "Device Code": "SE0001496", - "Quantity": 1, - "ADP Price": 711.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Sunrise Medical", - "Device Description": "Spex High-Contour sizes from 16\"x16\" to 17\"x18\"", - "Device Code": "SE0001497", - "Quantity": 1, - "ADP Price": 735.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Sunrise Medical", - "Device Description": "Spex High-Contour sizes from 18\"x18\" to 18\"x20\"", - "Device Code": "SE0001498", - "Quantity": 1, - "ADP Price": 890.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Sunrise Medical", - "Device Description": "Spex High-Contour sizes from 20\"x20\" to 20\"x22\"", - "Device Code": "SE0001499", - "Quantity": 1, - "ADP Price": 956.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Sunrise Medical", - "Device Description": "Spex Super High-Contour sizes up to 14\"x16\"", - "Device Code": "SE0001500", - "Quantity": 1, - "ADP Price": 932.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Sunrise Medical", - "Device Description": "Spex Super High-Contour sizes from 16\"x16\" to 17\"x18\"", - "Device Code": "SE0001501", - "Quantity": 1, - "ADP Price": 963.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Sunrise Medical", - "Device Description": "Spex High-Contour sizes from 18\"x18\" to 20\"x21\"", - "Device Code": "SE0001502", - "Quantity": 1, - "ADP Price": 1094.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Sunrise Medical", - "Device Description": "Spex Flex Cushion Standard Contour Regular (12\"x14\" - 15\"x18\")", - "Device Code": "SE0001636", - "Quantity": 1, - "ADP Price": 1437.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Sunrise Medical", - "Device Description": "Spex Flex Cushion Standard Contour Regular (16\"x16\")", - "Device Code": "SE0001637", - "Quantity": 1, - "ADP Price": 1521.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Sunrise Medical", - "Device Description": "Spex Flex Cushion Standard Contour Large (16\"x18\" - 20\"x20\")", - "Device Code": "SE0001638", - "Quantity": 1, - "ADP Price": 1521.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Sunrise Medical", - "Device Description": "Spex Flex Cushion High Contour Regular (12\"x14\" - 15\"x18\")", - "Device Code": "SE0001639", - "Quantity": 1, - "ADP Price": 1364.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Sunrise Medical", - "Device Description": "Spex Flex Cushion High Contour Regular (16\"x16\")", - "Device Code": "SE0001640", - "Quantity": 1, - "ADP Price": 1445.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Sunrise Medical", - "Device Description": "Spex Flex Cushion High Contour Large (16\"x18\" - 20\"x20\")", - "Device Code": "SE0001641", - "Quantity": 1, - "ADP Price": 1445.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Sunrise Medical", - "Device Description": "JAY Syncra Cushion (w/ Visco Foam, all sizes)", - "Device Code": "SE0001675", - "Quantity": 1, - "ADP Price": 656.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Sunrise Medical", - "Device Description": "JAY Syncra Cushion (Jay Flow Fluid w/ Cryo Technology, all sizes)", - "Device Code": "SE0001676", - "Quantity": 1, - "ADP Price": 690.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Sunrise Medical", - "Device Description": "JAY Syncra Cushion (w/ ROHO Dry Flotation Air Bladder, all sizes)", - "Device Code": "SE0001677", - "Quantity": 1, - "ADP Price": 725.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Sunrise Medical", - "Device Description": "JAY Fusion Cryo (16\" - 21\" wide)", - "Device Code": "SE0001685", - "Quantity": 1, - "ADP Price": 749.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Sunrise Medical", - "Device Description": "JAY Fusion Cryo (22\" wide)", - "Device Code": "SE0001686", - "Quantity": 1, - "ADP Price": 783.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Sunrise Medical", - "Device Description": "Support Seat Cushion", - "Device Code": "SESM90020", - "Quantity": 1, - "ADP Price": 259.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Supracor", - "Device Description": "Classic Cushion 14x16-20x20", - "Device Code": "SESRR0010", - "Quantity": 1, - "ADP Price": 470.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Supracor", - "Device Description": "Classic Sling Bottom Cushion 14x16-20x20", - "Device Code": "SESRR0015", - "Quantity": 1, - "ADP Price": 489.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Supracor", - "Device Description": "Bariatric Cushion (Classic) Clb 20-24\"", - "Device Code": "SESRR0016", - "Quantity": 1, - "ADP Price": 652.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Supracor", - "Device Description": "Bariatric Cushion (Classic) Clb 25-28\"", - "Device Code": "SESRR0017", - "Quantity": 1, - "ADP Price": 750.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Supracor", - "Device Description": "Bariatric Cushion (Classic) Clb 29-31\"", - "Device Code": "SESRR0018", - "Quantity": 1, - "ADP Price": 897.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Supracor", - "Device Description": "Contoured Cushion 14x16-20x20", - "Device Code": "SESRR0020", - "Quantity": 1, - "ADP Price": 574.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Supracor", - "Device Description": "Contoured Sling Bottom Cushion 14x16-20x20", - "Device Code": "SESRR0025", - "Quantity": 1, - "ADP Price": 568.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Supracor", - "Device Description": "Slimline Cushion 16x16-20x18", - "Device Code": "SESRR0030", - "Quantity": 1, - "ADP Price": 380.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Supracor", - "Device Description": "Slimline Sling Bottom Cushion 16x16-20x18", - "Device Code": "SESRR0035", - "Quantity": 1, - "ADP Price": 405.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Supracor", - "Device Description": "Contoured Cushion, Standard Sizes", - "Device Code": "SESRR0060", - "Quantity": 1, - "ADP Price": 549.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Supracor", - "Device Description": "Paediatric Contoured Cushion, Custom Sizes", - "Device Code": "SESRR0065", - "Quantity": 1, - "ADP Price": 405.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Supracor", - "Device Description": "Corbee Cushion 10x10-14x14", - "Device Code": "SESRR0100", - "Quantity": 1, - "ADP Price": 296.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Supracor", - "Device Description": "Corbee Sling 10x10-14x14", - "Device Code": "SESRR0110", - "Quantity": 1, - "ADP Price": 320.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "The Comfort Company", - "Device Description": "Embrace Anti-Thrust CushionHook and loop non-skid bottom", - "Device Code": "SE0000113", - "Quantity": 1, - "ADP Price": 369.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "The Comfort Company", - "Device Description": "Embrace Zero Elevation CushionHook and Loop non-skid bottom", - "Device Code": "SE0000126", - "Quantity": 1, - "ADP Price": 438.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "The Comfort Company", - "Device Description": "Custom Embrace Zero ElevationCushionHook and Loop non skid bottom", - "Device Code": "SE0000129", - "Quantity": 1, - "ADP Price": 701.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "The Comfort Company", - "Device Description": "Custom Embrace Anti Thrust CushionHook and Loop non skid bottom", - "Device Code": "SE0000130", - "Quantity": 1, - "ADP Price": 701.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "The Comfort Company", - "Device Description": "Curve Cushion, Stretch Air Or Fusion Cover, All Sizes", - "Device Code": "SES7C0050", - "Quantity": 1, - "ADP Price": 116.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "The Comfort Company", - "Device Description": "Curve Cushion, Stretch Air Or Fusion Cover, Custom Sizes", - "Device Code": "SES7C0055", - "Quantity": 1, - "ADP Price": 211.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Varilite Medical Products", - "Device Description": "Junior Cushion", - "Device Code": "SE0001146", - "Quantity": 1, - "ADP Price": 562.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Varilite Medical Products", - "Device Description": "Proform Nx Cushion, Single, Dual, AllSizesIncludes Cover", - "Device Code": "SESVP0351", - "Quantity": 1, - "ADP Price": 575.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Varilite Medical Products", - "Device Description": "Evolution Wave, All Sizes, Includes Cover And Positioning Base", - "Device Code": "SESVP0401", - "Quantity": 1, - "ADP Price": 604.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Varilite Medical Products", - "Device Description": "Evolution Wave Bariatric CushionIncludes,Cover And Positioning Base", - "Device Code": "SESVP0402", - "Quantity": 1, - "ADP Price": 705.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Varilite Medical Products", - "Device Description": "Evolution Cushion Standard Or Psv, AllSizes,Includes Cover And Pressure Setting Valve", - "Device Code": "SESVP0406", - "Quantity": 1, - "ADP Price": 580.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Varilite Medical Products", - "Device Description": "Evolution Bariatric Cushion StandardOr Psv, All Sizes,Includes Cover And Pressure Setting Valve", - "Device Code": "SESVP0408", - "Quantity": 1, - "ADP Price": 616.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Varilite Medical Products", - "Device Description": "Zoid Cushion, All Sizes, Includes Cover", - "Device Code": "SESVP0500", - "Quantity": 1, - "ADP Price": 479.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Varilite Medical Products", - "Device Description": "Meridian Cushion, All Sizes, Includes Cover", - "Device Code": "SESVP0600", - "Quantity": 1, - "ADP Price": 543.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Varilite Medical Products", - "Device Description": "Meridian Bariatric Cushion, All Sizes, Includes Cover", - "Device Code": "SESVP0605", - "Quantity": 1, - "ADP Price": 652.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Varilite Medical Products", - "Device Description": "Meridian Wave Cushion, All Sizes, Includes Cover", - "Device Code": "SESVP0610", - "Quantity": 1, - "ADP Price": 636.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Varilite Medical Products", - "Device Description": "Meridian Wave Bariatric Cushion, All Sizes, Includes Cover", - "Device Code": "SESVP0615", - "Quantity": 1, - "ADP Price": 741.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Varilite Medical Products", - "Device Description": "Reflex Cushion, All Sizes, Includes Cover", - "Device Code": "SESVP6020", - "Quantity": 1, - "ADP Price": 342.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vicair", - "Device Description": "Vicair Active: Sizes 12X12 - 18X18", - "Device Code": "SE0001102", - "Quantity": 1, - "ADP Price": 500.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vicair", - "Device Description": "Vicair Active: Sizes 18X20 - 20X20", - "Device Code": "SE0001103", - "Quantity": 1, - "ADP Price": 549.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vicair", - "Device Description": "Academy Adjuster", - "Device Code": "SESV10020", - "Quantity": 1, - "ADP Price": 543.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vicair", - "Device Description": "Academy Vector", - "Device Code": "SESV10025", - "Quantity": 1, - "ADP Price": 584.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vicair", - "Device Description": "Upcharge For Custom Sizes", - "Device Code": "SESV11005", - "Quantity": 1, - "ADP Price": 69.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "Epic Cushion: standard sizes: 16x16 1/2 to 18x18", - "Device Code": "SE0000672", - "Quantity": 1, - "ADP Price": 373.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "Epic Cushion: custom sizes (up to 19x19)", - "Device Code": "SE0000673", - "Quantity": 1, - "ADP Price": 418.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "Epic Plus Cushion Standard Sizes 16x20 to 20x18", - "Device Code": "SE0000676", - "Quantity": 1, - "ADP Price": 418.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "V3 Cushion Standard Sizes", - "Device Code": "SE0001454", - "Quantity": 1, - "ADP Price": 683.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "V3 Cushion Custom Sizes (up to 20 x 19)", - "Device Code": "SE0001455", - "Quantity": 1, - "ADP Price": 840.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "V3 Cushion Bariatric Custom Sizes (up to 24\")", - "Device Code": "SE0001456", - "Quantity": 1, - "ADP Price": 929.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "V3 Gel Cushion Standard Sizes", - "Device Code": "SE0001457", - "Quantity": 1, - "ADP Price": 735.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "V3 Gel Cushion Custom Sizes (up to 20 x 19)", - "Device Code": "SE0001458", - "Quantity": 1, - "ADP Price": 904.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "V3 Gel Cushion Bariatric Custom Sizes (up to 24\")", - "Device Code": "SE0001459", - "Quantity": 1, - "ADP Price": 999.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "VerySOFT Cushion, Standard Sizes 16x16 1/2 to 20x18", - "Device Code": "SESVC4000", - "Quantity": 1, - "ADP Price": 590.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "Very Soft Drop-Seat; Standard Sizes 16x16 1/2 to 20x18", - "Device Code": "SESVC4030", - "Quantity": 1, - "ADP Price": 752.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "VerySOFT -Deep Leg Trough Cushion; Standard Sizes 16x16 1/2 to 20x18", - "Device Code": "SESVC4100", - "Quantity": 1, - "ADP Price": 585.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "VerySOFT- Deep Leg Trough -Drop Seat; Standard Sizes 16x16 1/2 to 20x18", - "Device Code": "SESVC4120", - "Quantity": 1, - "ADP Price": 793.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "VIVE Cushion; Standard Sizes 16x16 1/2 to 20x18", - "Device Code": "SESVC4150", - "Quantity": 1, - "ADP Price": 627.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "VIVE -Deep Leg Trough Cushion; Standard Sizes 16x16 1/2 to 20x18", - "Device Code": "SESVC4170", - "Quantity": 1, - "ADP Price": 658.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "VIVE -Deep Leg Trough -Drop Seat; Standard Sizes 16x16 1/2 to 20x18", - "Device Code": "SESVC4180", - "Quantity": 1, - "ADP Price": 858.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "Upcharge for custom Cushions Up To 20\" X 19\", Inclusive", - "Device Code": "SESVC4500", - "Quantity": 1, - "ADP Price": 116.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion", - "Manufacturer": "Vision Wheelchair Seating Systems Inc.", - "Device Description": "Upcharge for custom Cushions 20\"X20 - 24\"X24\"", - "Device Code": "SESVC4510", - "Quantity": 1, - "ADP Price": 169.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion Cover(s)", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Extra Cover Standard Sizes", - "Device Code": "SESND1050", - "Quantity": 2, - "ADP Price": 65.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion Cover(s)", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Extra Cover Non Standard Sizes", - "Device Code": "SESND1055", - "Quantity": 2, - "ADP Price": 99.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion Cover(s)", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Extra Cover Bariatric Sizes", - "Device Code": "SESND1060", - "Quantity": 2, - "ADP Price": 134.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion Cover(s)", - "Manufacturer": "Custom Fabricated", - "Device Description": "Removable Cover For Flat Seat, ForIncontinence(Maximum 2)", - "Device Code": "SEMCF105L", - "Quantity": 2, - "ADP Price": 108.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion Cover(s)", - "Manufacturer": "Custom Fabricated", - "Device Description": "Removable Cover For Wedged OrContoured Seat,For Incontinence (Maximum 2)", - "Device Code": "SEMCF106L", - "Quantity": 2, - "ADP Price": 155.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Cushion Cover(s)", - "Manufacturer": "Custom Fabricated", - "Device Description": "Removable Cover For Sculptured OrMolded Seat,For Incontinence (Maximum 2)", - "Device Code": "SEMCF107L", - "Quantity": 2, - "ADP Price": 216.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Hardware", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Complex Specialized Mounting Hardware - Including Hardware For Custom Molded Modular Systems", - "Device Code": "SESND1010", - "Quantity": 1, - "ADP Price": 259.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Hardware", - "Manufacturer": "Custom Fabricated", - "Device Description": "Strap Interface (2) Mounts Seat To Wheelchair", - "Device Code": "SEICF140L", - "Quantity": 2, - "ADP Price": 86.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Hardware", - "Manufacturer": "Custom Fabricated", - "Device Description": "Simple Seat Interface Mounts Seat To Wheelchair Frame", - "Device Code": "SEICF150L", - "Quantity": 2, - "ADP Price": 168.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Hardware", - "Manufacturer": "Custom Fabricated", - "Device Description": "Complex Interface Mounts Seat & Back To Wheelchair Frame", - "Device Code": "SEICF170L", - "Quantity": 1, - "ADP Price": 302.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Hardware", - "Manufacturer": "Custom Fabricated", - "Device Description": "Hardware To Mount Seat & Back Into Dynamic Tilt Wheelchair", - "Device Code": "SEICF180L", - "Quantity": 1, - "ADP Price": 492.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Hardware", - "Manufacturer": "Custom Fabricated", - "Device Description": "Hardware To Mount PositioningDevice IntoPaediatric Stroller", - "Device Code": "SEICF190L", - "Quantity": 1, - "ADP Price": 86.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Hardware", - "Manufacturer": "Custom Fabricated", - "Device Description": "Securing Hardware That Mounts Hardware To Mobility Device (Maximum 8)", - "Device Code": "SEICF191L", - "Quantity": 8, - "ADP Price": 22.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Hardware", - "Manufacturer": "Custom Fabricated", - "Device Description": "Seat Rigidizer - Flat Rigid Insert", - "Device Code": "SEICF192L", - "Quantity": 1, - "ADP Price": 52.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Solid Seat Insert", - "Device Code": "SESND1015", - "Quantity": 1, - "ADP Price": 69.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Drop Base And Hooks (4)", - "Device Code": "SESND1020", - "Quantity": 1, - "ADP Price": 216.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Roho Bolster", - "Device Code": "SESND1035", - "Quantity": 1, - "ADP Price": 155.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Custom Modifications And Sizing -Including Custom Sizes,Static Adductors & Pommels, Wedges& Anti-ThrustDevices, Leg Length Discrepancy Allowance (Maximum 6).", - "Device Code": "SESND1040", - "Quantity": 6, - "ADP Price": 69.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Subasis Bar, Complete, Including Hardware", - "Device Code": "SESND1041", - "Quantity": 1, - "ADP Price": 173.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Additional Pressure Relief - Specialty Foam, Air, Gel", - "Device Code": "SESND1045", - "Quantity": 1, - "ADP Price": 358.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Upgrade To Provide Extra PressureRelief,Gel/Foam/Air/Liquid Etc. (Maximum 2)", - "Device Code": "SEMCF203L", - "Quantity": 2, - "ADP Price": 129.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Pelvic Stabilizer (Maximum 2)", - "Device Code": "SEMCF204L", - "Quantity": 2, - "ADP Price": 185.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Single Complex Pelvic Stabilizer For Seat Or Back", - "Device Code": "SEMCF205L", - "Quantity": 1, - "ADP Price": 259.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Complex Pelvic Stabilizers, Each (Maximum 2)", - "Device Code": "SEMCF206L", - "Quantity": 2, - "ADP Price": 194.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Heavy Duty Upgrade To Reinforce Seat", - "Device Code": "SEMCF207L", - "Quantity": 1, - "ADP Price": 65.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Simple Cushion Secured In Front Of ARoho Cushion,Not Including Roho Cushion, Includes Cover", - "Device Code": "SEMCF208L", - "Quantity": 1, - "ADP Price": 173.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Contoured Cushion With TroughingSecured In Front Of A RohoCushion, Not Including Roho Cushion, Includes Cover", - "Device Code": "SEMCF209L", - "Quantity": 1, - "ADP Price": 328.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Add Waterproof Skin On Complex Indirect Molded Seat", - "Device Code": "SEMCF210L", - "Quantity": 2, - "ADP Price": 86.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Modify Or Refurbish Existing CustomFabricated Seat,Includes Parts, Hardware & Labour", - "Device Code": "SEMCF212L", - "Quantity": 1, - "ADP Price": 194.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Viscoelastic Foam Or Pudgee 1\"Thick/1 Square Foot(Maximum 2)", - "Device Code": "SEMCF401L", - "Quantity": 2, - "ADP Price": 52.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Polymer Supplement Pad(Maximum 2)", - "Device Code": "SEMCF402L", - "Quantity": 2, - "ADP Price": 129.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "2\" Convolute Foam Cut To Size (Maximum 2)", - "Device Code": "SEMCF403L", - "Quantity": 2, - "ADP Price": 35.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "3\" Convolute Foam Cut To Size(Maximum 2)", - "Device Code": "SEMCF404L", - "Quantity": 2, - "ADP Price": 39.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "4\" Convolute Foam Cut To Size(Maximum 2)", - "Device Code": "SEMCF405L", - "Quantity": 2, - "ADP Price": 43.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "2\" Polyfoam Cut To Size(Maximum 2)", - "Device Code": "SEMCF406L", - "Quantity": 2, - "ADP Price": 26.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "3\" Polyfoam Cut To Size(Maximum 2)", - "Device Code": "SEMCF407L", - "Quantity": 2, - "ADP Price": 30.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Seat Plaster Molding/Vacuum Form, for Custom Fabricated Device Only", - "Device Code": "SEUCF005L", - "Quantity": 1, - "ADP Price": 138.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Package 1 for Power Bases", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Seat Package 1 for Power Bases", - "Device Code": "WEPN", - "Quantity": 1, - "ADP Price": 663.0, - "SN Required": "No" - }, - { - "Device Type": "Seat Package 2 for Power Bases", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Seat Package 2 for Power Bases", - "Device Code": "WEPO", - "Quantity": 1, - "ADP Price": 682.0, - "SN Required": "No" - }, - { - "Device Type": "SE - Custom Modifications", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Custom Modifications Required To Adp Listed Wheelchair To Facilitate Installation Of Custom Fabricated PositioningDevices (Seating). Authorizer MustProvide Clinical RationalTo Support Request. Clinic MustProvide A BreakdownOf The Cost Of Parts And Labour (Not To Exceed $40.00/Hour).", - "Device Code": "SEMCF990L", - "Quantity": 1, - "ADP Price": 40.0, - "SN Required": "No" - }, - { - "Device Type": "SE - Custom Modifications", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Transfer Existing Adp ApprovedModular Seating SystemInto New Or Modified Adp ApprovedWheelchair -Labour Only, When No Parts Required", - "Device Code": "SEMND1005", - "Quantity": 1, - "ADP Price": 69.0, - "SN Required": "No" - }, - { - "Device Type": "SE - Custom Modifications", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Custom Modifications To An AdpListed Modular Seating Device& No Adp Code With Assigned Funding Is Available - Authorizer Must Provide Clinical Rationale To SupportRequest - Vendor Must ProvideBreakdown Of Cost Of Parts& Labour (Not To Exceed$40.00/Hour)", - "Device Code": "SEMND2005", - "Quantity": 1, - "ADP Price": 40.0, - "SN Required": "No" - }, - { - "Device Type": "SE - Custom Modifications", - "Manufacturer": "Custom Fabricated", - "Device Description": "Transfer Existing Adp ApprovedCustom Seating SystemInto A New Or Modified AdpApproved Wheelchair.Labour Only, No Parts Required.", - "Device Code": "SEUCF200L", - "Quantity": 1, - "ADP Price": 69.0, - "SN Required": "No" - }, - { - "Device Type": "Specialty Controls 1 Non Standard Joystick*", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Specialty Controls 1 Non Standard Joystick*", - "Device Code": "WEX1", - "Quantity": 1, - "ADP Price": 1103.0, - "SN Required": "No" - }, - { - "Device Type": "Specialty Controls 2 Chin/Rim Control*", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Specialty Controls 2 Chin/Rim Control*", - "Device Code": "WEX2", - "Quantity": 1, - "ADP Price": 2363.0, - "SN Required": "No" - }, - { - "Device Type": "Specialty Controls 3 Simple Touch*", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Specialty Controls 3 Simple Touch*", - "Device Code": "WEX3", - "Quantity": 1, - "ADP Price": 5276.0, - "SN Required": "No" - }, - { - "Device Type": "Specialty Controls 4 Proximity Control*", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Specialty Controls 4 Proximity Control*", - "Device Code": "WEX4", - "Quantity": 1, - "ADP Price": 5906.0, - "SN Required": "No" - }, - { - "Device Type": "Specialty Controls 5 Breath Control*", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Specialty Controls 5 Breath Control*", - "Device Code": "WEX5", - "Quantity": 1, - "ADP Price": 2363.0, - "SN Required": "No" - }, - { - "Device Type": "Specialty Controls 6 Scanners*", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Specialty Controls 6 Scanners*", - "Device Code": "WEX6", - "Quantity": 1, - "ADP Price": 3938.0, - "SN Required": "No" - }, - { - "Device Type": "Spoke Protectors (pair)", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Spoke Protectors (pair)", - "Device Code": "WAMP", - "Quantity": 1, - "ADP Price": 91.0, - "SN Required": "No" - }, - { - "Device Type": "Standard Manual Wheelchair Frame with Manual Dynamic Tilt", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Standard Manual Wheelchair Frame with Manual Dynamic Tilt", - "Device Code": "WANA", - "Quantity": 1, - "ADP Price": 945.0, - "SN Required": "No" - }, - { - "Device Type": "Stroller Handles/Paediatric", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Stroller Handles/Paediatric", - "Device Code": "WAMW", - "Quantity": 1, - "ADP Price": 116.0, - "SN Required": "No" - }, - { - "Device Type": "Swingaway Mounting Bracket", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Swingaway Mounting Bracket", - "Device Code": "WEPM", - "Quantity": 1, - "ADP Price": 232.0, - "SN Required": "No" - }, - { - "Device Type": "Titanium Frame *", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Titanium Frame *", - "Device Code": "WAMZ", - "Quantity": 1, - "ADP Price": 1181.0, - "SN Required": "No" - }, - { - "Device Type": "Tray", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Full Tray For Positioning Support Only- StandardAdult & Paediatric Sizes, Includes Mounting Hardware", - "Device Code": "SETND0005", - "Quantity": 1, - "ADP Price": 164.0, - "SN Required": "No" - }, - { - "Device Type": "Tray", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Full Tray Non Standard Size ForPositioning Support Only -Adult & Paediatric Sizes, Includes Mounting Hardware", - "Device Code": "SETND0010", - "Quantity": 1, - "ADP Price": 280.0, - "SN Required": "No" - }, - { - "Device Type": "Tray", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Half Tray For Positioning Support Only- StandardAdult & Paediatric Sizes, Includes Mounting Hardware", - "Device Code": "SETND0015", - "Quantity": 2, - "ADP Price": 203.0, - "SN Required": "No" - }, - { - "Device Type": "Tray", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Half Tray For Positioning Support Only- Non StandardAdult & Paediatric Sizes, Includes Mounting Hardware", - "Device Code": "SETND0020", - "Quantity": 2, - "ADP Price": 272.0, - "SN Required": "No" - }, - { - "Device Type": "Tray", - "Manufacturer": "Custom Fabricated", - "Device Description": "Plastic Tray, Includes Mounting Hardware", - "Device Code": "SETCF101L", - "Quantity": 1, - "ADP Price": 302.0, - "SN Required": "No" - }, - { - "Device Type": "Tray", - "Manufacturer": "Custom Fabricated", - "Device Description": "Wood/Arborite Tray, Includes Mounting Hardware", - "Device Code": "SETCF102L", - "Quantity": 1, - "ADP Price": 220.0, - "SN Required": "No" - }, - { - "Device Type": "Tray", - "Manufacturer": "Custom Fabricated", - "Device Description": "Customized Lexan Tray, Includes Mounting Hardware", - "Device Code": "SETCF103L", - "Quantity": 1, - "ADP Price": 362.0, - "SN Required": "No" - }, - { - "Device Type": "Tray", - "Manufacturer": "Custom Fabricated", - "Device Description": "Kydex Tray, Includes Mounting Hardware", - "Device Code": "SETCF104L", - "Quantity": 1, - "ADP Price": 311.0, - "SN Required": "No" - }, - { - "Device Type": "Tray Options", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Add Modular Elbow Or Hip Blocks ToAny Modular Tray -(Maximum 4)", - "Device Code": "SETND0030", - "Quantity": 4, - "ADP Price": 56.0, - "SN Required": "No" - }, - { - "Device Type": "Tray Options", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Add Padding To Any Tray", - "Device Code": "SETND0035", - "Quantity": 2, - "ADP Price": 65.0, - "SN Required": "No" - }, - { - "Device Type": "Tray Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Clear Tray Cover, Removable", - "Device Code": "SEMCF301L", - "Quantity": 1, - "ADP Price": 69.0, - "SN Required": "No" - }, - { - "Device Type": "Tray Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Small Tray Pad (Maximum 2)", - "Device Code": "SEMCF303L", - "Quantity": 2, - "ADP Price": 69.0, - "SN Required": "No" - }, - { - "Device Type": "Tray Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Large/Full Tray Pad (Maximum 2)", - "Device Code": "SEMCF304L", - "Quantity": 2, - "ADP Price": 125.0, - "SN Required": "No" - }, - { - "Device Type": "Tray Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Elbow Blocks (Maximum 2)", - "Device Code": "SEMCF305L", - "Quantity": 2, - "ADP Price": 73.0, - "SN Required": "No" - }, - { - "Device Type": "Tray Options", - "Manufacturer": "Custom Fabricated", - "Device Description": "Elbow Block Padding Including Cover (Maximum 2)", - "Device Code": "SEMCF306L", - "Quantity": 2, - "ADP Price": 52.0, - "SN Required": "No" - }, - { - "Device Type": "Unilateral Hand Brake", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Unilateral Hand Brake", - "Device Code": "AA9", - "Quantity": 1, - "ADP Price": 100.0, - "SN Required": "No" - }, - { - "Device Type": "Uni-Lateral Wheel Lock", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Uni-Lateral Wheel Lock", - "Device Code": "WAMN", - "Quantity": 1, - "ADP Price": 117.0, - "SN Required": "No" - }, - { - "Device Type": "Walker Addons", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Forearm Attachments", - "Device Code": "AA1", - "Quantity": 2, - "ADP Price": 200.0, - "SN Required": "No" - }, - { - "Device Type": "Walker Addons", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Heavy Duty Package Client Weight 275-350 lbs", - "Device Code": "AA2", - "Quantity": 1, - "ADP Price": 100.0, - "SN Required": "No" - }, - { - "Device Type": "Walker Addons", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Heavy Duty Package Client Weight 350-400 lbs", - "Device Code": "AA3", - "Quantity": 1, - "ADP Price": 150.0, - "SN Required": "No" - }, - { - "Device Type": "Walker Addons", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Heavy Duty Package Client Weight Exceeded 400 lbs", - "Device Code": "AA4", - "Quantity": 1, - "ADP Price": 200.0, - "SN Required": "No" - }, - { - "Device Type": "Walker Addons", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Adolescent Size Paediatric Specific Walker", - "Device Code": "AA5", - "Quantity": 1, - "ADP Price": 100.0, - "SN Required": "No" - }, - { - "Device Type": "Walker Addons", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Adolescent Size Paediatric Walking Frame", - "Device Code": "AA6", - "Quantity": 1, - "ADP Price": 200.0, - "SN Required": "No" - }, - { - "Device Type": "Walker Addons", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Adolescent Size Paediatric Standing Frame", - "Device Code": "AA7", - "Quantity": 1, - "ADP Price": 300.0, - "SN Required": "No" - }, - { - "Device Type": "Walker Addons", - "Manufacturer": "Approved ADP Manufacturers Only", - "Device Description": "Extra Wide Adult Wheeled Walker", - "Device Code": "AA8", - "Quantity": 1, - "ADP Price": 100.0, - "SN Required": "No" - } -] \ No newline at end of file diff --git a/fusion_claims/fusion_claims/data/ir_actions_server_data.xml b/fusion_claims/fusion_claims/data/ir_actions_server_data.xml deleted file mode 100644 index 6139945..0000000 --- a/fusion_claims/fusion_claims/data/ir_actions_server_data.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - Sync to Invoices - - - form,list - code - -if records: - # Filter to only ADP sales - adp_records = records.filtered(lambda r: r.x_fc_is_adp_sale and r.state == 'sale') - if adp_records: - action = adp_records.action_sync_adp_fields() - else: - action = { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'No ADP Sales', - 'message': 'Selected orders are not confirmed ADP sales.', - 'type': 'warning', - 'sticky': False, - } - } - - - diff --git a/fusion_claims/fusion_claims/data/ir_config_parameter_data.xml b/fusion_claims/fusion_claims/data/ir_config_parameter_data.xml deleted file mode 100644 index 3229971..0000000 --- a/fusion_claims/fusion_claims/data/ir_config_parameter_data.xml +++ /dev/null @@ -1,157 +0,0 @@ - - - - - - - - fusion_claims.vendor_code - - - - fusion_claims.adp_posting_base_date - 2026-01-23 - - - fusion_claims.adp_posting_frequency_days - 14 - - - - - fusion_claims.enable_email_notifications - True - - - fusion_claims.application_reminder_days - 4 - - - fusion_claims.application_reminder_2_days - 4 - - - - - fusion_claims.ai_model - gpt-4o-mini - - - fusion_claims.auto_parse_xml - True - - - - - fusion_claims.store_open_hour - 9.0 - - - fusion_claims.store_close_hour - 18.0 - - - - - fusion_claims.push_enabled - False - - - fusion_claims.push_advance_minutes - 30 - - - - - fusion_claims.field_sale_type - x_fc_sale_type - - - fusion_claims.field_so_client_type - x_fc_client_type - - - fusion_claims.field_so_authorizer - x_fc_authorizer_id - - - fusion_claims.field_invoice_type - x_fc_invoice_type - - - fusion_claims.field_inv_client_type - x_fc_client_type - - - fusion_claims.field_inv_authorizer - x_fc_authorizer_id - - - fusion_claims.field_product_code - x_fc_adp_device_code - - - fusion_claims.field_sol_serial - x_fc_serial_number - - - fusion_claims.field_aml_serial - x_fc_serial_number - - - - - fusion_claims.mod_default_email - hvmp@marchofdimes.ca - - - - - fusion_claims.twilio_enabled - False - - - fusion_claims.twilio_account_sid - - - - fusion_claims.twilio_auth_token - - - - fusion_claims.twilio_phone_number - - - - - - fusion_claims.mod_followup_interval_days - 14 - - - fusion_claims.mod_followup_escalation_days - 3 - - - - - fusion_claims.sa_mobility_email - samobility@ontario.ca - - - fusion_claims.sa_mobility_phone - 1-888-222-5099 - - - - - fusion_claims.sync_instance_id - - - - - diff --git a/fusion_claims/fusion_claims/data/ir_cron_data.xml b/fusion_claims/fusion_claims/data/ir_cron_data.xml deleted file mode 100644 index 8beb2ef..0000000 --- a/fusion_claims/fusion_claims/data/ir_cron_data.xml +++ /dev/null @@ -1,183 +0,0 @@ - - - - - - - Fusion Claims: Sync ADP Fields - - code - model._cron_sync_adp_fields() - 1 - hours - - - - - Fusion Claims: Renew Delivery Reminders - - code - model._cron_renew_delivery_reminders() - 1 - days - True - - - - - Fusion Claims: Renew Billing Reminders - - code - model._cron_renew_billing_reminders() - 1 - days - True - - - - - Fusion Claims: Renew Correction Reminders - - code - model._cron_renew_correction_reminders() - 1 - days - True - - - - - Fusion Claims: Auto-Close Billed Cases - - code - model._cron_auto_close_billed_cases() - 1 - days - True - - - - - Fusion Claims: Auto-Close ODSP Paid Cases - - code - model._cron_auto_close_odsp_paid_cases() - 1 - days - True - - - - - Fusion Claims: First Application Reminder - - code - model._cron_send_application_reminders() - 1 - days - True - - - - - - Fusion Claims: Second Application Reminder - - code - model._cron_send_application_reminders_2() - 1 - days - True - - - - - - Fusion Claims: Acceptance Reminder Emails - - code - model._cron_send_acceptance_reminders() - 1 - days - True - - - - - - - - - Fusion Claims: MOD Follow-up Scheduler - - code - model._cron_mod_schedule_followups() - 1 - days - True - - - - - - Fusion Claims: MOD Follow-up Escalation - - code - model._cron_mod_escalate_followups() - 1 - days - True - - - - - - Fusion Claims: Calculate Technician Travel Times - - code - model._cron_calculate_travel_times() - 1 - days - True - - - - - - Fusion Claims: Technician Push Notifications - - code - model._cron_send_push_notifications() - 15 - minutes - True - - - - - Fusion Claims: Sync Remote Tasks (Pull) - - code - model._cron_pull_remote_tasks() - 5 - minutes - True - - - - - Fusion Claims: Cleanup Old Shadow Tasks - - code - model._cron_cleanup_old_shadows() - 1 - days - True - - - - diff --git a/fusion_claims/fusion_claims/data/mail_activity_type_data.xml b/fusion_claims/fusion_claims/data/mail_activity_type_data.xml deleted file mode 100644 index a3a47c6..0000000 --- a/fusion_claims/fusion_claims/data/mail_activity_type_data.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - ADP Delivery Reminder - Complete delivery for ADP billing - fa-truck - 0 - days - sale.order - default - warning - - - - - ADP Billing Deadline - Complete ADP billing by Wednesday 6 PM - fa-file-invoice-dollar - 0 - days - account.move - default - warning - - - - - ADP Correction Required - Invoice needs correction and resubmission - fa-exclamation-triangle - 0 - days - account.move - default - danger - - - - - MOD Follow-up Call - Call client for March of Dimes case update - fa-phone - 14 - days - sale.order - default - warning - - diff --git a/fusion_claims/fusion_claims/data/mail_template_data.xml b/fusion_claims/fusion_claims/data/mail_template_data.xml deleted file mode 100644 index 572b87d..0000000 --- a/fusion_claims/fusion_claims/data/mail_template_data.xml +++ /dev/null @@ -1,174 +0,0 @@ - - - - - - - - - - ADP: Send Quotation (Landscape) - - {{ object.company_id.name }} - Quotation {{ object.name or 'n/a' }} - {{ (object.user_id.email_formatted or object.company_id.email_formatted or user.email_formatted) }} - {{ object.partner_id.id }} - -
      -
      -
      -

      - -

      -

      ADP Quotation

      -

      - Please find attached your quotation . -

      - - - - - - - - - - - - -
      Quotation Details
      Reference
      Date
      Authorizer
      Client Portion (25%)
      ADP Portion (75%)
      Total
      -
      -

      Attached: ADP Quotation (PDF)

      -
      -
      -

      Please review the attached quotation. If you have any questions or need assistance, do not hesitate to contact us.

      -
      - -
      --
      -
      -
      -
      -
      - {{ object.partner_id.lang }} - - -
      - - - - - - ADP: Sales Order Confirmation (Landscape) - - {{ object.company_id.name }} - Order Confirmation {{ object.name or 'n/a' }} - {{ (object.user_id.email_formatted or object.company_id.email_formatted or user.email_formatted) }} - {{ object.partner_id.id }} - -
      -
      -
      -

      - -

      -

      Order Confirmed

      -

      - Your ADP sales order has been confirmed. -

      - - - - - - - - - - - - -
      Order Details
      Reference
      Date
      Authorizer
      Client Portion (25%)
      ADP Portion (75%)
      Total
      -
      -

      Attached: Sales Order Confirmation (PDF)

      -
      -
      -

      Your order is being processed. We will keep you updated on the delivery status and any updates from the Assistive Devices Program.

      -
      - -
      --
      -
      -
      -
      -
      - {{ object.partner_id.lang }} - - -
      - - - - - - ADP: Send Invoice (Landscape) - - {{ object.company_id.name }} - Invoice {{ object.name or 'Draft' }} - {{ (object.invoice_user_id.email_formatted or object.company_id.email_formatted or user.email_formatted) }} - {{ object.partner_id.id }} - -
      -
      -
      -

      - -

      -

      Invoice

      -

      - Please find attached your invoice . -

      - - - - - - - - - - - -
      Invoice Details
      Invoice
      Date
      Due Date
      Type - Client Portion - ADP Portion -
      Amount Due
      -
      -

      Attached: Invoice (PDF)

      -
      - -
      -

      This invoice represents your client portion for the ADP-funded equipment. The remaining amount will be billed directly to the Assistive Devices Program.

      -
      -
      - -
      -

      Please review the attached invoice and process payment at your earliest convenience. Contact us if you have any questions.

      -
      -
      - - -
      --
      -
      -
      -
      -
      - {{ object.partner_id.lang }} - - -
      - -
      -
      diff --git a/fusion_claims/fusion_claims/data/pdf_template_data.xml b/fusion_claims/fusion_claims/data/pdf_template_data.xml deleted file mode 100644 index 48f8e2b..0000000 --- a/fusion_claims/fusion_claims/data/pdf_template_data.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/fusion_claims/fusion_claims/data/product_labor_data.xml b/fusion_claims/fusion_claims/data/product_labor_data.xml deleted file mode 100644 index 1af8108..0000000 --- a/fusion_claims/fusion_claims/data/product_labor_data.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - LABOR - CHARGED HOURLY - NON REFUNDABLE - LABOR - service - 75.00 - - - - - - - diff --git a/fusion_claims/fusion_claims/data/stock_location_data.xml b/fusion_claims/fusion_claims/data/stock_location_data.xml deleted file mode 100644 index c30d61d..0000000 --- a/fusion_claims/fusion_claims/data/stock_location_data.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - Loaner Stock - internal - - - - - - Loaner Checkout Sequence - fusion.loaner.checkout - LOAN/ - 5 - - - - - Loaner Equipment - - - Rollators - - - - Wheelchairs - - - - Powerchairs - - - - diff --git a/fusion_claims/fusion_claims/models/__init__.py b/fusion_claims/fusion_claims/models/__init__.py deleted file mode 100644 index 33231ce..0000000 --- a/fusion_claims/fusion_claims/models/__init__.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2025 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) -# Part of the Fusion Claim Assistant product family. - -from . import email_builder_mixin -from . import adp_posting_schedule -from . import res_company -from . import res_config_settings -from . import fusion_central_config -from . import fusion_adp_device_code -from . import product_template -from . import product_product -from . import sale_order -from . import sale_order_line -from . import account_move -from . import account_move_line -from . import account_payment -from . import account_payment_method_line -from . import submission_history -from . import fusion_loaner_checkout -from . import fusion_loaner_history -from . import client_profile -from . import adp_application_data -from . import xml_parser -from . import client_chat -from . import ai_agent_ext -from . import dashboard -from . import res_partner -from . import res_users -from . import technician_task -from . import task_sync -from . import technician_location -from . import push_subscription \ No newline at end of file diff --git a/fusion_claims/fusion_claims/models/account_move.py b/fusion_claims/fusion_claims/models/account_move.py deleted file mode 100644 index 3ed5517..0000000 --- a/fusion_claims/fusion_claims/models/account_move.py +++ /dev/null @@ -1,1217 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2025 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) -# Part of the Fusion Claim Assistant product family. - -import logging -from odoo import models, fields, api - -_logger = logging.getLogger(__name__) - - -class AccountMove(models.Model): - _name = 'account.move' - _inherit = ['account.move', 'fusion_claims.adp.posting.schedule.mixin'] - - # ========================================================================== - # FIELD FLAGS - # ========================================================================== - x_fc_is_adp_invoice = fields.Boolean( - compute='_compute_is_adp_invoice_flag', - string='Is ADP Invoice', - ) - - def _compute_is_adp_invoice_flag(self): - """Compute if this is an ADP invoice.""" - for move in self: - move.x_fc_is_adp_invoice = move._is_adp_invoice() - - def _compute_payment_state(self): - """Extend to auto-advance linked ODSP orders when invoice is paid.""" - old_states = {move.id: move.payment_state for move in self} - super()._compute_payment_state() - for move in self: - if move.payment_state in ('paid', 'in_payment') and old_states.get(move.id) != move.payment_state: - move._auto_advance_odsp_on_payment() - - x_fc_is_mod_invoice = fields.Boolean( - compute='_compute_is_mod_invoice', - string='Is MOD Invoice', - ) - - @api.depends('x_fc_invoice_type') - def _compute_is_mod_invoice(self): - for move in self: - move.x_fc_is_mod_invoice = move.x_fc_invoice_type == 'march_of_dimes' - - def _auto_advance_odsp_on_payment(self): - """When invoice is paid, auto-advance linked ODSP order to payment_received.""" - self.ensure_one() - so = self.x_fc_source_sale_order_id - if not so: - so = self.invoice_line_ids.mapped('sale_line_ids.order_id')[:1] - if not so or not so.x_fc_is_odsp_sale: - return - current_status = so._get_odsp_status() - eligible = {'pod_submitted', 'submitted_to_ow', 'payment_received'} - if current_status in eligible: - if current_status != 'payment_received': - so._odsp_advance_status( - 'payment_received', - f"Payment received on invoice {self.name}. Status auto-advanced.", - ) - _logger.info(f"Auto-advanced ODSP order {so.name} to payment_received") - if so.x_fc_odsp_division == 'ontario_works': - self._ow_schedule_delivery_activity(so) - - def _ow_schedule_delivery_activity(self, so): - """Schedule an activity on the OW sale order to arrange delivery.""" - from datetime import timedelta - try: - activity_type = self.env.ref('mail.mail_activity_data_todo') - so.activity_schedule( - 'mail.mail_activity_data_todo', - date_deadline=fields.Date.today() + timedelta(days=3), - summary="Schedule delivery for Ontario Works case", - note="Payment received on invoice %s. Please schedule delivery for this Ontario Works order." % self.name, - user_id=so.user_id.id or self.env.uid, - ) - except Exception as e: - _logger.warning(f"Could not schedule delivery activity for {so.name}: {e}") - - def action_mod_send_invoice(self): - """Send MOD invoice to the case worker via email.""" - self.ensure_one() - so = self.x_fc_source_sale_order_id - if not so: - from odoo.exceptions import UserError - raise UserError("No linked sale order found.") - - # Get case worker email from the sale order's case worker contact - case_worker = so.x_fc_case_worker - if not case_worker or not case_worker.email: - from odoo.exceptions import UserError - raise UserError( - "No case worker with email found on the sale order.\n\n" - "Please add the case worker contact in the sale order first." - ) - - # Generate MOD Invoice PDF - import base64 - from markupsafe import Markup - attachment_ids = [] - attachment_names = [] - Attachment = self.env['ir.attachment'].sudo() - try: - report = self.env.ref('fusion_claims.action_report_mod_invoice') - pdf_content, _ = report._render_qweb_pdf(report.id, [self.id]) - client_name = (so.partner_id.name or 'Client').replace(' ', '_').replace(',', '') - att = Attachment.create({ - 'name': f'Invoice - {client_name} - {self.name}.pdf', - 'type': 'binary', - 'datas': base64.b64encode(pdf_content), - 'res_model': 'account.move', - 'res_id': self.id, - 'mimetype': 'application/pdf', - }) - attachment_ids.append(att.id) - attachment_names.append(att.name) - except Exception as e: - import logging - logging.getLogger(__name__).error(f"Failed to generate MOD invoice PDF: {e}") - - client_name = so.partner_id.name or 'Client' - sender_name = (so.user_id or self.env.user).name - ref = so.x_fc_case_reference or '' - - body_html = so._mod_email_build( - title='Invoice Submitted', - summary=f'Please find attached the invoice for the accessibility modification project ' - f'for {client_name}.', - email_type='info', - sections=[('Invoice Details', [ - ('Invoice', self.name), - ('Client', client_name), - ('HVMP Reference', ref or 'N/A'), - ('Amount', f'${self.amount_total:,.2f}'), - ])], - note='Please process the payment as per the Payment Commitment Agreement terms.', - attachments_note=', '.join(attachment_names) if attachment_names else None, - sender_name=sender_name, - ) - - subject = f'Invoice - {ref} - {client_name}' if ref else f'Invoice - {client_name} - {self.name}' - - cc_list = [] - if so.user_id and so.user_id.email: - cc_list.append(so.user_id.email) - - self.env['mail.mail'].sudo().create({ - 'subject': subject, - 'body_html': body_html, - 'email_to': case_worker.email, - 'email_cc': ', '.join(cc_list) if cc_list else '', - 'model': 'account.move', - 'res_id': self.id, - 'attachment_ids': [(6, 0, attachment_ids)] if attachment_ids else False, - }).send() - - # Log to chatter on both invoice and sale order - so._email_chatter_log('MOD Invoice sent', case_worker.email, - ', '.join(cc_list) if cc_list else None, - [f'Invoice: {self.name}'] + ([f'Attachments: {", ".join(attachment_names)}'] if attachment_names else [])) - self.message_post( - body=Markup( - f'
      ' - f'Invoice sent to case worker: {case_worker.name} ({case_worker.email})' - f'
      ' - ), - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'Invoice Sent', - 'message': f'Invoice sent to {case_worker.name} ({case_worker.email})', - 'type': 'success', - 'sticky': False, - }, - } - - # ========================================================================== - # INVOICE TYPE AND CLIENT TYPE FIELDS - # ========================================================================== - x_fc_invoice_type = fields.Selection( - selection=[ - ('adp', 'ADP'), - ('adp_client', 'ADP Client Portion'), - ('adp_odsp', 'ADP/ODSP'), - ('odsp', 'ODSP'), - ('wsib', 'WSIB'), - ('direct_private', 'Direct/Private'), - ('insurance', 'Insurance'), - ('march_of_dimes', 'March of Dimes'), - ('muscular_dystrophy', 'Muscular Dystrophy'), - ('other', 'Others'), - ('rental', 'Rentals'), - ('hardship', 'Hardship Funding'), - ('regular', 'Regular'), - ], - string='Invoice Type', - tracking=True, - help='Type of invoice for billing purposes', - ) - x_fc_client_type = fields.Selection( - selection=[ - ('REG', 'REG'), - ('ODS', 'ODS'), - ('OWP', 'OWP'), - ('ACS', 'ACS'), - ('LTC', 'LTC'), - ('SEN', 'SEN'), - ('CCA', 'CCA'), - ], - string='Client Type', - tracking=True, - help='Client type for ADP portion calculations. REG = 75%/25%, others = 100%/0%', - ) - - # Authorizer Required field - only for certain invoice types - x_fc_authorizer_required = fields.Selection( - selection=[ - ('yes', 'Yes'), - ('no', 'No'), - ], - string='Authorizer Required?', - help='For ODSP, Direct/Private, Insurance, Others, and Rentals - specify if an authorizer is needed.', - ) - - # Computed field to determine if authorizer should be shown - x_fc_show_authorizer = fields.Boolean( - compute='_compute_show_authorizer', - string='Show Authorizer', - ) - - @api.depends('x_fc_invoice_type', 'x_fc_authorizer_required') - def _compute_show_authorizer(self): - """Compute whether to show the authorizer field based on invoice type and authorizer_required.""" - # Invoice types that require the "Authorizer Required?" question - optional_auth_types = ('odsp', 'direct_private', 'insurance', 'other', 'rental') - # Invoice types where authorizer is always shown - always_auth_types = ('adp', 'adp_client', 'adp_odsp', 'wsib', 'march_of_dimes', 'muscular_dystrophy') - - for move in self: - invoice_type = move.x_fc_invoice_type - if invoice_type in always_auth_types: - move.x_fc_show_authorizer = True - elif invoice_type in optional_auth_types: - move.x_fc_show_authorizer = move.x_fc_authorizer_required == 'yes' - else: - move.x_fc_show_authorizer = False - - # Computed field to determine if "Authorizer Required?" question should be shown - x_fc_show_authorizer_question = fields.Boolean( - compute='_compute_show_authorizer_question', - string='Show Authorizer Question', - ) - - @api.depends('x_fc_invoice_type') - def _compute_show_authorizer_question(self): - """Compute whether to show the 'Authorizer Required?' field.""" - optional_auth_types = ('odsp', 'direct_private', 'insurance', 'other', 'rental') - for move in self: - move.x_fc_show_authorizer_question = move.x_fc_invoice_type in optional_auth_types - - # ========================================================================== - # ADP CLAIM FIELDS (Copied from Sale Order) - # ========================================================================== - x_fc_claim_number = fields.Char( - string='Claim Number', - tracking=True, - copy=False, - help='ADP Claim Number', - ) - x_fc_client_ref_1 = fields.Char( - string='Client Reference 1', - help='Primary client reference (e.g., Health Card Number)', - ) - x_fc_client_ref_2 = fields.Char( - string='Client Reference 2', - help='Secondary client reference', - ) - x_fc_adp_delivery_date = fields.Date( - string='ADP Delivery Date', - help='Date the product was delivered to the client (for ADP billing)', - ) - x_fc_service_start_date = fields.Date( - string='Service Start Date', - help='Service period start date (optional)', - ) - x_fc_service_end_date = fields.Date( - string='Service End Date', - help='Service period end date (optional)', - ) - x_fc_authorizer_id = fields.Many2one( - 'res.partner', - string='Authorizer', - help='Authorizer contact for this invoice', - domain="[('is_company', '=', False)]", - ) - - x_fc_primary_serial = fields.Char( - string='Primary Serial Number', - help='Primary serial number for the invoice (header level). ' - 'Line-level serials are tracked on individual invoice lines.', - copy=False, - ) - - # ========================================================================== - # SPLIT INVOICE TRACKING - # ========================================================================== - x_fc_source_sale_order_id = fields.Many2one( - 'sale.order', - string='Source Sale Order', - help='The sale order this split invoice was created from', - index=True, - ) - x_fc_adp_invoice_portion = fields.Selection( - selection=[ - ('client', 'Client Portion (25%)'), - ('adp', 'ADP Portion (75%)'), - ('full', 'Full Invoice'), - ], - string='Invoice Portion', - default='full', - help='Tracks whether this is a split invoice for client or ADP portion', - ) - - is_manually_modified = fields.Boolean( - string='Manually Modified', - default=False, - copy=False, - help='Set to True if invoice fields have been manually edited (not synced from SO)', - ) - - # ========================================================================== - # COMPUTED TOTALS FOR ADP PORTIONS - # ========================================================================== - x_fc_adp_portion_total = fields.Monetary( - string='Total ADP Portion', - compute='_compute_adp_totals', - currency_field='currency_id', - help='Total ADP portion from the linked sale order', - ) - x_fc_client_portion_total = fields.Monetary( - string='Total Client Portion', - compute='_compute_adp_totals', - currency_field='currency_id', - help='Total client portion from the linked sale order', - ) - - # Sibling invoice totals (shows the OTHER invoice's total) - x_fc_sibling_adp_total = fields.Monetary( - string='ADP Invoice Total', - compute='_compute_sibling_totals', - currency_field='currency_id', - help='Total from the sibling ADP portion invoice', - ) - x_fc_sibling_client_total = fields.Monetary( - string='Client Invoice Total', - compute='_compute_sibling_totals', - currency_field='currency_id', - help='Total from the sibling Client portion invoice', - ) - - # ========================================================================== - # COMPUTED FIELD FOR PRODUCT-ONLY LINES (for ADP Summary) - # ========================================================================== - x_fc_product_lines = fields.One2many( - 'account.move.line', - compute='_compute_product_lines', - string='Product Lines Only', - help='Only product lines (excludes sections, notes, and empty lines)', - ) - - # ========================================================================== - # DEDUCTION TRACKING - # ========================================================================== - x_fc_has_deductions = fields.Boolean( - string='Has Deductions', - compute='_compute_has_deductions', - help='True if any line has a deduction applied', - ) - x_fc_total_deduction_amount = fields.Monetary( - string='Total Deduction Amount', - compute='_compute_has_deductions', - currency_field='currency_id', - help='Total amount of deductions applied to ADP portion', - ) - - # ========================================================================== - # DEVICE VERIFICATION STATUS (for linked Sale Order) - # ========================================================================== - x_fc_needs_device_verification = fields.Boolean( - string='Needs Device Verification', - compute='_compute_needs_device_verification', - help='True if this is a client invoice and the linked SO needs device verification', - ) - - @api.depends('x_fc_adp_invoice_portion', 'invoice_line_ids.sale_line_ids') - def _compute_needs_device_verification(self): - """Check if this client invoice needs device verification. - - Shows True if: - - This is a client portion invoice - - The linked sale order has ADP devices - - Device verification is NOT complete - """ - for move in self: - needs_verification = False - - # Only applies to client invoices - if move.x_fc_adp_invoice_portion == 'client': - # Find linked sale order - sale_order = None - for line in move.invoice_line_ids: - if line.sale_line_ids: - sale_order = line.sale_line_ids[0].order_id - break - - if sale_order: - # Check if SO has ADP devices and verification is not complete - if (sale_order.x_fc_total_device_count > 0 and - not sale_order.x_fc_device_verification_complete): - needs_verification = True - - move.x_fc_needs_device_verification = needs_verification - - # ========================================================================== - # ADP EXPORT TRACKING - # ========================================================================== - adp_exported = fields.Boolean( - string='ADP Exported', - default=False, - copy=False, - help='Has this invoice been exported to ADP format', - ) - adp_export_date = fields.Datetime( - string='ADP Export Date', - copy=False, - ) - adp_export_count = fields.Integer( - string='Export Count', - default=0, - copy=False, - help='Number of times this invoice has been exported', - ) - - # ========================================================================== - # ADP BILLING STATUS (Post-Export Lifecycle) - # ========================================================================== - x_fc_adp_billing_status = fields.Selection( - selection=[ - ('not_applicable', 'Not Applicable'), - ('waiting', 'Waiting'), - ('submitted', 'Submitted'), - ('resubmitted', 'Resubmitted'), - ('need_correction', 'Need Correction'), - ('payment_issued', 'Payment Issued'), - ('cancelled', 'Cancelled'), - ], - string='ADP Billing Status', - default='not_applicable', - tracking=True, - copy=False, - help='Tracks the ADP billing lifecycle after invoice export', - ) - - # (Legacy studio fields removed - all data migrated to x_fc_* fields) - - # ========================================================================== - # COMPUTED METHODS - # ========================================================================== - @api.depends('invoice_line_ids', 'invoice_line_ids.x_fc_adp_portion', 'invoice_line_ids.x_fc_client_portion') - def _compute_adp_totals(self): - """Compute ADP and Client portion totals from invoice lines. - - These totals are calculated from the stored portion values on each - invoice line, which were set during invoice creation using the - device codes database pricing and client type calculation. - """ - for move in self: - # Sum portions from invoice lines (values set during invoice creation) - adp_total = sum(move.invoice_line_ids.mapped('x_fc_adp_portion') or [0]) - client_total = sum(move.invoice_line_ids.mapped('x_fc_client_portion') or [0]) - - move.x_fc_adp_portion_total = adp_total - move.x_fc_client_portion_total = client_total - - @api.depends('invoice_line_ids', 'invoice_line_ids.product_id', 'invoice_line_ids.quantity', 'invoice_line_ids.display_type') - def _compute_product_lines(self): - """Compute filtered list of only actual product lines (no sections, notes, or empty lines).""" - for move in self: - # Invoice lines have display_type='product' for actual products (unlike sale.order.line which uses False) - # Filter to only include product lines with quantity > 0 - move.x_fc_product_lines = move.invoice_line_ids.filtered( - lambda l: l.display_type == 'product' and l.product_id and l.quantity > 0 - ) - - @api.depends('invoice_line_ids.x_fc_deduction_type', 'invoice_line_ids.x_fc_deduction_value', - 'invoice_line_ids.x_fc_adp_portion', 'invoice_line_ids.product_id') - def _compute_has_deductions(self): - """Compute if invoice has any deductions and total deduction amount.""" - for move in self: - product_lines = move.invoice_line_ids.filtered( - lambda l: l.display_type == 'product' and l.product_id and l.quantity > 0 - ) - - # Check if any line has a deduction - has_deductions = any( - line.x_fc_deduction_type and line.x_fc_deduction_type != 'none' - for line in product_lines - ) - - # Calculate total deduction impact - total_deduction = 0.0 - if has_deductions: - for line in product_lines: - if line.x_fc_deduction_type == 'amt' and line.x_fc_deduction_value: - total_deduction += line.x_fc_deduction_value - elif line.x_fc_deduction_type == 'pct' and line.x_fc_deduction_value: - # For percentage, calculate the reduction from normal - client_type = move._get_client_type() - base_pct = 0.75 if client_type == 'REG' else 1.0 - adp_price = line.x_fc_adp_max_price or line.price_unit - normal_adp = adp_price * line.quantity * base_pct - actual_adp = line.x_fc_adp_portion - total_deduction += max(0, normal_adp - actual_adp) - - move.x_fc_has_deductions = has_deductions - move.x_fc_total_deduction_amount = total_deduction - - def _compute_sibling_totals(self): - """Compute the OTHER portion totals from the linked sale order. - - For Client Invoice: show the ADP portion from the sale order - For ADP Invoice: show the Client portion from the sale order - - This way the report always shows both portions even if the other - invoice hasn't been created yet. - """ - SaleOrder = self.env['sale.order'].sudo() - - for move in self: - adp_total = 0.0 - client_total = 0.0 - sale_order = False - - # Method 1: Find the SO via invoice_ids reverse relation - sale_order = SaleOrder.search([('invoice_ids', 'in', move.id)], limit=1) - - # Method 2: Find via invoice_line_ids.sale_line_ids - if not sale_order: - sale_line_ids = move.invoice_line_ids.mapped('sale_line_ids') - if sale_line_ids: - sale_order = sale_line_ids[0].order_id - - # Method 3: Parse invoice_origin (e.g., "S29958 (Client 25%)") - if not sale_order and move.invoice_origin: - origin = move.invoice_origin.split(' ')[0] if move.invoice_origin else '' - if origin: - sale_order = SaleOrder.search([('name', '=', origin)], limit=1) - - if sale_order: - # Get the portions from the sale order - adp_total = sale_order.x_fc_adp_portion_total or 0.0 - client_total = sale_order.x_fc_client_portion_total or 0.0 - - move.x_fc_sibling_adp_total = adp_total - move.x_fc_sibling_client_total = client_total - - @api.onchange('x_fc_invoice_type', 'x_fc_client_type') - def _onchange_invoice_type_client_type(self): - """Trigger recalculation when invoice type or client type changes.""" - for line in self.invoice_line_ids: - line._compute_adp_portions() - - # ========================================================================== - # GETTER METHODS - # ========================================================================== - def _get_invoice_type(self): - """Get invoice type from mapped field or built-in field.""" - self.ensure_one() - ICP = self.env['ir.config_parameter'].sudo() - field_name = ICP.get_param('fusion_claims.field_invoice_type', 'x_fc_invoice_type') - value = getattr(self, field_name, None) if hasattr(self, field_name) else None - if not value and field_name != 'x_fc_invoice_type': - value = self.x_fc_invoice_type - return value or '' - - def _get_client_type(self): - """Get client type from mapped field or built-in field.""" - self.ensure_one() - ICP = self.env['ir.config_parameter'].sudo() - field_name = ICP.get_param('fusion_claims.field_inv_client_type', 'x_fc_client_type') - value = getattr(self, field_name, None) if hasattr(self, field_name) else None - if not value and field_name != 'x_fc_client_type': - value = self.x_fc_client_type - return value or '' - - def _get_authorizer(self): - """Get authorizer from mapped field or built-in field. Returns name as string.""" - self.ensure_one() - ICP = self.env['ir.config_parameter'].sudo() - field_name = ICP.get_param('fusion_claims.field_inv_authorizer', 'x_fc_authorizer_id') - value = getattr(self, field_name, None) if hasattr(self, field_name) else None - if not value and field_name != 'x_fc_authorizer_id': - value = self.x_fc_authorizer_id - # Return name if it's a record, otherwise return string value - if hasattr(value, 'name'): - return value.name or '' - return str(value) if value else '' - - def _get_claim_number(self): - """Get claim number.""" - self.ensure_one() - return self.x_fc_claim_number or '' - - def _get_client_ref_1(self): - """Get client reference 1.""" - self.ensure_one() - return self.x_fc_client_ref_1 or '' - - def _get_client_ref_2(self): - """Get client reference 2.""" - self.ensure_one() - return self.x_fc_client_ref_2 or '' - - def _get_adp_delivery_date(self): - """Get ADP delivery date.""" - self.ensure_one() - return self.x_fc_adp_delivery_date - - def _is_adp_invoice(self): - """Check if this is an ADP invoice type.""" - self.ensure_one() - invoice_type = self._get_invoice_type() - if not invoice_type: - return False - invoice_type_lower = str(invoice_type).lower() - return 'adp' in invoice_type_lower - - def _get_serial_numbers(self): - """Get all serial numbers from invoice lines.""" - self.ensure_one() - serial_lines = [] - for line in self.invoice_line_ids: - serial = line._get_serial_number() - if serial: - serial_lines.append({ - 'product': line.product_id.name if line.product_id else line.name, - 'serial': serial, - 'adp_code': line._get_adp_device_code(), - }) - return serial_lines - - # ========================================================================== - # ACTION METHODS - # ========================================================================== - def action_export_adp_claim(self): - """Open the ADP export wizard for this invoice.""" - self.ensure_one() - return { - 'name': 'Export ADP Claim', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion_claims.export.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': { - 'default_invoice_ids': [(6, 0, self.ids)], - 'active_ids': self.ids, - 'active_model': 'account.move', - }, - } - - def action_recalculate_adp_portions(self): - """Manually recalculate ADP and Client portions for all lines.""" - for move in self: - for line in move.invoice_line_ids: - line._compute_adp_portions() - move._compute_adp_totals() - - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'ADP Portions Recalculated', - 'message': 'All line portions have been recalculated.', - 'type': 'success', - 'sticky': False, - } - } - - def action_sync_to_sale_order(self): - """Sync ADP fields from this Invoice TO the linked Sale Order and all other invoices. - - This is a 2-way sync: Invoice becomes the source of truth, updates SO, - then SO syncs to all linked invoices. - """ - synced_orders = [] - for move in self: - _logger.info(f"=== Invoice {move.name} Sync to SO started ===") - - # Find linked sale orders via sale_line_ids -> order_id - sale_orders = self.env['sale.order'] - for line in move.invoice_line_ids: - if line.sale_line_ids: - sale_orders |= line.sale_line_ids.mapped('order_id') - - # Also try direct search - if not sale_orders: - sale_orders = self.env['sale.order'].search([ - ('invoice_ids', 'in', move.id) - ]) - - if not sale_orders: - _logger.warning(f"No linked sale orders found for invoice {move.name}") - continue - - _logger.info(f"Found {len(sale_orders)} linked sale orders: {sale_orders.mapped('name')}") - - # Update all linked sale orders with invoice values - for order in sale_orders: - so_vals = {} - - # Get values from invoice FC fields - so_vals['x_fc_claim_number'] = move.x_fc_claim_number or False - so_vals['x_fc_client_ref_1'] = move.x_fc_client_ref_1 or False - so_vals['x_fc_client_ref_2'] = move.x_fc_client_ref_2 or False - so_vals['x_fc_adp_delivery_date'] = move.x_fc_adp_delivery_date or False - - authorizer_id = move.x_fc_authorizer_id.id if move.x_fc_authorizer_id else False - so_vals['x_fc_authorizer_id'] = authorizer_id or False - - # Client Type - if move.x_fc_client_type: - so_vals['x_fc_client_type'] = move.x_fc_client_type - - # Service Dates - so_vals['x_fc_service_start_date'] = move.x_fc_service_start_date or False - so_vals['x_fc_service_end_date'] = move.x_fc_service_end_date or False - - # Primary Serial Number - if move.x_fc_primary_serial: - so_vals['x_fc_primary_serial'] = move.x_fc_primary_serial - - _logger.debug(f" SO vals to write: {so_vals}") - - try: - # Update the Sale Order (skip_sync to avoid infinite loop) - order.sudo().with_context(skip_sync=True).write(so_vals) - synced_orders.append(order.name) - _logger.info(f"SUCCESS: Synced fields from invoice {move.name} to SO {order.name}") - - # Sync line-level fields (Serial Numbers) from Invoice Lines to SO Lines - self._sync_line_fields_to_sale_order(move, order) - - # Now sync from SO to ALL linked invoices (including this one and others) - order.with_context(skip_sync=False)._sync_fields_to_invoices() - - except Exception as e: - _logger.error(f"FAILED to sync from invoice {move.name} to SO {order.name}: {e}") - - if synced_orders: - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'Sync Complete', - 'message': f'Synced ADP fields to Sale Order(s): {", ".join(synced_orders)} and all linked invoices.', - 'type': 'success', - 'sticky': False, - } - } - else: - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'No Sync Performed', - 'message': 'No linked Sale Orders found for this invoice.', - 'type': 'warning', - 'sticky': False, - } - } - - def _sync_line_fields_to_sale_order(self, invoice, sale_order): - """Sync Serial Numbers from Invoice lines to corresponding SO lines and sibling invoice lines. - - Each invoice line syncs its serial to: - 1. The linked SO line's x_fc_serial_number - 2. All other invoice lines linked to that same SO line - Also syncs first serial to SO header's x_fc_primary_serial - """ - primary_serial = None # To collect primary serial for SO header - - for inv_line in invoice.invoice_line_ids: - if inv_line.display_type in ('line_section', 'line_note'): - continue - - # Get Serial Number from invoice line - serial_number = None - if 'x_fc_serial_number' in inv_line._fields: - serial_number = inv_line.x_fc_serial_number - - # Track first non-empty serial as primary for SO header - if serial_number and not primary_serial: - primary_serial = serial_number - - # Find linked SO lines - so_lines = inv_line.sale_line_ids - if not so_lines: - continue - - for so_line in so_lines: - # Update SO line's serial - if serial_number is not None: - so_line_vals = {} - if 'x_fc_serial_number' in so_line._fields: - so_line_vals['x_fc_serial_number'] = serial_number or False - if so_line_vals: - try: - so_line.sudo().with_context(skip_sync=True).write(so_line_vals) - _logger.debug(f" Synced serial '{serial_number}' to SO line {so_line.id}") - except Exception as e: - _logger.error(f" Failed to sync serial to SO line {so_line.id}: {e}") - - # Find sibling invoice lines (other invoices linked to same SO line) - sibling_inv_lines = self.env['account.move.line'].sudo().search([ - ('sale_line_ids', 'in', so_line.id), - ('id', '!=', inv_line.id), - ('move_id.state', '!=', 'cancel'), - ]) - - for sibling_line in sibling_inv_lines: - sibling_vals = {} - # Sync serial number to sibling invoice line - if 'x_fc_serial_number' in sibling_line._fields: - sibling_vals['x_fc_serial_number'] = serial_number or False - if sibling_vals: - try: - sibling_line.sudo().with_context(skip_sync=True).write(sibling_vals) - _logger.debug(f" Synced serial '{serial_number}' to sibling inv line {sibling_line.id} (inv {sibling_line.move_id.name})") - except Exception as e: - _logger.error(f" Failed to sync serial to sibling inv line {sibling_line.id}: {e}") - - # Sync primary serial to SO header (FC field only - Studio fields are read-only) - if primary_serial: - so_header_vals = {'x_fc_primary_serial': primary_serial} - try: - sale_order.sudo().with_context(skip_sync=True).write(so_header_vals) - _logger.debug(f" Synced primary serial to SO header {sale_order.name}: {so_header_vals}") - except Exception as e: - _logger.error(f" Failed to sync primary serial to SO {sale_order.name}: {e}") - - # ========================================================================== - # OVERRIDE WRITE - # ========================================================================== - def write(self, vals): - """Override write to trigger recalculation and handle billing status changes.""" - # Track billing status changes for reminder scheduling - new_billing_status = vals.get('x_fc_adp_billing_status') - new_payment_state = vals.get('payment_state') - - result = super().write(vals) - - # Check if we need to recalculate - ICP = self.env['ir.config_parameter'].sudo() - invoice_type_field = ICP.get_param('fusion_claims.field_invoice_type', 'x_fc_invoice_type') - client_type_field = ICP.get_param('fusion_claims.field_inv_client_type', 'x_fc_client_type') - - trigger_fields = {'x_fc_invoice_type', 'x_fc_client_type', invoice_type_field, client_type_field} - if trigger_fields & set(vals.keys()): - for move in self: - for line in move.invoice_line_ids: - line._compute_adp_portions() - - # Auto-update ADP billing status when payment is registered - # payment_state values: 'not_paid', 'in_payment', 'paid', 'partial', 'reversed', 'invoicing_legacy' - if new_payment_state in ('paid', 'in_payment'): - for move in self: - # Only for ADP invoices that are in 'submitted' or 'resubmitted' status - if (move.x_fc_adp_invoice_portion == 'adp' and - move.x_fc_adp_billing_status in ('submitted', 'resubmitted', 'waiting')): - move.with_context(skip_payment_status_update=True).write({ - 'x_fc_adp_billing_status': 'payment_issued' - }) - _logger.info(f"Auto-updated ADP billing status to 'payment_issued' for {move.name}") - - - # Handle billing status changes for reminders - if new_billing_status: - for move in self: - if move.x_fc_adp_invoice_portion != 'adp': - # Only track billing status for ADP invoices - continue - - if new_billing_status == 'waiting': - # Schedule billing deadline reminder - move._schedule_billing_reminder() - - elif new_billing_status == 'need_correction': - # Schedule correction reminders for all configured users - move._schedule_correction_reminders() - - elif new_billing_status == 'submitted': - # Complete billing deadline activity - move._complete_adp_activities('fusion_claims.mail_activity_type_adp_billing') - - elif new_billing_status == 'resubmitted': - # Complete correction activities - move._complete_adp_activities('fusion_claims.mail_activity_type_adp_correction') - - elif new_billing_status == 'payment_issued': - # Complete all remaining activities - move._complete_adp_activities('fusion_claims.mail_activity_type_adp_billing') - move._complete_adp_activities('fusion_claims.mail_activity_type_adp_correction') - - return result - - # ========================================================================== - # DEVICE APPROVAL WIZARD FROM INVOICE - # ========================================================================== - def action_open_device_approval_wizard(self): - """Open the Device Approval Wizard for the linked Sale Order. - - This allows users to complete device verification from the Client Invoice - when the invoice was created before ADP approval. - """ - self.ensure_one() - - # Find linked sale order - sale_order = None - for line in self.invoice_line_ids: - if line.sale_line_ids: - sale_order = line.sale_line_ids[0].order_id - break - - if not sale_order: - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'No Linked Sale Order', - 'message': 'Cannot find linked Sale Order for device verification.', - 'type': 'warning', - } - } - - # Check if verification is already complete - if sale_order.x_fc_device_verification_complete: - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'Already Verified', - 'message': f'Device verification is already complete for {sale_order.name}.', - 'type': 'info', - } - } - - # Open the device approval wizard for the linked sale order - return { - 'name': 'Verify Device Approval', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion_claims.device.approval.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': { - 'active_id': sale_order.id, - 'active_model': 'sale.order', - }, - } - - # ========================================================================== - # EMAIL SEND OVERRIDE (Use ADP templates for ADP invoices) - # ========================================================================== - def action_invoice_sent(self): - """Override to use ADP email template for ADP invoices. - - When sending an invoice for an ADP sale, automatically selects the - ADP landscape template instead of the default template. - """ - self.ensure_one() - - # Check if this is an ADP invoice - if self._is_adp_invoice(): - # Get the ADP invoice template - template_xmlid = 'fusion_claims.email_template_adp_invoice' - - try: - template = self.env.ref(template_xmlid, raise_if_not_found=False) - if template: - # Open the mail compose wizard with the ADP template pre-selected - ctx = { - 'default_model': 'account.move', - 'default_res_ids': self.ids, - 'default_template_id': template.id, - 'default_email_layout_xmlid': 'mail.mail_notification_layout_with_responsible_signature', - 'default_composition_mode': 'comment', - 'mark_invoice_as_sent': True, - 'force_email': True, - 'model_description': self.type_name, - } - - return { - 'type': 'ir.actions.act_window', - 'res_model': 'mail.compose.message', - 'view_mode': 'form', - 'views': [(False, 'form')], - 'target': 'new', - 'context': ctx, - } - except Exception as e: - _logger.warning(f"Could not load ADP email template: {e}") - - # Fall back to standard behavior for non-ADP invoices - return super().action_invoice_sent() - - # ========================================================================== - # ADP ACTIVITY REMINDER METHODS - # ========================================================================== - def _schedule_or_renew_adp_activity(self, activity_type_xmlid, user_id, date_deadline, summary, note=False): - """Schedule or renew an ADP-related activity. - - If an activity of the same type for the same user already exists, - update its deadline instead of creating a duplicate. - """ - self.ensure_one() - - try: - activity_type = self.env.ref(activity_type_xmlid) - except ValueError: - _logger.warning(f"Activity type not found: {activity_type_xmlid}") - return - - # Search for existing activity of this type for this user - existing = self.activity_ids.filtered( - lambda a: a.activity_type_id.id == activity_type.id - and a.user_id.id == user_id - ) - - if existing: - # Update existing activity - existing[0].write({ - 'date_deadline': date_deadline, - 'summary': summary, - 'note': note or existing[0].note, - }) - _logger.info(f"Renewed ADP activity for invoice {self.name}: {summary} -> {date_deadline}") - else: - # Create new activity - self.activity_schedule( - activity_type_xmlid, - date_deadline=date_deadline, - summary=summary, - note=note, - user_id=user_id - ) - _logger.info(f"Scheduled new ADP activity for invoice {self.name}: {summary} -> {date_deadline}") - - def _complete_adp_activities(self, activity_type_xmlid): - """Complete all activities of a specific type for this record.""" - self.ensure_one() - - try: - activity_type = self.env.ref(activity_type_xmlid) - except ValueError: - return - - activities = self.activity_ids.filtered( - lambda a: a.activity_type_id.id == activity_type.id - ) - - for activity in activities: - activity.action_feedback(feedback='Completed automatically') - _logger.info(f"Completed ADP activity for invoice {self.name}: {activity.summary}") - - def _schedule_billing_reminder(self): - """Schedule a billing deadline reminder for the configured billing person. - - Reminds on Monday to complete billing by Wednesday 6 PM of the posting week. - """ - self.ensure_one() - - if not self._is_adp_invoice(): - return - - # Get the configured billing reminder user - billing_user = self._get_adp_billing_reminder_user() - if not billing_user: - _logger.warning(f"No billing reminder user configured, cannot schedule reminder for {self.name}") - return - - # Calculate the next posting date and Monday of that week - next_posting = self._get_next_posting_date() - reminder_date = self._get_posting_week_monday(next_posting) - deadline_wednesday = self._get_posting_week_wednesday(next_posting) - - # Don't schedule if reminder date is in the past - from datetime import date - if reminder_date < date.today(): - next_posting = self._get_next_posting_date(next_posting) - reminder_date = self._get_posting_week_monday(next_posting) - deadline_wednesday = self._get_posting_week_wednesday(next_posting) - - summary = f"Complete ADP billing for {self.name} by Wednesday 6 PM" - note = f"Submit invoice {self.name} to ADP by {deadline_wednesday.strftime('%A, %B %d, %Y')} 6 PM for the {next_posting.strftime('%B %d')} posting." - - self._schedule_or_renew_adp_activity( - 'fusion_claims.mail_activity_type_adp_billing', - billing_user.id, - reminder_date, - summary, - note - ) - - def _schedule_correction_reminders(self): - """Schedule correction reminders for all configured correction alert users. - - Creates an activity for each user when an invoice needs correction. - """ - self.ensure_one() - - if not self._is_adp_invoice(): - return - - # Get all configured correction reminder users - correction_users = self._get_adp_correction_reminder_users() - if not correction_users: - _logger.warning(f"No correction reminder users configured, cannot schedule reminder for {self.name}") - return - - # Calculate the next submission deadline - next_posting = self._get_next_posting_date() - deadline_wednesday = self._get_posting_week_wednesday(next_posting) - - from datetime import date - if deadline_wednesday < date.today(): - next_posting = self._get_next_posting_date(next_posting) - deadline_wednesday = self._get_posting_week_wednesday(next_posting) - - summary = f"Invoice {self.name} needs correction - resubmit to ADP" - note = f"This invoice was rejected by ADP and needs correction. Please fix and resubmit by {deadline_wednesday.strftime('%A, %B %d, %Y')} 6 PM." - - for user in correction_users: - self._schedule_or_renew_adp_activity( - 'fusion_claims.mail_activity_type_adp_correction', - user.id, - deadline_wednesday, - summary, - note - ) - - def _cron_renew_billing_reminders(self): - """Cron job to renew overdue billing reminders. - - For invoices with 'waiting' status that have overdue billing activities, - reschedule them to the next posting week's Monday. - """ - from datetime import date - today = date.today() - - try: - activity_type = self.env.ref('fusion_claims.mail_activity_type_adp_billing') - except ValueError: - _logger.warning("ADP Billing activity type not found") - return - - # Find ADP invoices in 'waiting' status with overdue billing activities - waiting_invoices = self.search([ - ('x_fc_adp_invoice_portion', '=', 'adp'), - ('x_fc_adp_billing_status', '=', 'waiting'), - ]) - - for invoice in waiting_invoices: - overdue_activities = invoice.activity_ids.filtered( - lambda a: a.activity_type_id.id == activity_type.id - and a.date_deadline < today - ) - - if overdue_activities: - invoice._schedule_billing_reminder() - _logger.info(f"Renewed overdue billing reminder for invoice {invoice.name}") - - def _cron_renew_correction_reminders(self): - """Cron job to renew overdue correction reminders. - - For invoices with 'need_correction' status that have overdue activities, - reschedule them to the next posting week's Wednesday. - """ - from datetime import date - today = date.today() - - try: - activity_type = self.env.ref('fusion_claims.mail_activity_type_adp_correction') - except ValueError: - _logger.warning("ADP Correction activity type not found") - return - - # Find ADP invoices needing correction with overdue activities - correction_invoices = self.search([ - ('x_fc_adp_invoice_portion', '=', 'adp'), - ('x_fc_adp_billing_status', '=', 'need_correction'), - ]) - - for invoice in correction_invoices: - overdue_activities = invoice.activity_ids.filtered( - lambda a: a.activity_type_id.id == activity_type.id - and a.date_deadline < today - ) - - if overdue_activities: - invoice._schedule_correction_reminders() - _logger.info(f"Renewed overdue correction reminder for invoice {invoice.name}") diff --git a/fusion_claims/fusion_claims/models/account_move_line.py b/fusion_claims/fusion_claims/models/account_move_line.py deleted file mode 100644 index b77bf81..0000000 --- a/fusion_claims/fusion_claims/models/account_move_line.py +++ /dev/null @@ -1,247 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2025 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) -# Part of the Fusion Claim Assistant product family. - -from odoo import models, fields, api - - -class AccountMoveLine(models.Model): - _inherit = 'account.move.line' - - # ========================================================================== - # SERIAL NUMBER AND DEVICE PLACEMENT - # ========================================================================== - x_fc_serial_number = fields.Char( - string='Serial Number', - help='Serial number for this product', - ) - x_fc_device_placement = fields.Selection( - selection=[ - ('L', 'Left'), - ('R', 'Right'), - ('NA', 'N/A'), - ], - string='Device Placement', - default='NA', - help='Device placement position (Left/Right/N/A)', - ) - - # ========================================================================== - # DEDUCTION FIELDS - # ========================================================================== - x_fc_deduction_type = fields.Selection( - selection=[ - ('none', 'No Deduction'), - ('pct', 'Percentage'), - ('amt', 'Amount'), - ], - string='Deduction Type', - default='none', - help='Type of ADP deduction applied to this line', - ) - x_fc_deduction_value = fields.Float( - string='Deduction Value', - digits='Product Price', - help='Deduction value (percentage if PCT, dollar amount if AMT)', - ) - - # ========================================================================== - # ADP REFERENCE FIELDS - # ========================================================================== - x_fc_adp_max_price = fields.Float( - string='ADP Max Price', - digits='Product Price', - help='Maximum price ADP will cover for this device (from mobility manual)', - ) - x_fc_sn_required = fields.Boolean( - string='S/N Required', - help='Is serial number required for this device?', - ) - - # ========================================================================== - # ADP DEVICE APPROVAL TRACKING - # ========================================================================== - x_fc_adp_approved = fields.Boolean( - string='ADP Approved', - default=False, - help='Was this device approved by ADP in the application approval?', - ) - x_fc_adp_device_type = fields.Char( - string='ADP Device Type', - help='Device type from ADP mobility manual (for approval matching)', - ) - - # ========================================================================== - # ADP PORTIONS - Stored fields set during invoice creation - # ========================================================================== - x_fc_adp_portion = fields.Monetary( - string='ADP Portion', - currency_field='currency_id', - help='ADP portion for this line (calculated during invoice creation from device codes database)', - ) - x_fc_client_portion = fields.Monetary( - string='Client Portion', - currency_field='currency_id', - help='Client portion for this line (calculated during invoice creation from device codes database)', - ) - - def _compute_adp_portions(self): - """Compute ADP and client portions based on device codes database. - - This is called during invoice type/client type changes to recalculate portions. - """ - self.action_recalculate_portions() - - def action_recalculate_portions(self): - """Manually recalculate ADP and client portions based on device codes database. - - This can be called to recalculate portions if values are incorrect. - Uses the same logic as invoice creation. - """ - ADPDevice = self.env['fusion.adp.device.code'].sudo() - - for line in self: - move = line.move_id - if not move or move.move_type not in ['out_invoice', 'out_refund']: - continue - - if not line.product_id or line.quantity <= 0: - continue - - # Get client type - client_type = move._get_client_type() - if client_type == 'REG': - base_adp_pct = 0.75 - base_client_pct = 0.25 - else: - base_adp_pct = 1.0 - base_client_pct = 0.0 - - # Get ADP price from device codes database (priority) - device_code = line._get_adp_device_code() - adp_price = 0 - - if device_code: - adp_device = ADPDevice.search([ - ('device_code', '=', device_code), - ('active', '=', True) - ], limit=1) - if adp_device: - adp_price = adp_device.adp_price or 0 - - # Fallback to product fields - if not adp_price and line.product_id: - product_tmpl = line.product_id.product_tmpl_id - if hasattr(product_tmpl, 'x_fc_adp_price'): - adp_price = getattr(product_tmpl, 'x_fc_adp_price', 0) or 0 - # (Studio field fallback removed) - - # Fallback to line max price or unit price - if not adp_price: - adp_price = line.x_fc_adp_max_price or line.price_unit - - qty = line.quantity - adp_base_total = adp_price * qty - - # Apply deductions - if line.x_fc_deduction_type == 'pct' and line.x_fc_deduction_value: - effective_adp_pct = base_adp_pct * (line.x_fc_deduction_value / 100) - adp_portion = adp_base_total * effective_adp_pct - client_portion = adp_base_total - adp_portion - elif line.x_fc_deduction_type == 'amt' and line.x_fc_deduction_value: - base_adp_amount = adp_base_total * base_adp_pct - adp_portion = max(0, base_adp_amount - line.x_fc_deduction_value) - client_portion = adp_base_total - adp_portion - else: - adp_portion = adp_base_total * base_adp_pct - client_portion = adp_base_total * base_client_pct - - line.write({ - 'x_fc_adp_portion': adp_portion, - 'x_fc_client_portion': client_portion, - 'x_fc_adp_max_price': adp_price, - }) - - # ========================================================================== - # GETTER METHODS - # ========================================================================== - def _get_adp_device_code(self): - """Get ADP device code from product. - - Checks multiple sources in order and validates against ADP device database: - 1. x_fc_adp_device_code (module field) - verified in ADP database - 2. x_adp_code (Studio/custom field) - verified in ADP database - 3. default_code - verified in ADP database - 4. Code in parentheses in product name (e.g., "Product Name (SE0001109)") - - Returns empty string if no valid ADP code found. - """ - import re - - self.ensure_one() - if not self.product_id: - return '' - - product_tmpl = self.product_id.product_tmpl_id - ADPDevice = self.env['fusion.adp.device.code'].sudo() - - # 1. Check x_fc_adp_device_code (module field) - code = '' - if hasattr(product_tmpl, 'x_fc_adp_device_code'): - code = getattr(product_tmpl, 'x_fc_adp_device_code', '') or '' - - # Verify code exists in ADP database - if code and ADPDevice.search_count([('device_code', '=', code), ('active', '=', True)]) > 0: - return code - - # 2. Check x_adp_code (Studio/custom field) - if hasattr(product_tmpl, 'x_adp_code'): - code = getattr(product_tmpl, 'x_adp_code', '') or '' - if code and ADPDevice.search_count([('device_code', '=', code), ('active', '=', True)]) > 0: - return code - - # 3. Check default_code - ONLY if it's a valid ADP code - code = self.product_id.default_code or '' - if code and ADPDevice.search_count([('device_code', '=', code), ('active', '=', True)]) > 0: - return code - - # 4. Try to extract code from product name in parentheses - # E.g., "[MXA-1618] GEOMATRIX SILVERBACK MAX BACKREST - ACTIVE (SE0001109)" - product_name = self.product_id.name or '' - match = re.search(r'\(([A-Z]{2}\d{7})\)', product_name) - if match: - code = match.group(1) - if ADPDevice.search_count([('device_code', '=', code), ('active', '=', True)]) > 0: - return code - - # 5. Last resort: check if there's a linked sale order line with ADP code - if self.sale_line_ids: - for sale_line in self.sale_line_ids: - if hasattr(sale_line, '_get_adp_device_code'): - sale_code = sale_line._get_adp_device_code() - if sale_code: - return sale_code - - # No valid ADP code found - return empty to skip this line in export - return '' - - def _get_serial_number(self): - """Get serial number from mapped field or native field.""" - self.ensure_one() - ICP = self.env['ir.config_parameter'].sudo() - field_name = ICP.get_param('fusion_claims.field_aml_serial', 'x_fc_serial_number') - - # Try mapped field first - if hasattr(self, field_name): - value = getattr(self, field_name, None) - if value: - return value - - # Fallback to native field - return self.x_fc_serial_number or '' - - def _get_device_placement(self): - """Get device placement.""" - self.ensure_one() - return self.x_fc_device_placement or 'NA' diff --git a/fusion_claims/fusion_claims/models/account_payment.py b/fusion_claims/fusion_claims/models/account_payment.py deleted file mode 100644 index 6c7f2dc..0000000 --- a/fusion_claims/fusion_claims/models/account_payment.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2025 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) -# Part of the Fusion Claim Assistant product family. - -from odoo import models, fields, api - - -class AccountPayment(models.Model): - _inherit = 'account.payment' - - x_fc_card_last_four = fields.Char( - string='Card Last 4 Digits', - size=4, - help='Last 4 digits of the card used for payment (for card payments only)', - ) - - x_fc_payment_note = fields.Char( - string='Payment Note', - help='Additional note for this payment (e.g., transaction reference)', - ) diff --git a/fusion_claims/fusion_claims/models/account_payment_method_line.py b/fusion_claims/fusion_claims/models/account_payment_method_line.py deleted file mode 100644 index bbeaf60..0000000 --- a/fusion_claims/fusion_claims/models/account_payment_method_line.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2025 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) -# Part of the Fusion Claim Assistant product family. - -from odoo import models, fields - - -class AccountPaymentMethodLine(models.Model): - _inherit = 'account.payment.method.line' - - x_fc_requires_card_digits = fields.Boolean( - string='Requires Card Digits', - default=False, - help='If checked, the user must enter the last 4 digits of the card when using this payment method.', - ) diff --git a/fusion_claims/fusion_claims/models/adp_application_data.py b/fusion_claims/fusion_claims/models/adp_application_data.py deleted file mode 100644 index 03ce1e0..0000000 --- a/fusion_claims/fusion_claims/models/adp_application_data.py +++ /dev/null @@ -1,670 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) - -import base64 -import json -import logging -import xml.etree.ElementTree as ET - -from odoo import api, fields, models - -_logger = logging.getLogger(__name__) - - -class FusionAdpApplicationData(models.Model): - _name = 'fusion.adp.application.data' - _description = 'ADP Application Data (Parsed XML)' - _order = 'application_date desc, id desc' - _rec_name = 'display_name' - - # ------------------------------------------------------------------ - # LINKAGE - # ------------------------------------------------------------------ - profile_id = fields.Many2one( - 'fusion.client.profile', string='Client Profile', - ondelete='cascade', index=True, - ) - sale_order_id = fields.Many2one( - 'sale.order', string='Sale Order', - ondelete='set null', index=True, - ) - display_name = fields.Char( - string='Name', compute='_compute_display_name', store=True, - ) - - # ------------------------------------------------------------------ - # COMPLETE XML DATA (for round-trip export fidelity) - # ------------------------------------------------------------------ - xml_data_json = fields.Text( - string='Complete XML Data (JSON)', - help='Complete 1:1 JSON representation of all ~300 XML fields for export', - ) - raw_xml = fields.Text(string='Raw XML Data') - - # ------------------------------------------------------------------ - # APPLICATION METADATA - # ------------------------------------------------------------------ - device_category = fields.Selection([ - ('AA', 'Ambulation Aids (Section 2a)'), - ('MD', 'Mobility Devices (Section 2b/2c)'), - ('PS', 'Positioning/Seating (Section 2d)'), - ('MX', 'Mixed/Multiple Sections'), - ], string='Device Category') - version_number = fields.Char(string='Form Version') - application_date = fields.Date(string='Application Date') - - # ------------------------------------------------------------------ - # SECTION 1 - APPLICANT BIOGRAPHICAL INFORMATION - # ------------------------------------------------------------------ - applicant_last_name = fields.Char(string='Last Name') - applicant_first_name = fields.Char(string='First Name') - applicant_middle_initial = fields.Char(string='Middle Initial') - health_card_number = fields.Char(string='Health Card Number', index=True) - health_card_version = fields.Char(string='Health Card Version') - date_of_birth = fields.Date(string='Date of Birth') - ltch_name = fields.Char(string='Long-Term Care Home') - - # Address (individual fields, not combined) - unit_number = fields.Char(string='Unit Number') - street_number = fields.Char(string='Street Number') - street_name = fields.Char(string='Street Name') - rural_route = fields.Char(string='Lot/Concession/Rural Route') - city = fields.Char(string='City', index=True) - province = fields.Char(string='Province') - postal_code = fields.Char(string='Postal Code') - - # Contact - home_phone = fields.Char(string='Home Phone') - business_phone = fields.Char(string='Business Phone') - phone_extension = fields.Char(string='Phone Extension') - - # ------------------------------------------------------------------ - # SECTION 1 - CONFIRMATION OF BENEFITS - # ------------------------------------------------------------------ - receives_social_assistance = fields.Boolean(string='Receives Social Assistance') - benefit_type = fields.Char(string='Benefit Program') - benefit_owp = fields.Boolean(string='Ontario Works Program (OWP)') - benefit_odsp = fields.Boolean(string='Ontario Disability Support Program (ODSP)') - benefit_acsd = fields.Boolean(string='Assistance to Children with Severe Disabilities (ACSD)') - wsib_eligible = fields.Boolean(string='WSIB Eligible') - vac_eligible = fields.Boolean(string='Veterans Affairs Canada (VAC) Eligible') - - # ------------------------------------------------------------------ - # SECTION 2 - DEVICES AND ELIGIBILITY - # ------------------------------------------------------------------ - medical_condition = fields.Text(string='Medical Condition / Diagnosis') - mobility_status = fields.Text(string='Functional Mobility Status') - - # Previously funded equipment - prev_funded_none = fields.Boolean(string='None Previously Funded') - prev_funded_forearm = fields.Boolean(string='Forearm Crutches (Previously)') - prev_funded_wheeled = fields.Boolean(string='Wheeled Walker (Previously)') - prev_funded_manual = fields.Boolean(string='Manual Wheelchair (Previously)') - prev_funded_power = fields.Boolean(string='Power Wheelchair (Previously)') - prev_funded_addon = fields.Boolean(string='Power Add-On Device (Previously)') - prev_funded_scooter = fields.Boolean(string='Power Scooter (Previously)') - prev_funded_seating = fields.Boolean(string='Positioning Devices (Previously)') - prev_funded_tilt = fields.Boolean(string='Power Tilt System (Previously)') - prev_funded_recline = fields.Boolean(string='Power Recline System (Previously)') - prev_funded_legrests = fields.Boolean(string='Power Elevating Leg Rests (Previously)') - prev_funded_frame = fields.Boolean(string='Paediatric Standing Frame (Previously)') - prev_funded_stroller = fields.Boolean(string='Paediatric Specialty Stroller (Previously)') - - # Devices currently required - device_forearm_crutches = fields.Boolean(string='Forearm Crutches') - device_wheeled_walker = fields.Boolean(string='Wheeled Walker') - device_manual_wheelchair = fields.Boolean(string='Manual Wheelchair') - device_ambulation_manual = fields.Boolean(string='Ambulation Aid + Manual Wheelchair') - device_dependent_wheelchair = fields.Boolean(string='Manual Wheelchair (Dependent)') - device_dynamic_tilt = fields.Boolean(string='Manual Dynamic Tilt Wheelchair') - device_manual_dynamic = fields.Boolean(string='Manual Dynamic Tilt (Dependent)') - device_manual_power_addon = fields.Boolean(string='Manual Wheelchair with Power Add-On') - device_power_base = fields.Boolean(string='Power Base Only') - device_power_scooter = fields.Boolean(string='Power Scooter Only') - device_ambulation_power = fields.Boolean(string='Ambulation Aid + Power Base/Scooter') - device_positioning = fields.Boolean(string='Positioning Devices (Seating)') - device_high_tech = fields.Boolean(string='High Technology Power Base') - device_standing_frame = fields.Boolean(string='Paediatric Standing Frame') - device_adp_funded_mods = fields.Boolean(string='Modifications to ADP Funded Device(s)') - device_non_adp_funded_mods = fields.Boolean(string='Modifications to Non ADP Funded Device(s)') - - # ------------------------------------------------------------------ - # SECTION 2A - AMBULATION AIDS (Walkers) - # ------------------------------------------------------------------ - s2a_base_device = fields.Char(string='Walker Type') - s2a_paediatric_frame = fields.Char(string='Paediatric Frame') - s2a_forearm_crutches = fields.Char(string='Forearm Crutches Type') - s2a_none = fields.Char(string='None Selected') - s2a_reason = fields.Char(string='Reason for Application') - s2a_replacement_status = fields.Char(string='Replacement - Mobility Status Change') - s2a_replacement_size = fields.Char(string='Replacement - Body Size Change') - s2a_replacement_adp = fields.Char(string='Replacement - Equipment Worn Out') - s2a_replacement_special = fields.Char(string='Replacement - Special Circumstances') - s2a_confirm1 = fields.Char(string='Confirmation 1') - s2a_confirm2 = fields.Char(string='Confirmation 2') - s2a_confirm3 = fields.Char(string='Confirmation 3') - s2a_confirm4 = fields.Char(string='Confirmation 4') - s2a_confirm5 = fields.Char(string='Confirmation 5') - s2a_confirm6 = fields.Char(string='Confirmation 6') - # Prescription - s2a_seat_height = fields.Char(string='Seat Height') - s2a_seat_height_unit = fields.Char(string='Seat Height Unit') - s2a_handle_height = fields.Char(string='Push Handle Height') - s2a_handle_height_unit = fields.Char(string='Handle Height Unit') - s2a_hand_grips = fields.Char(string='Hand Grips') - s2a_forearm_attachments = fields.Char(string='Forearm Attachments') - s2a_width_handles = fields.Char(string='Width Between Push Handles') - s2a_width_handles_unit = fields.Char(string='Width Handles Unit') - s2a_client_weight = fields.Char(string='Client Weight') - s2a_client_weight_unit = fields.Char(string='Client Weight Unit') - s2a_brakes = fields.Char(string='Brakes') - s2a_brake_type = fields.Char(string='Brake Type') - s2a_num_wheels = fields.Char(string='Number of Wheels') - s2a_wheel_size = fields.Char(string='Wheel Size') - s2a_back_support = fields.Char(string='Back Support') - # ADP options - s2a_adp_walker = fields.Char(string='ADP Adolescent Walker') - s2a_adp_frame = fields.Char(string='ADP Adolescent Frame') - s2a_adp_standing = fields.Char(string='ADP Adolescent Standing') - # Custom modifications - s2a_custom = fields.Char(string='Custom Modifications Required') - s2a_cost_labour = fields.Char(string='Cost of Labour') - - # ------------------------------------------------------------------ - # SECTION 2B - MANUAL WHEELCHAIRS - # ------------------------------------------------------------------ - s2b_base_device = fields.Char(string='Manual Wheelchair Type') - s2b_power_addon = fields.Char(string='Power Add-On Device') - s2b_reason = fields.Char(string='Reason for Application') - s2b_replacement_status = fields.Char(string='Replacement - Mobility Status') - s2b_replacement_size = fields.Char(string='Replacement - Body Size') - s2b_replacement_adp = fields.Char(string='Replacement - Equipment Worn') - s2b_replacement_special = fields.Char(string='Replacement - Special') - s2b_confirm1 = fields.Char(string='Confirmation 1') - s2b_confirm2 = fields.Char(string='Confirmation 2') - s2b_confirm3 = fields.Char(string='Confirmation 3') - s2b_confirm4 = fields.Char(string='Confirmation 4') - s2b_confirm5 = fields.Char(string='Confirmation 5') - s2b_confirm6 = fields.Char(string='Confirmation 6') - s2b_confirm7 = fields.Char(string='Confirmation 7') - s2b_confirm8 = fields.Char(string='Confirmation 8') - s2b_confirm9 = fields.Char(string='Confirmation 9') - s2b_confirm10 = fields.Char(string='Confirmation 10') - s2b_confirm11 = fields.Char(string='Confirmation 11') - s2b_confirm12 = fields.Char(string='Confirmation 12') - s2b_confirm13 = fields.Char(string='Confirmation 13') - # Prescription - s2b_seat_width = fields.Char(string='Seat Width') - s2b_seat_width_unit = fields.Char(string='Seat Width Unit') - s2b_seat_depth = fields.Char(string='Seat Depth') - s2b_seat_depth_unit = fields.Char(string='Seat Depth Unit') - s2b_floor_height = fields.Char(string='Finished Seat to Floor Height') - s2b_floor_height_unit = fields.Char(string='Floor Height Unit') - s2b_cane_height = fields.Char(string='Back Cane Height') - s2b_cane_height_unit = fields.Char(string='Cane Height Unit') - s2b_back_height = fields.Char(string='Finished Back Height') - s2b_back_height_unit = fields.Char(string='Back Height Unit') - s2b_rest_length = fields.Char(string='Finished Leg Rest Length') - s2b_rest_length_unit = fields.Char(string='Rest Length Unit') - s2b_client_weight = fields.Char(string='Client Weight') - s2b_client_weight_unit = fields.Char(string='Client Weight Unit') - # Add-on options - s2b_adjustable_tension = fields.Boolean(string='Adjustable Tension Back Upholstery') - s2b_heavy_duty = fields.Boolean(string='Heavy Duty Cross Braces & Upholstery') - s2b_recliner = fields.Boolean(string='Recliner Option') - s2b_footplates = fields.Boolean(string='Angle Adjustable Footplates') - s2b_legrests = fields.Boolean(string='Elevating Legrests') - s2b_spoke = fields.Boolean(string='Spoke Protectors') - s2b_projected = fields.Boolean(string='Projected Handrims') - s2b_standard_manual = fields.Boolean(string='Standard Manual with Dynamic Tilt') - s2b_grade_aids = fields.Boolean(string='Grade Aids') - s2b_caster_pin = fields.Boolean(string='Caster Pin Locks') - s2b_amputee_axle = fields.Boolean(string='Amputee Axle Plates') - s2b_quick_release = fields.Boolean(string='Quick Release Axles') - s2b_stroller = fields.Boolean(string='Stroller Handles/Paediatric') - s2b_oxygen = fields.Boolean(string='Oxygen Tank Holder') - s2b_ventilator = fields.Boolean(string='Ventilator Tray') - s2b_titanium = fields.Boolean(string='Titanium Frame') - s2b_clothing_guards = fields.Boolean(string='Clothing Guards') - s2b_one_arm = fields.Boolean(string='One Arm/Lever Drive') - s2b_uni_lateral = fields.Boolean(string='Uni-Lateral Wheel Lock') - s2b_plastic = fields.Boolean(string='Plastic Coated Handrims') - s2b_rationale = fields.Text(string='Clinical Rationale') - s2b_custom = fields.Char(string='Custom Modifications Required') - s2b_cost_labour = fields.Char(string='Cost of Labour') - - # ------------------------------------------------------------------ - # SECTION 2C - POWER BASES AND POWER SCOOTERS - # ------------------------------------------------------------------ - s2c_base_device = fields.Char(string='Power Base/Scooter Type') - s2c_reason = fields.Char(string='Reason for Application') - s2c_replacement_status = fields.Char(string='Replacement - Mobility Status') - s2c_replacement_size = fields.Char(string='Replacement - Body Size') - s2c_replacement_adp = fields.Char(string='Replacement - Equipment Worn') - s2c_replacement_special = fields.Char(string='Replacement - Special') - s2c_confirm1 = fields.Char(string='Power Base Confirmation 1') - s2c_confirm2 = fields.Char(string='Power Base Confirmation 2') - s2c_confirm3 = fields.Char(string='Scooter Confirmation 1') - s2c_confirm4 = fields.Char(string='Scooter Confirmation 2') - s2c_confirm5 = fields.Char(string='Scooter Confirmation 3') - # Prescription - s2c_seat_width = fields.Char(string='Seat Width') - s2c_seat_width_unit = fields.Char(string='Seat Width Unit') - s2c_back_height = fields.Char(string='Finished Back Height') - s2c_back_height_unit = fields.Char(string='Back Height Unit') - s2c_floor_height = fields.Char(string='Finished Seat to Floor Height') - s2c_floor_height_unit = fields.Char(string='Floor Height Unit') - s2c_rest_length = fields.Char(string='Leg Rest Length') - s2c_rest_length_unit = fields.Char(string='Rest Length Unit') - s2c_seat_depth = fields.Char(string='Seat Depth') - s2c_seat_depth_unit = fields.Char(string='Seat Depth Unit') - s2c_client_weight = fields.Char(string='Client Weight') - s2c_client_weight_unit = fields.Char(string='Client Weight Unit') - # Add-on options - s2c_adjustable_tension = fields.Boolean(string='Adjustable Tension Back Upholstery') - s2c_midline = fields.Boolean(string='Midline Control') - s2c_manual_recline = fields.Boolean(string='Manual Recline Option') - s2c_footplates = fields.Boolean(string='Angle Adjustable Footplates') - s2c_legrests = fields.Boolean(string='Manual Elevating Legrests') - s2c_swingaway = fields.Boolean(string='Swingaway Mounting Bracket') - s2c_one_piece = fields.Boolean(string='One Piece 90/90 Front Riggings') - s2c_seat_package_1 = fields.Boolean(string='Seat Package 1 for Power Bases') - s2c_seat_package_2 = fields.Boolean(string='Seat Package 2 for Power Bases') - s2c_oxygen = fields.Boolean(string='Oxygen Tank Holder') - s2c_ventilator = fields.Boolean(string='Ventilator Tray') - # Specialty controls - s2c_sp_controls_1 = fields.Boolean(string='Specialty Controls 1 - Non Standard Joystick') - s2c_sp_controls_2 = fields.Boolean(string='Specialty Controls 2 - Chin/Rim Control') - s2c_sp_controls_3 = fields.Boolean(string='Specialty Controls 3 - Simple Touch') - s2c_sp_controls_4 = fields.Boolean(string='Specialty Controls 4 - Proximity Control') - s2c_sp_controls_5 = fields.Boolean(string='Specialty Controls 5 - Breath Control') - s2c_sp_controls_6 = fields.Boolean(string='Specialty Controls 6 - Scanners') - s2c_auto_correction = fields.Boolean(string='Auto Correction System') - s2c_rationale = fields.Text(string='Clinical Rationale') - # Power positioning - s2c_power_tilt = fields.Boolean(string='Power Tilt Only') - s2c_power_recline = fields.Boolean(string='Power Recline Only') - s2c_tilt_and_recline = fields.Boolean(string='Power Tilt and Recline') - s2c_power_elevating = fields.Boolean(string='Power Elevating Footrests') - s2c_control_box = fields.Boolean(string='Multi-Function Control Box') - s2c_custom = fields.Char(string='Custom Modifications Required') - s2c_cost_labour = fields.Char(string='Cost of Labour') - - # ------------------------------------------------------------------ - # SECTION 2D - POSITIONING DEVICES (SEATING) FOR MOBILITY - # ------------------------------------------------------------------ - # Seat Cushion - s2d_seat_modular = fields.Boolean(string='Seat Cushion - Modular') - s2d_seat_custom = fields.Boolean(string='Seat Cushion - Custom Fabricated') - s2d_seat_cover_modular = fields.Boolean(string='Seat Cover - Modular') - s2d_seat_cover_custom = fields.Boolean(string='Seat Cover - Custom Fabricated') - s2d_seat_option_modular = fields.Boolean(string='Seat Options - Modular') - s2d_seat_option_custom = fields.Boolean(string='Seat Options - Custom Fabricated') - s2d_seat_hardware_modular = fields.Boolean(string='Seat Hardware - Modular') - s2d_seat_hardware_custom = fields.Boolean(string='Seat Hardware - Custom Fabricated') - s2d_adductor_modular = fields.Boolean(string='Pommel/Adductors - Modular') - s2d_adductor_custom = fields.Boolean(string='Pommel/Adductors - Custom Fabricated') - s2d_pommel_custom = fields.Boolean(string='Pommel Hardware - Custom Fabricated') - # Back Support - s2d_back_modular = fields.Boolean(string='Back Support - Modular') - s2d_back_custom = fields.Boolean(string='Back Support - Custom Fabricated') - s2d_back_option_modular = fields.Boolean(string='Back Options - Modular') - s2d_back_option_custom = fields.Boolean(string='Back Options - Custom Fabricated') - s2d_back_cover_custom = fields.Boolean(string='Back Cover - Custom Fabricated') - s2d_back_hardware_modular = fields.Boolean(string='Back Hardware - Modular') - s2d_back_hardware_custom = fields.Boolean(string='Back Hardware - Custom Fabricated') - # Complete Assembly - s2d_complete_modular = fields.Boolean(string='Complete Assembly - Modular') - s2d_complete_custom = fields.Boolean(string='Complete Assembly - Custom Fabricated') - # Headrest/Neckrest - s2d_headrest_modular = fields.Boolean(string='Headrest/Neckrest - Modular') - s2d_headrest_custom = fields.Boolean(string='Headrest/Neckrest - Custom Fabricated') - s2d_head_option_custom = fields.Boolean(string='Headrest Options - Custom Fabricated') - s2d_head_hardware_modular = fields.Boolean(string='Headrest Hardware - Modular') - s2d_head_hardware_custom = fields.Boolean(string='Headrest Hardware - Custom Fabricated') - # Positioning Belts - s2d_belt_modular = fields.Boolean(string='Positioning Belt - Modular') - s2d_belt_custom = fields.Boolean(string='Positioning Belt - Custom Fabricated') - s2d_belt_option_custom = fields.Boolean(string='Belt Options - Custom Fabricated') - # Arm Supports - s2d_arm_modular = fields.Boolean(string='Arm Support - Modular') - s2d_arm_custom = fields.Boolean(string='Arm Support - Custom Fabricated') - s2d_arm_option_modular = fields.Boolean(string='Arm Options - Modular') - s2d_arm_option_custom = fields.Boolean(string='Arm Options - Custom Fabricated') - s2d_arm_hardware_modular = fields.Boolean(string='Arm Hardware - Modular') - s2d_arm_hardware_custom = fields.Boolean(string='Arm Hardware - Custom Fabricated') - # Tray - s2d_tray_modular = fields.Boolean(string='Tray - Modular') - s2d_tray_custom = fields.Boolean(string='Tray - Custom Fabricated') - s2d_tray_option_modular = fields.Boolean(string='Tray Options - Modular') - s2d_tray_option_custom = fields.Boolean(string='Tray Options - Custom Fabricated') - # Lateral Supports - s2d_lateral_modular = fields.Boolean(string='Lateral Support - Modular') - s2d_lateral_custom = fields.Boolean(string='Lateral Support - Custom Fabricated') - s2d_lateral_option_custom = fields.Boolean(string='Lateral Options - Custom Fabricated') - s2d_lateral_hardware_custom = fields.Boolean(string='Lateral Hardware - Custom Fabricated') - # Foot/Leg Supports - s2d_foot_modular = fields.Boolean(string='Foot/Leg Support - Modular') - s2d_foot_custom = fields.Boolean(string='Foot/Leg Support - Custom Fabricated') - s2d_foot_option_modular = fields.Boolean(string='Foot Options - Modular') - s2d_foot_option_custom = fields.Boolean(string='Foot Options - Custom Fabricated') - s2d_foot_hardware_modular = fields.Boolean(string='Foot Hardware - Modular') - s2d_foot_hardware_custom = fields.Boolean(string='Foot Hardware - Custom Fabricated') - # Seating reason and confirmations - s2d_reason = fields.Char(string='Reason for Application') - s2d_replacement_status = fields.Char(string='Replacement - Mobility Status') - s2d_replacement_size = fields.Char(string='Replacement - Body Size') - s2d_replacement_adp = fields.Char(string='Replacement - Equipment Worn') - s2d_replacement_special = fields.Char(string='Replacement - Special') - s2d_confirm1 = fields.Char(string='Seating Confirmation 1') - s2d_confirm2 = fields.Char(string='Seating Confirmation 2') - s2d_custom = fields.Char(string='Custom Modifications Required') - s2d_cost_labour = fields.Char(string='Cost of Labour') - - # ------------------------------------------------------------------ - # SECTION 3 - APPLICANT CONSENT AND SIGNATURE - # ------------------------------------------------------------------ - consent_date = fields.Date(string='Consent Date') - consent_signed_by = fields.Selection([ - ('applicant', 'Applicant'), - ('agent', 'Agent'), - ], string='Signed By') - # Agent/Contact info (if signed by agent) - agent_relationship = fields.Char(string='Agent Relationship') - agent_last_name = fields.Char(string='Agent Last Name') - agent_first_name = fields.Char(string='Agent First Name') - agent_middle_initial = fields.Char(string='Agent Middle Initial') - agent_unit = fields.Char(string='Agent Unit') - agent_street_no = fields.Char(string='Agent Street Number') - agent_street_name = fields.Char(string='Agent Street Name') - agent_rural_route = fields.Char(string='Agent Rural Route') - agent_city = fields.Char(string='Agent City') - agent_province = fields.Char(string='Agent Province') - agent_postal_code = fields.Char(string='Agent Postal Code') - agent_home_phone = fields.Char(string='Agent Home Phone') - agent_bus_phone = fields.Char(string='Agent Business Phone') - agent_phone_ext = fields.Char(string='Agent Phone Ext') - - # ------------------------------------------------------------------ - # SECTION 4 - AUTHORIZER - # ------------------------------------------------------------------ - authorizer_last_name = fields.Char(string='Authorizer Last Name') - authorizer_first_name = fields.Char(string='Authorizer First Name') - authorizer_phone = fields.Char(string='Authorizer Phone') - authorizer_phone_ext = fields.Char(string='Authorizer Phone Ext') - authorizer_adp_number = fields.Char(string='Authorizer ADP Registration Number') - assessment_date = fields.Date(string='Assessment Date') - - # ------------------------------------------------------------------ - # SECTION 4 - VENDOR 1 - # ------------------------------------------------------------------ - vendor_business_name = fields.Char(string='Vendor Business Name') - vendor_adp_number = fields.Char(string='Vendor ADP Registration Number') - vendor_representative = fields.Char(string='Vendor Representative (Last, First)') - vendor_position = fields.Char(string='Vendor Position Title') - vendor_location = fields.Char(string='Vendor Location') - vendor_phone = fields.Char(string='Vendor Phone') - vendor_phone_ext = fields.Char(string='Vendor Phone Ext') - vendor_sign_date = fields.Date(string='Vendor Sign Date') - - # ------------------------------------------------------------------ - # SECTION 4 - VENDOR 2 - # ------------------------------------------------------------------ - vendor2_business_name = fields.Char(string='Vendor 2 Business Name') - vendor2_adp_number = fields.Char(string='Vendor 2 ADP Registration') - vendor2_representative = fields.Char(string='Vendor 2 Representative') - vendor2_position = fields.Char(string='Vendor 2 Position') - vendor2_location = fields.Char(string='Vendor 2 Location') - vendor2_phone = fields.Char(string='Vendor 2 Phone') - vendor2_phone_ext = fields.Char(string='Vendor 2 Phone Ext') - vendor2_sign_date = fields.Date(string='Vendor 2 Sign Date') - - # ------------------------------------------------------------------ - # SECTION 4 - EQUIPMENT SPEC & PROOF OF DELIVERY - # ------------------------------------------------------------------ - equip_vendor_invoice_no = fields.Char(string='Vendor Invoice Number') - equip_vendor_adp_reg = fields.Char(string='Vendor ADP Reg (Page 12)') - equip_cell1 = fields.Char(string='ADP Device Code') - equip_cell2 = fields.Char(string='Description of Item') - equip_cell3 = fields.Char(string='Base Device') - equip_cell4 = fields.Char(string='ADP Portion') - equip_cell5 = fields.Char(string='Client Portion') - pod_received_by = fields.Char(string='Proof of Delivery - Received By') - pod_date = fields.Date(string='Proof of Delivery Date') - - # ------------------------------------------------------------------ - # SECTION 4 - NOTE TO ADP (sections submitted checklist) - # ------------------------------------------------------------------ - note_section1 = fields.Boolean(string='Section 1 Submitted') - note_section2a = fields.Boolean(string='Section 2a Submitted') - note_section2b = fields.Boolean(string='Section 2b Submitted') - note_section2c = fields.Boolean(string='Section 2c Submitted') - note_section2d = fields.Boolean(string='Section 2d Submitted') - note_section3and4 = fields.Boolean(string='Section 3 & 4 Submitted') - note_vendor_replacement = fields.Char(string='Vendor Quote - Replacement') - note_vendor_custom = fields.Char(string='Vendor Quote - Custom Modifications') - note_funding_chart = fields.Char(string='Justification for Funding Chart') - note_letter = fields.Char(string='Letter of Rationale') - - # Computed summary - sections_submitted = fields.Char( - string='Sections Submitted', - compute='_compute_sections_submitted', store=True, - ) - - # Legacy compat fields - base_device = fields.Char( - string='Base Device Selected', - compute='_compute_base_device', store=True, - ) - reason_for_application = fields.Char( - string='Reason for Application', - compute='_compute_reason', store=True, - ) - - # ------------------------------------------------------------------ - # COMPUTED - # ------------------------------------------------------------------ - @api.depends('applicant_last_name', 'applicant_first_name', 'application_date') - def _compute_display_name(self): - for rec in self: - name_parts = [rec.applicant_last_name or '', rec.applicant_first_name or ''] - name = ', '.join(p for p in name_parts if p) or 'Unknown' - date_str = rec.application_date.strftime('%Y-%m-%d') if rec.application_date else 'No Date' - rec.display_name = f'{name} ({date_str})' - - @api.depends('note_section1', 'note_section2a', 'note_section2b', - 'note_section2c', 'note_section2d', 'note_section3and4') - def _compute_sections_submitted(self): - for rec in self: - parts = [] - if rec.note_section1: - parts.append('1') - if rec.note_section2a: - parts.append('2a') - if rec.note_section2b: - parts.append('2b') - if rec.note_section2c: - parts.append('2c') - if rec.note_section2d: - parts.append('2d') - if rec.note_section3and4: - parts.append('3+4') - rec.sections_submitted = ', '.join(parts) if parts else '' - - @api.depends('s2a_base_device', 's2b_base_device', 's2c_base_device') - def _compute_base_device(self): - for rec in self: - rec.base_device = rec.s2a_base_device or rec.s2b_base_device or rec.s2c_base_device or '' - - @api.depends('s2a_reason', 's2b_reason', 's2c_reason', 's2d_reason') - def _compute_reason(self): - for rec in self: - rec.reason_for_application = rec.s2a_reason or rec.s2b_reason or rec.s2c_reason or rec.s2d_reason or '' - - # ------------------------------------------------------------------ - # XML EXPORT - # ------------------------------------------------------------------ - def action_export_xml(self): - """Reconstruct ADP XML from stored JSON data.""" - self.ensure_one() - if not self.xml_data_json: - # Fall back to raw_xml if available - if self.raw_xml: - xml_content = self.raw_xml.encode('utf-8') - attachment = self.env['ir.attachment'].create({ - 'name': f'{self.applicant_last_name}_{self.applicant_first_name}_data.xml', - 'type': 'binary', - 'datas': base64.b64encode(xml_content), - 'mimetype': 'application/xml', - }) - return { - 'type': 'ir.actions.act_url', - 'url': f'/web/content/{attachment.id}?download=true', - 'target': 'new', - } - return False - - try: - data = json.loads(self.xml_data_json) - xml_str = self._json_to_xml(data) - attachment = self.env['ir.attachment'].create({ - 'name': f'{self.applicant_last_name or "export"}_{self.applicant_first_name or "data"}_data.xml', - 'type': 'binary', - 'datas': base64.b64encode(xml_str.encode('utf-8')), - 'mimetype': 'application/xml', - }) - return { - 'type': 'ir.actions.act_url', - 'url': f'/web/content/{attachment.id}?download=true', - 'target': 'new', - } - except Exception as e: - _logger.exception('XML export error: %s', e) - return False - - def _json_to_xml(self, data): - """Reconstruct the ADP XML from flat JSON dictionary.""" - # Build the XML tree following the exact ADP structure - root = ET.Element('form1') - form = ET.SubElement(root, 'Form') - - # Simple top-level fields - self._set_el(form, 'deviceCategory', data.get('deviceCategory', '')) - self._set_el(form, 'VersionNumber', data.get('VersionNumber', '')) - - # Section 1 - s1 = ET.SubElement(form, 'section1') - s1_fields = [ - 'applicantLastname', 'applicantFirstname', 'applicantMiddleinitial', - 'healthNo', 'versionNo', 'DateOfBirth', 'nameLTCH', - 'unitNo', 'streetNo', 'streetName', 'rrRoute', - 'city', 'province', 'postalCode', - 'homePhone', 'busPhone', 'phoneExtension', - ] - for f in s1_fields: - self._set_el(s1, f, data.get(f'section1.{f}', '')) - - # Confirmation of benefit - cob = ET.SubElement(s1, 'confirmationOfBenefit') - for f in ['q1Yn', 'q1Ifyes', 'q2Yn', 'q3Yn']: - self._set_el(cob, f, data.get(f'section1.confirmationOfBenefit.{f}', '')) - - # Section 2 - s2 = ET.SubElement(form, 'section2') - - # Devices and Eligibility - de = ET.SubElement(s2, 'devicesandEligibility') - de_fields = [ - 'condition', 'status', 'none', 'forearm', 'wheeled', 'manual', - 'power', 'addOn', 'scooter', 'seating', 'tiltSystem', 'reclineSystem', - 'legRests', 'frame', 'stroller', 'deviceForearm', 'deviceWheeled', - 'deviceManual', 'deviceAmbulation', 'deviceDependent', 'deviceDynamic', - 'manualDyanmic', 'manualWheelchair', 'powerBase', 'powerScooter', - 'ambulation', 'positioning', 'highTech', 'standingFrame', - 'adpFunded', 'nonADPFunded', - ] - for f in de_fields: - self._set_el(de, f, data.get(f'section2.devicesandEligibility.{f}', '')) - - # Sections 2a, 2b, 2c, 2d - for section_key in ['section2a', 'section2b', 'section2c', 'section2d']: - section_data = {k.split(f'section2.{section_key}.')[1]: v - for k, v in data.items() - if k.startswith(f'section2.{section_key}.')} - sec = ET.SubElement(s2, section_key) - # Preserve field order from the data keys - ordered_keys = [k.split(f'section2.{section_key}.')[1] - for k in sorted(data.keys()) - if k.startswith(f'section2.{section_key}.')] - for f in ordered_keys: - self._set_el(sec, f, section_data.get(f, '')) - - # Section 3 - s3 = ET.SubElement(form, 'section3') - sig = ET.SubElement(s3, 'sig') - for f in ['signature', 'person', 'Date']: - self._set_el(sig, f, data.get(f'section3.sig.{f}', '')) - contact = ET.SubElement(s3, 'contact') - contact_fields = [ - 'relationship', 'applicantLastname', 'applicantFirstname', - 'applicantMiddleinitial', 'unitNo', 'streetNo', 'streetName', - 'rrRoute', 'city', 'province', 'postalCode', - 'homePhone', 'busPhone', 'phoneExtension', - ] - for f in contact_fields: - self._set_el(contact, f, data.get(f'section3.contact.{f}', '')) - - # Section 4 - s4 = ET.SubElement(form, 'section4') - # Authorizer - auth = ET.SubElement(s4, 'authorizer') - for f in ['authorizerLastname', 'authorizerFirstname', 'busPhone', - 'phoneExtension', 'adpNo', 'signature', 'Date']: - self._set_el(auth, f, data.get(f'section4.authorizer.{f}', '')) - # Vendor - vendor = ET.SubElement(s4, 'vendor') - for f in ['vendorBusName', 'adpVendorRegNo', 'vendorLastfirstname', - 'positionTitle', 'vendorLocation', 'busPhone', - 'phoneExtension', 'signature', 'Date']: - self._set_el(vendor, f, data.get(f'section4.vendor.{f}', '')) - # Vendor 2 - v2 = ET.SubElement(s4, 'vendor2') - for f in ['vendorBusName', 'adpVendorRegNo', 'vendorLastfirstname', - 'positionTitle', 'vendorLocation', 'busPhone', - 'phoneExtension', 'signature', 'Date']: - self._set_el(v2, f, data.get(f'section4.vendor2.{f}', '')) - # Equipment Spec - eq = ET.SubElement(s4, 'equipmentSpec') - self._set_el(eq, 'vendorInvoiceNo', data.get('section4.equipmentSpec.vendorInvoiceNo', '')) - self._set_el(eq, 'vendorADPRegNo', data.get('section4.equipmentSpec.vendorADPRegNo', '')) - t2 = ET.SubElement(eq, 'Table2') - r1 = ET.SubElement(t2, 'Row1') - for c in ['Cell1', 'Cell2', 'Cell3', 'Cell4', 'Cell5']: - self._set_el(r1, c, data.get(f'section4.equipmentSpec.Table2.Row1.{c}', '')) - # Proof of delivery - pod = ET.SubElement(s4, 'proofOfDelivery') - for f in ['signature', 'receivedBy', 'Date']: - self._set_el(pod, f, data.get(f'section4.proofOfDelivery.{f}', '')) - # Note to ADP - note = ET.SubElement(s4, 'noteToADP') - for f in ['section1', 'section2a', 'section2b', 'section2c', 'section2d', - 'section3and4', 'vendorReplacement', 'vendorCustom', - 'fundingChart', 'letter']: - self._set_el(note, f, data.get(f'section4.noteToADP.{f}', '')) - - # Convert to string - tree = ET.ElementTree(root) - ET.indent(tree, space='') - import io - buf = io.BytesIO() - tree.write(buf, encoding='unicode', xml_declaration=True) - return buf.getvalue() - - @staticmethod - def _set_el(parent, tag, value): - """Create a child element, self-closing if empty.""" - el = ET.SubElement(parent, tag) - if value: - el.text = str(value) diff --git a/fusion_claims/fusion_claims/models/adp_posting_schedule.py b/fusion_claims/fusion_claims/models/adp_posting_schedule.py deleted file mode 100644 index 29cae5c..0000000 --- a/fusion_claims/fusion_claims/models/adp_posting_schedule.py +++ /dev/null @@ -1,262 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2025 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) -# Part of the Fusion Claim Assistant product family. - -import logging -from datetime import date, timedelta -from odoo import models, api - -_logger = logging.getLogger(__name__) - - -class ADPPostingScheduleMixin(models.AbstractModel): - """Mixin providing ADP posting schedule calculation methods. - - This mixin can be inherited by any model that needs to calculate - ADP posting dates and deadlines. - - Posting Schedule Logic: - - Posting days occur every N days (default 14) from a base date - - Submission deadline: Wednesday 6 PM before posting day - - Delivery reminder: Tuesday of posting week - - Billing reminder: Monday of posting week - - Payment processed: Posting day + 7 days - - Payment received: Posting day + 10 days - """ - _name = 'fusion_claims.adp.posting.schedule.mixin' - _description = 'ADP Posting Schedule Mixin' - - @api.model - def _get_adp_posting_base_date(self): - """Get the configured base posting date from settings.""" - ICP = self.env['ir.config_parameter'].sudo() - base_date_str = ICP.get_param('fusion_claims.adp_posting_base_date', '2026-01-23') - try: - return date.fromisoformat(base_date_str) - except (ValueError, TypeError): - return date(2026, 1, 23) - - @api.model - def _get_adp_posting_frequency(self): - """Get the configured posting frequency in days from settings.""" - ICP = self.env['ir.config_parameter'].sudo() - frequency = ICP.get_param('fusion_claims.adp_posting_frequency_days', '14') - try: - return int(frequency) - except (ValueError, TypeError): - return 14 - - @api.model - def _get_next_posting_date(self, from_date=None): - """Calculate the next ADP posting date from a given date. - - Args: - from_date: The date to calculate from (default: today) - - Returns: - date: The next posting date - """ - if from_date is None: - from_date = date.today() - elif hasattr(from_date, 'date'): - from_date = from_date.date() - - base_date = self._get_adp_posting_base_date() - frequency = self._get_adp_posting_frequency() - - if frequency <= 0: - frequency = 14 - - # Calculate days since base date - days_diff = (from_date - base_date).days - - if days_diff < 0: - # from_date is before base_date, so base_date is the next posting date - return base_date - - # Calculate how many complete cycles have passed - cycles_passed = days_diff // frequency - - # The next posting date is (cycles_passed + 1) * frequency days from base - next_posting = base_date + timedelta(days=(cycles_passed + 1) * frequency) - - # If from_date equals a posting date, return the next one - if days_diff % frequency == 0: - return next_posting - - return next_posting - - @api.model - def _get_current_posting_date(self, from_date=None): - """Get the posting date for the current cycle (may be in the past). - - Args: - from_date: The date to calculate from (default: today) - - Returns: - date: The current cycle's posting date - """ - if from_date is None: - from_date = date.today() - elif hasattr(from_date, 'date'): - from_date = from_date.date() - - base_date = self._get_adp_posting_base_date() - frequency = self._get_adp_posting_frequency() - - if frequency <= 0: - frequency = 14 - - days_diff = (from_date - base_date).days - - if days_diff < 0: - return base_date - - cycles_passed = days_diff // frequency - return base_date + timedelta(days=cycles_passed * frequency) - - @api.model - def _get_posting_week_wednesday(self, posting_date): - """Get the Wednesday before the posting date (submission deadline day). - - The submission deadline is Wednesday 6 PM of the posting week. - Posting day is typically Friday, so Wednesday is 2 days before. - - Args: - posting_date: The posting date - - Returns: - date: The Wednesday before posting date - """ - if hasattr(posting_date, 'date'): - posting_date = posting_date.date() - - # Find the Wednesday of the same week - # weekday(): Monday=0, Tuesday=1, Wednesday=2, Thursday=3, Friday=4 - days_since_wednesday = (posting_date.weekday() - 2) % 7 - if days_since_wednesday == 0 and posting_date.weekday() != 2: - days_since_wednesday = 7 - - return posting_date - timedelta(days=days_since_wednesday) - - @api.model - def _get_posting_week_tuesday(self, posting_date): - """Get the Tuesday of the posting week (delivery reminder date). - - Args: - posting_date: The posting date - - Returns: - date: The Tuesday of posting week - """ - if hasattr(posting_date, 'date'): - posting_date = posting_date.date() - - # Find the Tuesday of the same week - days_since_tuesday = (posting_date.weekday() - 1) % 7 - if days_since_tuesday == 0 and posting_date.weekday() != 1: - days_since_tuesday = 7 - - return posting_date - timedelta(days=days_since_tuesday) - - @api.model - def _get_posting_week_monday(self, posting_date): - """Get the Monday of the posting week (billing reminder date). - - Args: - posting_date: The posting date - - Returns: - date: The Monday of posting week - """ - if hasattr(posting_date, 'date'): - posting_date = posting_date.date() - - # Find the Monday of the same week - days_since_monday = posting_date.weekday() # Monday=0 - return posting_date - timedelta(days=days_since_monday) - - @api.model - def _get_expected_payment_date(self, posting_date): - """Get the expected payment received date (posting + 10 days). - - Args: - posting_date: The posting date - - Returns: - date: The expected payment received date - """ - if hasattr(posting_date, 'date'): - posting_date = posting_date.date() - - return posting_date + timedelta(days=10) - - @api.model - def _get_payment_processed_date(self, posting_date): - """Get the payment processed date (posting + 7 days). - - Args: - posting_date: The posting date - - Returns: - date: The payment processed date - """ - if hasattr(posting_date, 'date'): - posting_date = posting_date.date() - - return posting_date + timedelta(days=7) - - @api.model - def _get_adp_billing_reminder_user(self): - """Get the configured billing reminder user from settings.""" - ICP = self.env['ir.config_parameter'].sudo() - user_id_str = ICP.get_param('fusion_claims.adp_billing_reminder_user_id', '') - if user_id_str: - try: - user_id = int(user_id_str) - return self.env['res.users'].browse(user_id).exists() - except (ValueError, TypeError): - pass - return self.env['res.users'] - - @api.model - def _get_adp_correction_reminder_users(self): - """Get the configured correction reminder users from settings.""" - ICP = self.env['ir.config_parameter'].sudo() - user_ids_str = ICP.get_param('fusion_claims.adp_correction_reminder_user_ids', '') - if user_ids_str: - try: - user_ids = [int(x.strip()) for x in user_ids_str.split(',') if x.strip()] - return self.env['res.users'].browse(user_ids).exists() - except (ValueError, TypeError): - pass - return self.env['res.users'] - - @api.model - def _is_past_submission_deadline(self, posting_date=None, check_time=True): - """Check if we're past the submission deadline for a posting cycle. - - Args: - posting_date: The posting date to check (default: next posting date) - check_time: If True, checks if past 6 PM on Wednesday - - Returns: - bool: True if past deadline - """ - from datetime import datetime - - if posting_date is None: - posting_date = self._get_next_posting_date() - - wednesday = self._get_posting_week_wednesday(posting_date) - today = date.today() - - if today > wednesday: - return True - elif today == wednesday and check_time: - # Check if past 6 PM (18:00) - now = datetime.now() - return now.hour >= 18 - - return False diff --git a/fusion_claims/fusion_claims/models/ai_agent_ext.py b/fusion_claims/fusion_claims/models/ai_agent_ext.py deleted file mode 100644 index 520c092..0000000 --- a/fusion_claims/fusion_claims/models/ai_agent_ext.py +++ /dev/null @@ -1,164 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) - -import json -import logging - -from odoo import api, models - -_logger = logging.getLogger(__name__) - - -class AIAgentFusionClaims(models.Model): - """Extend ai.agent with Fusion Claims tool methods.""" - _inherit = 'ai.agent' - - def _fc_tool_search_clients(self, search_term=None, city_filter=None, condition_filter=None): - """AI Tool: Search client profiles.""" - Profile = self.env['fusion.client.profile'].sudo() - domain = [] - if search_term: - domain = ['|', '|', '|', - ('first_name', 'ilike', search_term), - ('last_name', 'ilike', search_term), - ('health_card_number', 'ilike', search_term), - ('city', 'ilike', search_term), - ] - if city_filter: - domain.append(('city', 'ilike', city_filter)) - if condition_filter: - domain.append(('medical_condition', 'ilike', condition_filter)) - - profiles = Profile.search(domain, limit=20) - results = [] - for p in profiles: - results.append({ - 'id': p.id, - 'name': p.display_name, - 'health_card': p.health_card_number or '', - 'dob': str(p.date_of_birth) if p.date_of_birth else '', - 'city': p.city or '', - 'condition': (p.medical_condition or '')[:100], - 'claims': p.claim_count, - 'total_adp': float(p.total_adp_funded), - 'total_client': float(p.total_client_portion), - }) - return json.dumps({'count': len(results), 'profiles': results}) - - def _fc_tool_client_details(self, profile_id): - """AI Tool: Get detailed client information.""" - Profile = self.env['fusion.client.profile'].sudo() - profile = Profile.browse(int(profile_id)) - if not profile.exists(): - return json.dumps({'error': 'Profile not found'}) - - # Get orders - orders = [] - if profile.partner_id: - for o in self.env['sale.order'].sudo().search([ - ('partner_id', '=', profile.partner_id.id), - ('x_fc_sale_type', '!=', False), - ], limit=20): - orders.append({ - 'name': o.name, - 'sale_type': o.x_fc_sale_type, - 'status': o.x_fc_adp_application_status or '', - 'adp_total': float(o.x_fc_adp_portion_total), - 'client_total': float(o.x_fc_client_portion_total), - 'total': float(o.amount_total), - 'date': str(o.date_order.date()) if o.date_order else '', - }) - - # Get applications - apps = [] - for a in profile.application_data_ids[:10]: - apps.append({ - 'date': str(a.application_date) if a.application_date else '', - 'device': a.base_device or '', - 'category': a.device_category or '', - 'reason': a.reason_for_application or '', - 'condition': (a.medical_condition or '')[:100], - 'authorizer': f'{a.authorizer_first_name or ""} {a.authorizer_last_name or ""}'.strip(), - }) - - return json.dumps({ - 'profile': { - 'id': profile.id, - 'name': profile.display_name, - 'first_name': profile.first_name, - 'last_name': profile.last_name, - 'health_card': profile.health_card_number or '', - 'dob': str(profile.date_of_birth) if profile.date_of_birth else '', - 'city': profile.city or '', - 'province': profile.province or '', - 'postal_code': profile.postal_code or '', - 'phone': profile.home_phone or '', - 'condition': profile.medical_condition or '', - 'mobility': profile.mobility_status or '', - 'benefits': { - 'social_assistance': profile.receives_social_assistance, - 'type': profile.benefit_type or '', - 'wsib': profile.wsib_eligible, - 'vac': profile.vac_eligible, - }, - 'claims_count': profile.claim_count, - 'total_adp': float(profile.total_adp_funded), - 'total_client': float(profile.total_client_portion), - 'total_amount': float(profile.total_amount), - 'last_assessment': str(profile.last_assessment_date) if profile.last_assessment_date else '', - }, - 'orders': orders, - 'applications': apps, - }) - - def _fc_tool_claims_stats(self): - """AI Tool: Get aggregated claims statistics.""" - SO = self.env['sale.order'].sudo() - Profile = self.env['fusion.client.profile'].sudo() - - total_profiles = Profile.search_count([]) - total_orders = SO.search_count([('x_fc_sale_type', '!=', False)]) - - # By sale type - type_data = SO.read_group( - [('x_fc_sale_type', '!=', False)], - ['x_fc_sale_type', 'amount_total:sum'], - ['x_fc_sale_type'], - ) - by_type = {} - for r in type_data: - by_type[r['x_fc_sale_type']] = { - 'count': r['x_fc_sale_type_count'], - 'total': float(r['amount_total'] or 0), - } - - # By status - status_data = SO.read_group( - [('x_fc_sale_type', '!=', False), ('x_fc_adp_application_status', '!=', False)], - ['x_fc_adp_application_status'], - ['x_fc_adp_application_status'], - ) - by_status = {} - for r in status_data: - by_status[r['x_fc_adp_application_status']] = r['x_fc_adp_application_status_count'] - - # By city (top 10) - city_data = Profile.read_group( - [('city', '!=', False)], - ['city'], - ['city'], - limit=10, - orderby='city_count desc', - ) - by_city = {} - for r in city_data: - by_city[r['city']] = r['city_count'] - - return json.dumps({ - 'total_profiles': total_profiles, - 'total_orders': total_orders, - 'by_sale_type': by_type, - 'by_status': by_status, - 'top_cities': by_city, - }) diff --git a/fusion_claims/fusion_claims/models/client_chat.py b/fusion_claims/fusion_claims/models/client_chat.py deleted file mode 100644 index 6d508df..0000000 --- a/fusion_claims/fusion_claims/models/client_chat.py +++ /dev/null @@ -1,350 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) - -import json -import logging - -from odoo import api, fields, models -from odoo.exceptions import UserError - -_logger = logging.getLogger(__name__) - - -class FusionClientChatSession(models.Model): - _name = 'fusion.client.chat.session' - _description = 'Client Intelligence Chat Session' - _order = 'create_date desc' - - name = fields.Char(string='Session Title', required=True, - default=lambda self: f'Chat - {fields.Date.today()}') - profile_id = fields.Many2one( - 'fusion.client.profile', string='Client Profile', - ondelete='set null', - help='If set, chat is scoped to this specific client', - ) - user_id = fields.Many2one( - 'res.users', string='User', default=lambda self: self.env.user, - required=True, - ) - message_ids = fields.One2many( - 'fusion.client.chat.message', 'session_id', string='Messages', - ) - state = fields.Selection([ - ('active', 'Active'), - ('archived', 'Archived'), - ], default='active', string='State') - - # Input field for the form view - user_input = fields.Text(string='Your Question') - - def action_send_message(self): - """Process user message and generate AI response.""" - self.ensure_one() - if not self.user_input or not self.user_input.strip(): - return - - question = self.user_input.strip() - - # Create user message - self.env['fusion.client.chat.message'].create({ - 'session_id': self.id, - 'role': 'user', - 'content': question, - }) - - # Generate AI response - try: - response = self._generate_ai_response(question) - except Exception as e: - _logger.exception('AI chat error: %s', e) - response = f'Sorry, I encountered an error processing your question. Error: {str(e)}' - - # Create assistant message - msg = self.env['fusion.client.chat.message'].create({ - 'session_id': self.id, - 'role': 'assistant', - 'content': response, - }) - - # Clear input - self.user_input = False - return { - 'type': 'ir.actions.act_window', - 'res_model': 'fusion.client.chat.session', - 'view_mode': 'form', - 'res_id': self.id, - 'target': 'current', - } - - def _generate_ai_response(self, question): - """Generate an AI-powered response to the user question. - - Uses OpenAI API to analyze the question, query relevant data, - and formulate a response. - """ - ICP = self.env['ir.config_parameter'].sudo() - api_key = ICP.get_param('fusion_claims.ai_api_key', '') - if not api_key: - return self._generate_local_response(question) - - ai_model = ICP.get_param('fusion_claims.ai_model', 'gpt-4o-mini') - - # Build context about available data - context_data = self._build_data_context(question) - - # Build system prompt - system_prompt = self._build_system_prompt() - - # Build messages - messages = [{'role': 'system', 'content': system_prompt}] - - # Add conversation history (last 10 messages) - history = self.message_ids.sorted('create_date')[-10:] - for msg in history: - messages.append({'role': msg.role, 'content': msg.content}) - - # Add current question with data context - user_msg = question - if context_data: - user_msg += f'\n\n--- Retrieved Data ---\n{context_data}' - messages.append({'role': 'user', 'content': user_msg}) - - # Call OpenAI API - try: - import requests - response = requests.post( - 'https://api.openai.com/v1/chat/completions', - headers={ - 'Authorization': f'Bearer {api_key}', - 'Content-Type': 'application/json', - }, - json={ - 'model': ai_model, - 'messages': messages, - 'max_tokens': 2000, - 'temperature': 0.3, - }, - timeout=30, - ) - response.raise_for_status() - result = response.json() - return result['choices'][0]['message']['content'] - except ImportError: - return self._generate_local_response(question) - except Exception as e: - _logger.warning('OpenAI API error: %s', e) - return self._generate_local_response(question) - - def _generate_local_response(self, question): - """Generate a response without AI, using direct database queries. - - This is the fallback when no API key is configured. - """ - question_lower = question.lower() - Profile = self.env['fusion.client.profile'] - SaleOrder = self.env['sale.order'] - - # If scoped to a specific profile - if self.profile_id: - profile = self.profile_id - orders = SaleOrder.search([ - ('partner_id', '=', profile.partner_id.id), - ('x_fc_sale_type', '!=', False), - ]) if profile.partner_id else SaleOrder - - lines = [] - lines.append(f'**Client: {profile.display_name}**') - lines.append(f'- Health Card: {profile.health_card_number or "N/A"}') - lines.append(f'- Date of Birth: {profile.date_of_birth or "N/A"}') - lines.append(f'- City: {profile.city or "N/A"}') - lines.append(f'- Medical Condition: {profile.medical_condition or "N/A"}') - lines.append(f'- Mobility Status: {profile.mobility_status or "N/A"}') - lines.append(f'- Total Claims: {len(orders)}') - lines.append(f'- Total ADP Funded: ${profile.total_adp_funded:,.2f}') - lines.append(f'- Total Client Portion: ${profile.total_client_portion:,.2f}') - - if orders: - lines.append('\n**Claims History:**') - for order in orders[:10]: - status = dict(order._fields['x_fc_adp_application_status'].selection).get( - order.x_fc_adp_application_status, order.x_fc_adp_application_status or 'N/A' - ) - lines.append( - f'- {order.name}: {order.x_fc_sale_type or "N/A"} | ' - f'Status: {status} | ' - f'ADP: ${order.x_fc_adp_portion_total:,.2f} | ' - f'Client: ${order.x_fc_client_portion_total:,.2f}' - ) - - apps = profile.application_data_ids[:5] - if apps: - lines.append('\n**Application History:**') - for app in apps: - lines.append( - f'- {app.application_date or "No date"}: ' - f'{app.device_category or "N/A"} | ' - f'Device: {app.base_device or "N/A"} | ' - f'Reason: {app.reason_for_application or "N/A"}' - ) - - return '\n'.join(lines) - - # Global queries - total_profiles = Profile.search_count([]) - total_orders = SaleOrder.search_count([('x_fc_sale_type', '!=', False)]) - - if 'how many' in question_lower or 'count' in question_lower: - if 'client' in question_lower or 'profile' in question_lower: - return f'There are currently **{total_profiles}** client profiles in the system.' - if 'claim' in question_lower or 'order' in question_lower or 'case' in question_lower: - return f'There are currently **{total_orders}** claims/orders in the system.' - - # Search for specific client - if 'find' in question_lower or 'search' in question_lower or 'show' in question_lower: - # Try to extract name from question - words = question.split() - profiles = Profile.search([], limit=20) - for word in words: - if len(word) > 2 and word[0].isupper(): - found = Profile.search([ - '|', - ('first_name', 'ilike', word), - ('last_name', 'ilike', word), - ], limit=5) - if found: - profiles = found - break - - if profiles: - lines = [f'Found **{len(profiles)}** matching profile(s):'] - for p in profiles[:10]: - lines.append( - f'- **{p.display_name}** | HC: {p.health_card_number or "N/A"} | ' - f'City: {p.city or "N/A"} | Claims: {p.claim_count}' - ) - return '\n'.join(lines) - - return ( - f'I have access to **{total_profiles}** client profiles and **{total_orders}** claims. ' - f'You can ask me questions like:\n' - f'- "How many clients are from Brampton?"\n' - f'- "Find client Raymond Wellesley"\n' - f'- "Show all clients with CVA diagnosis"\n\n' - f'For more intelligent responses, configure an OpenAI API key in ' - f'Fusion Claims > Configuration > Settings.' - ) - - def _build_system_prompt(self): - """Build the system prompt for the AI.""" - profile_context = '' - if self.profile_id: - p = self.profile_id - profile_context = f""" -You are currently looking at a specific client profile: -- Name: {p.display_name} -- Health Card: {p.health_card_number or 'N/A'} -- DOB: {p.date_of_birth or 'N/A'} -- City: {p.city or 'N/A'} -- Medical Condition: {p.medical_condition or 'N/A'} -- Mobility Status: {p.mobility_status or 'N/A'} -- Total Claims: {p.claim_count} -- Total ADP Funded: ${p.total_adp_funded:,.2f} -- Total Client Portion: ${p.total_client_portion:,.2f} -""" - - return f"""You are a helpful AI assistant for Fusion Claims, a healthcare equipment claims management system. -You help users find information about clients, their ADP (Assistive Devices Program) claims, funding history, -medical conditions, and devices. - -Available data includes: -- Client profiles with personal info, health card numbers, addresses, medical conditions -- ADP application data parsed from XML submissions -- Sale orders with funding type, status, ADP/client portions -- Device information (wheelchairs, walkers, power bases, seating) - -Funding types: ADP, ODSP, WSIB, March of Dimes, Muscular Dystrophy, Insurance, Hardship Funding, Rentals, Direct/Private -Client types: REG (75%/25%), ODS, OWP, ACS, LTC, SEN, CCA (100%/0%) -{profile_context} -Answer concisely and include specific data when available. Format monetary values with $ and commas.""" - - def _build_data_context(self, question): - """Query relevant data based on the question to provide context to AI.""" - question_lower = question.lower() - context_parts = [] - - Profile = self.env['fusion.client.profile'] - SaleOrder = self.env['sale.order'] - - if self.profile_id: - # Scoped to specific client - load their data - p = self.profile_id - orders = SaleOrder.search([ - ('partner_id', '=', p.partner_id.id), - ('x_fc_sale_type', '!=', False), - ], limit=20) if p.partner_id else SaleOrder - - if orders: - order_data = [] - for o in orders: - order_data.append({ - 'name': o.name, - 'sale_type': o.x_fc_sale_type, - 'status': o.x_fc_adp_application_status, - 'adp_total': o.x_fc_adp_portion_total, - 'client_total': o.x_fc_client_portion_total, - 'amount_total': o.amount_total, - 'date': str(o.date_order) if o.date_order else '', - }) - context_parts.append(f'Orders: {json.dumps(order_data)}') - - apps = p.application_data_ids[:10] - if apps: - app_data = [] - for a in apps: - app_data.append({ - 'date': str(a.application_date) if a.application_date else '', - 'device_category': a.device_category, - 'base_device': a.base_device or '', - 'condition': a.medical_condition or '', - 'reason': a.reason_for_application or '', - 'authorizer': f'{a.authorizer_first_name} {a.authorizer_last_name}'.strip(), - }) - context_parts.append(f'Applications: {json.dumps(app_data)}') - else: - # Global query - provide summary stats - total_profiles = Profile.search_count([]) - total_orders = SaleOrder.search_count([('x_fc_sale_type', '!=', False)]) - - # City distribution - if 'city' in question_lower or 'cities' in question_lower or 'where' in question_lower: - city_data = SaleOrder.read_group( - [('x_fc_sale_type', '!=', False), ('partner_id.city', '!=', False)], - ['partner_id'], - ['partner_id'], - limit=20, - ) - context_parts.append(f'Total profiles: {total_profiles}, Total orders: {total_orders}') - - context_parts.append(f'Summary: {total_profiles} profiles, {total_orders} orders') - - return '\n'.join(context_parts) if context_parts else '' - - -class FusionClientChatMessage(models.Model): - _name = 'fusion.client.chat.message' - _description = 'Chat Message' - _order = 'create_date asc' - - session_id = fields.Many2one( - 'fusion.client.chat.session', string='Session', - required=True, ondelete='cascade', - ) - role = fields.Selection([ - ('user', 'User'), - ('assistant', 'Assistant'), - ], string='Role', required=True) - content = fields.Text(string='Content', required=True) - timestamp = fields.Datetime( - string='Timestamp', default=fields.Datetime.now, - ) diff --git a/fusion_claims/fusion_claims/models/client_profile.py b/fusion_claims/fusion_claims/models/client_profile.py deleted file mode 100644 index 55bfd54..0000000 --- a/fusion_claims/fusion_claims/models/client_profile.py +++ /dev/null @@ -1,298 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) - -from odoo import api, fields, models - - -class FusionClientProfile(models.Model): - _name = 'fusion.client.profile' - _description = 'Client Profile' - _order = 'last_name, first_name' - _rec_name = 'display_name' - _inherit = ['mail.thread', 'mail.activity.mixin'] - - # ------------------------------------------------------------------ - # PERSONAL INFORMATION (from ADP XML Section 1) - # ------------------------------------------------------------------ - partner_id = fields.Many2one( - 'res.partner', string='Odoo Contact', - help='Linked contact record in Odoo', - ) - first_name = fields.Char(string='First Name', tracking=True) - last_name = fields.Char(string='Last Name', tracking=True) - middle_initial = fields.Char(string='Middle Initial') - display_name = fields.Char( - string='Name', compute='_compute_display_name', store=True, - ) - health_card_number = fields.Char( - string='Health Card Number', index=True, tracking=True, - help='Ontario Health Card Number (10 digits)', - ) - health_card_version = fields.Char(string='Health Card Version') - date_of_birth = fields.Date(string='Date of Birth', tracking=True) - ltch_name = fields.Char( - string='Long-Term Care Home', - help='Name of LTCH if applicable', - ) - - # ------------------------------------------------------------------ - # ADDRESS - # ------------------------------------------------------------------ - unit_number = fields.Char(string='Unit Number') - street_number = fields.Char(string='Street Number') - street_name = fields.Char(string='Street Name') - rural_route = fields.Char(string='Lot/Concession/Rural Route') - city = fields.Char(string='City', index=True, tracking=True) - province = fields.Char(string='Province', default='ON') - postal_code = fields.Char(string='Postal Code') - - # ------------------------------------------------------------------ - # CONTACT - # ------------------------------------------------------------------ - home_phone = fields.Char(string='Home Phone') - business_phone = fields.Char(string='Business Phone') - phone_extension = fields.Char(string='Phone Extension') - - # ------------------------------------------------------------------ - # BENEFITS ELIGIBILITY (from XML confirmationOfBenefit) - # ------------------------------------------------------------------ - receives_social_assistance = fields.Boolean( - string='Receives Social Assistance', tracking=True, - ) - benefit_type = fields.Selection([ - ('owp', 'Ontario Works Program (OWP)'), - ('odsp', 'Ontario Disability Support Program (ODSP)'), - ('acsd', 'Assistance to Children with Severe Disabilities (ACSD)'), - ], string='Benefit Type', tracking=True) - wsib_eligible = fields.Boolean(string='WSIB Eligible', tracking=True) - vac_eligible = fields.Boolean( - string='Veterans Affairs Canada Eligible', tracking=True, - ) - - # ------------------------------------------------------------------ - # CURRENT MEDICAL STATUS (updated from latest XML) - # ------------------------------------------------------------------ - medical_condition = fields.Text( - string='Medical Condition/Diagnosis', tracking=True, - help='Current presenting medical condition from latest ADP application', - ) - mobility_status = fields.Text( - string='Functional Mobility Status', tracking=True, - help='Current functional mobility status from latest ADP application', - ) - last_assessment_date = fields.Date( - string='Last Assessment Date', tracking=True, - ) - - # ------------------------------------------------------------------ - # RELATIONSHIPS - # ------------------------------------------------------------------ - application_data_ids = fields.One2many( - 'fusion.adp.application.data', 'profile_id', - string='ADP Applications', - ) - # Chat is handled via Odoo's native AI agent (discuss.channel with ai_chat type) - - # ------------------------------------------------------------------ - # COMPUTED FIELDS - # ------------------------------------------------------------------ - claim_count = fields.Integer( - string='Claims', compute='_compute_claim_stats', store=True, - ) - total_adp_funded = fields.Monetary( - string='Total ADP Funded', compute='_compute_claim_stats', store=True, - currency_field='currency_id', - ) - total_client_portion = fields.Monetary( - string='Total Client Portion', compute='_compute_claim_stats', store=True, - currency_field='currency_id', - ) - total_amount = fields.Monetary( - string='Total Amount', compute='_compute_claim_stats', store=True, - currency_field='currency_id', - ) - currency_id = fields.Many2one( - 'res.currency', string='Currency', - default=lambda self: self.env.company.currency_id, - ) - application_count = fields.Integer( - string='Applications', compute='_compute_application_count', - ) - - # ------------------------------------------------------------------ - # AI ANALYSIS (auto-computed from application data) - # ------------------------------------------------------------------ - ai_summary = fields.Text( - string='Summary', - compute='_compute_ai_analysis', - ) - ai_risk_flags = fields.Text( - string='Risk Flags', - compute='_compute_ai_analysis', - ) - ai_last_analyzed = fields.Datetime(string='Last AI Analysis') - - # ------------------------------------------------------------------ - # COMPUTED METHODS - # ------------------------------------------------------------------ - @api.depends('first_name', 'last_name') - def _compute_display_name(self): - for profile in self: - parts = [profile.last_name or '', profile.first_name or ''] - profile.display_name = ', '.join(p for p in parts if p) or 'New Profile' - - @api.depends('partner_id', 'partner_id.sale_order_ids', - 'partner_id.sale_order_ids.x_fc_adp_portion_total', - 'partner_id.sale_order_ids.x_fc_client_portion_total', - 'partner_id.sale_order_ids.amount_total') - def _compute_claim_stats(self): - for profile in self: - if profile.partner_id: - orders = self.env['sale.order'].search([ - ('partner_id', '=', profile.partner_id.id), - ('x_fc_sale_type', '!=', False), - ]) - profile.claim_count = len(orders) - profile.total_adp_funded = sum(orders.mapped('x_fc_adp_portion_total')) - profile.total_client_portion = sum(orders.mapped('x_fc_client_portion_total')) - profile.total_amount = sum(orders.mapped('amount_total')) - else: - profile.claim_count = 0 - profile.total_adp_funded = 0 - profile.total_client_portion = 0 - profile.total_amount = 0 - - def _compute_application_count(self): - for profile in self: - profile.application_count = len(profile.application_data_ids) - - @api.depends('application_data_ids', 'application_data_ids.application_date', - 'application_data_ids.base_device', 'application_data_ids.reason_for_application') - def _compute_ai_analysis(self): - for profile in self: - apps = profile.application_data_ids.sorted('application_date', reverse=True) - - # --- SUMMARY --- - summary_lines = [] - - # Number of applications - app_count = len(apps) - summary_lines.append(f"Total Applications: {app_count}") - - # Last funding history - if apps: - latest = apps[0] - date_str = latest.application_date.strftime('%B %d, %Y') if latest.application_date else 'Unknown date' - device = latest.base_device or 'Not specified' - category = dict(latest._fields['device_category'].selection).get( - latest.device_category, latest.device_category or 'N/A' - ) if latest.device_category else 'N/A' - summary_lines.append(f"Last Application: {date_str}") - summary_lines.append(f"Last Device: {device} ({category})") - - # Reason for last application - reason = latest.reason_for_application or 'Not specified' - summary_lines.append(f"Reason: {reason}") - - # Authorizer - auth_name = f"{latest.authorizer_first_name or ''} {latest.authorizer_last_name or ''}".strip() - if auth_name: - summary_lines.append(f"Authorizer: {auth_name}") - - # All devices received (unique) - devices = set() - for a in apps: - if a.base_device: - devices.add(a.base_device) - if len(devices) > 1: - summary_lines.append(f"All Devices: {', '.join(sorted(devices))}") - else: - summary_lines.append("No applications on file.") - - profile.ai_summary = '\n'.join(summary_lines) - - # --- RISK FLAGS --- - risk_lines = [] - - if app_count >= 2: - # Calculate frequency - dated_apps = [a for a in apps if a.application_date] - if len(dated_apps) >= 2: - dates = sorted([a.application_date for a in dated_apps]) - total_span = (dates[-1] - dates[0]).days - if total_span > 0: - avg_days = total_span / (len(dates) - 1) - if avg_days < 365: - risk_lines.append( - f"High Frequency: {app_count} applications over " - f"{total_span} days (avg {avg_days:.0f} days apart)" - ) - elif avg_days < 730: - risk_lines.append( - f"Moderate Frequency: {app_count} applications over " - f"{total_span // 365} year(s) (avg {avg_days:.0f} days apart)" - ) - else: - risk_lines.append( - f"Normal Frequency: {app_count} applications over " - f"{total_span // 365} year(s) (avg {avg_days:.0f} days apart)" - ) - - # Check for multiple replacements - replacements = [a for a in apps if a.reason_for_application and 'replacement' in a.reason_for_application.lower()] - if len(replacements) >= 2: - risk_lines.append(f"Multiple Replacements: {len(replacements)} replacement applications") - - if not risk_lines: - risk_lines.append("No flags identified.") - - profile.ai_risk_flags = '\n'.join(risk_lines) - - # ------------------------------------------------------------------ - # ACTIONS - # ------------------------------------------------------------------ - def action_view_claims(self): - """Open sale orders for this client.""" - self.ensure_one() - return { - 'type': 'ir.actions.act_window', - 'name': f'Claims - {self.display_name}', - 'res_model': 'sale.order', - 'view_mode': 'list,form', - 'domain': [('partner_id', '=', self.partner_id.id), ('x_fc_sale_type', '!=', False)], - } - - def action_view_applications(self): - """Open parsed ADP application data for this client.""" - self.ensure_one() - return { - 'type': 'ir.actions.act_window', - 'name': f'Applications - {self.display_name}', - 'res_model': 'fusion.adp.application.data', - 'view_mode': 'list,form', - 'domain': [('profile_id', '=', self.id)], - } - - def action_open_ai_chat(self): - """Open AI chat about this client using Odoo's native AI agent.""" - self.ensure_one() - agent = self.env.ref('fusion_claims.ai_agent_fusion_claims', raise_if_not_found=False) - if agent: - # Create channel with client context so the AI knows which client - channel = agent._create_ai_chat_channel() - # Post an initial context message about this client - initial_prompt = ( - f"I want to ask about client {self.display_name} " - f"(Profile ID: {self.id}, Health Card: {self.health_card_number or 'N/A'}). " - f"Please look up their details." - ) - return { - 'type': 'ir.actions.client', - 'tag': 'agent_chat_action', - 'params': { - 'channelId': channel.id, - 'user_prompt': initial_prompt, - }, - } - return {'type': 'ir.actions.act_window_close'} diff --git a/fusion_claims/fusion_claims/models/dashboard.py b/fusion_claims/fusion_claims/models/dashboard.py deleted file mode 100644 index fe02079..0000000 --- a/fusion_claims/fusion_claims/models/dashboard.py +++ /dev/null @@ -1,162 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) - -from odoo import api, fields, models - -CASE_TYPE_SELECTION = [ - ('adp', 'ADP'), - ('odsp', 'ODSP'), - ('march_of_dimes', 'March of Dimes'), - ('hardship', 'Hardship Funding'), - ('acsd', 'ACSD'), - ('muscular_dystrophy', 'Muscular Dystrophy'), - ('insurance', 'Insurance'), - ('wsib', 'WSIB'), -] - -TYPE_DOMAINS = { - 'adp': [('x_fc_sale_type', 'in', ['adp', 'adp_odsp'])], - 'odsp': [('x_fc_sale_type', 'in', ['odsp', 'adp_odsp'])], - 'march_of_dimes': [('x_fc_sale_type', '=', 'march_of_dimes')], - 'hardship': [('x_fc_sale_type', '=', 'hardship')], - 'acsd': [('x_fc_client_type', '=', 'ACS')], - 'muscular_dystrophy': [('x_fc_sale_type', '=', 'muscular_dystrophy')], - 'insurance': [('x_fc_sale_type', '=', 'insurance')], - 'wsib': [('x_fc_sale_type', '=', 'wsib')], -} - -TYPE_LABELS = dict(CASE_TYPE_SELECTION) - - -class FusionClaimsDashboard(models.TransientModel): - _name = 'fusion.claims.dashboard' - _description = 'Fusion Claims Dashboard' - _rec_name = 'name' - - name = fields.Char(default='Dashboard', readonly=True) - - # Case counts by funding type - adp_count = fields.Integer(compute='_compute_stats') - odsp_count = fields.Integer(compute='_compute_stats') - march_of_dimes_count = fields.Integer(compute='_compute_stats') - hardship_count = fields.Integer(compute='_compute_stats') - acsd_count = fields.Integer(compute='_compute_stats') - muscular_dystrophy_count = fields.Integer(compute='_compute_stats') - insurance_count = fields.Integer(compute='_compute_stats') - wsib_count = fields.Integer(compute='_compute_stats') - total_profiles = fields.Integer(compute='_compute_stats') - - # Panel selectors (4 panels) - panel1_type = fields.Selection(CASE_TYPE_SELECTION, string='Window 1', default='adp') - panel2_type = fields.Selection(CASE_TYPE_SELECTION, string='Window 2', default='odsp') - panel3_type = fields.Selection(CASE_TYPE_SELECTION, string='Window 3', default='march_of_dimes') - panel4_type = fields.Selection(CASE_TYPE_SELECTION, string='Window 4', default='hardship') - - # Panel HTML - panel1_html = fields.Html(compute='_compute_panels', sanitize=False) - panel2_html = fields.Html(compute='_compute_panels', sanitize=False) - panel3_html = fields.Html(compute='_compute_panels', sanitize=False) - panel4_html = fields.Html(compute='_compute_panels', sanitize=False) - panel1_title = fields.Char(compute='_compute_panels') - panel2_title = fields.Char(compute='_compute_panels') - panel3_title = fields.Char(compute='_compute_panels') - panel4_title = fields.Char(compute='_compute_panels') - - def _compute_stats(self): - SO = self.env['sale.order'].sudo() - Profile = self.env['fusion.client.profile'].sudo() - for rec in self: - rec.adp_count = SO.search_count(TYPE_DOMAINS['adp']) - rec.odsp_count = SO.search_count(TYPE_DOMAINS['odsp']) - rec.march_of_dimes_count = SO.search_count(TYPE_DOMAINS['march_of_dimes']) - rec.hardship_count = SO.search_count(TYPE_DOMAINS['hardship']) - rec.acsd_count = SO.search_count(TYPE_DOMAINS['acsd']) - rec.muscular_dystrophy_count = SO.search_count(TYPE_DOMAINS['muscular_dystrophy']) - rec.insurance_count = SO.search_count(TYPE_DOMAINS['insurance']) - rec.wsib_count = SO.search_count(TYPE_DOMAINS['wsib']) - rec.total_profiles = Profile.search_count([]) - - @api.depends('panel1_type', 'panel2_type', 'panel3_type', 'panel4_type') - def _compute_panels(self): - SO = self.env['sale.order'].sudo() - for rec in self: - for i in range(1, 5): - ptype = getattr(rec, f'panel{i}_type') or 'adp' - domain = TYPE_DOMAINS.get(ptype, []) - orders = SO.search(domain, order='create_date desc', limit=50) - count = SO.search_count(domain) - title = f'Window {i} - {TYPE_LABELS.get(ptype, ptype)} ({count} cases)' - html = rec._build_top_list(orders) - setattr(rec, f'panel{i}_title', title) - setattr(rec, f'panel{i}_html', html) - - def _build_top_list(self, orders): - if not orders: - return '

      No cases found

      ' - rows = [] - for o in orders: - status = o.x_fc_adp_application_status or '' - status_label = dict(o._fields['x_fc_adp_application_status'].selection).get(status, status) - rows.append( - f'' - f'{o.name}' - f'{o.partner_id.name or ""}' - f'{status_label}' - f'${o.amount_total:,.2f}' - f'' - ) - return ( - '' - '' - '' + ''.join(rows) + '
      OrderClientStatusTotal
      ' - ) - - def action_open_order(self, order_id): - """Open a specific sale order with breadcrumbs.""" - return { - 'type': 'ir.actions.act_window', - 'name': 'Sale Order', - 'res_model': 'sale.order', - 'view_mode': 'form', - 'res_id': order_id, - 'target': 'current', - } - - def action_open_adp(self): - return self._open_type_action('adp') - - def action_open_odsp(self): - return self._open_type_action('odsp') - - def action_open_march(self): - return self._open_type_action('march_of_dimes') - - def action_open_hardship(self): - return self._open_type_action('hardship') - - def action_open_acsd(self): - return self._open_type_action('acsd') - - def action_open_muscular(self): - return self._open_type_action('muscular_dystrophy') - - def action_open_insurance(self): - return self._open_type_action('insurance') - - def action_open_wsib(self): - return self._open_type_action('wsib') - - def action_open_profiles(self): - return { - 'type': 'ir.actions.act_window', 'name': 'Client Profiles', - 'res_model': 'fusion.client.profile', 'view_mode': 'list,form', - } - - def _open_type_action(self, type_key): - return { - 'type': 'ir.actions.act_window', - 'name': f'{TYPE_LABELS.get(type_key, type_key)} Cases', - 'res_model': 'sale.order', 'view_mode': 'list,form', - 'domain': TYPE_DOMAINS.get(type_key, []), - } diff --git a/fusion_claims/fusion_claims/models/email_builder_mixin.py b/fusion_claims/fusion_claims/models/email_builder_mixin.py deleted file mode 100644 index 9fa3023..0000000 --- a/fusion_claims/fusion_claims/models/email_builder_mixin.py +++ /dev/null @@ -1,242 +0,0 @@ -# -*- coding: utf-8 -*- -# Fusion Claims - Professional Email Builder Mixin -# Provides consistent, dark/light mode safe email templates across all modules. - -from odoo import models - - -class FusionEmailBuilderMixin(models.AbstractModel): - _name = 'fusion.email.builder.mixin' - _description = 'Fusion Email Builder Mixin' - - # ------------------------------------------------------------------ - # Color constants - # ------------------------------------------------------------------ - _EMAIL_COLORS = { - 'info': '#2B6CB0', - 'success': '#38a169', - 'attention': '#d69e2e', - 'urgent': '#c53030', - } - - # ------------------------------------------------------------------ - # Public API - # ------------------------------------------------------------------ - - def _email_build( - self, - title, - summary, - sections=None, - note=None, - note_color=None, - email_type='info', - attachments_note=None, - button_url=None, - button_text='View Case Details', - sender_name=None, - extra_html='', - ): - """Build a complete professional email HTML string. - - Args: - title: Email heading (e.g. "Application Approved") - summary: One-sentence summary HTML (may contain tags) - sections: list of (heading, rows) where rows is list of (label, value) - e.g. [('Case Details', [('Client', 'John'), ('Case', 'S30073')])] - note: Optional note/next-steps text (plain or HTML) - note_color: Override left-border color for note (default uses email_type) - email_type: 'info' | 'success' | 'attention' | 'urgent' - attachments_note: Optional string listing attached files - button_url: Optional CTA button URL - button_text: CTA button label - sender_name: Name for sign-off (defaults to current user) - extra_html: Any additional HTML to insert before sign-off - """ - accent = self._EMAIL_COLORS.get(email_type, self._EMAIL_COLORS['info']) - company = self._get_company_info() - - parts = [] - # -- Wrapper open + accent bar - parts.append( - f'
      ' - f'
      ' - f'
      ' - ) - - # -- Company name - parts.append( - f'

      {company["name"]}

      ' - ) - - # -- Title - parts.append( - f'

      {title}

      ' - ) - - # -- Summary - parts.append( - f'

      {summary}

      ' - ) - - # -- Sections (details tables) - if sections: - for heading, rows in sections: - parts.append(self._email_section(heading, rows)) - - # -- Note / Next Steps - if note: - nc = note_color or accent - parts.append(self._email_note(note, nc)) - - # -- Extra HTML - if extra_html: - parts.append(extra_html) - - # -- Attachment note - if attachments_note: - parts.append(self._email_attachment_note(attachments_note)) - - # -- CTA Button - if button_url: - parts.append(self._email_button(button_url, button_text, accent)) - - # -- Sign-off - signer = sender_name or (self.env.user.name if self.env.user else '') - parts.append( - f'

      ' - f'Best regards,
      ' - f'{signer}
      ' - f'{company["name"]}

      ' - ) - - # -- Close content card - parts.append('
      ') - - # -- Footer - footer_parts = [company['name']] - if company['phone']: - footer_parts.append(company['phone']) - if company['email']: - footer_parts.append(company['email']) - footer_text = ' · '.join(footer_parts) - - parts.append( - f'
      ' - f'

      ' - f'{footer_text}
      ' - f'This is an automated notification from the ADP Claims Management System.

      ' - f'
      ' - ) - - # -- Close wrapper - parts.append('
      ') - - return ''.join(parts) - - # ------------------------------------------------------------------ - # Building blocks - # ------------------------------------------------------------------ - - def _email_section(self, heading, rows): - """Build a labeled details table section. - - Args: - heading: Section title (e.g. "Case Details") - rows: list of (label, value) tuples. Value can be plain text or HTML. - """ - if not rows: - return '' - - html = ( - '' - f'' - ) - - for label, value in rows: - if value is None or value == '' or value is False: - continue - html += ( - f'' - f'' - f'' - f'' - ) - - html += '
      {heading}
      {label}{value}
      ' - return html - - def _email_note(self, text, color='#2B6CB0'): - """Build a left-border accent note block.""" - return ( - f'
      ' - f'

      {text}

      ' - f'
      ' - ) - - def _email_button(self, url, text='View Case Details', color='#2B6CB0'): - """Build a centered CTA button.""" - return ( - f'

      ' - f'{text}

      ' - ) - - def _email_attachment_note(self, description): - """Build a dashed-border attachment callout. - - Args: - description: e.g. "ADP Application (PDF), XML Data File" - """ - return ( - f'
      ' - f'

      ' - f'Attached: {description}

      ' - f'
      ' - ) - - def _email_status_badge(self, label, color='#2B6CB0'): - """Return an inline status badge/pill HTML snippet.""" - # Pick a light background tint for the badge - bg_map = { - '#38a169': '#f0fff4', - '#2B6CB0': '#ebf4ff', - '#d69e2e': '#fefcbf', - '#c53030': '#fff5f5', - } - bg = bg_map.get(color, '#ebf4ff') - return ( - f'' - f'{label}' - ) - - # ------------------------------------------------------------------ - # Helpers - # ------------------------------------------------------------------ - - def _get_company_info(self): - """Return company name, phone, email for email templates.""" - company = getattr(self, 'company_id', None) or self.env.company - return { - 'name': company.name or 'Our Company', - 'phone': company.phone or '', - 'email': company.email or '', - } - - def _email_is_enabled(self): - """Check if email notifications are enabled in settings.""" - ICP = self.env['ir.config_parameter'].sudo() - val = ICP.get_param('fusion_claims.enable_email_notifications', 'True') - return val.lower() in ('true', '1', 'yes') diff --git a/fusion_claims/fusion_claims/models/fusion_adp_device_code.py b/fusion_claims/fusion_claims/models/fusion_adp_device_code.py deleted file mode 100644 index 0a6c201..0000000 --- a/fusion_claims/fusion_claims/models/fusion_adp_device_code.py +++ /dev/null @@ -1,390 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2025 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) -# Part of the Fusion Claim Assistant product family. - -from odoo import models, fields, api, _ -from odoo.exceptions import UserError -from odoo.tools.misc import file_path as get_resource_path -import json -import re -import os -import logging - -_logger = logging.getLogger(__name__) - - -class FusionADPDeviceCode(models.Model): - _name = 'fusion.adp.device.code' - _description = 'ADP Device Code Reference (Mobility Manual)' - _order = 'device_type, device_code' - - def _register_hook(self): - """ - Called when the model is loaded. - Re-loads device codes from packaged JSON on module upgrade. - """ - super()._register_hook() - # Use with_context to check if this is a module upgrade - # The data will be loaded via post_init_hook on install, - # and via this hook on upgrade (when module is reloaded) - try: - self.sudo()._load_packaged_device_codes() - except Exception as e: - _logger.warning("Could not auto-load device codes: %s", str(e)) - - # ========================================================================== - # MAIN FIELDS - # ========================================================================== - device_code = fields.Char( - string='Device Code', - required=True, - index=True, - help='ADP device code from the mobility manual', - ) - name = fields.Char( - string='Description', - compute='_compute_name', - store=True, - ) - device_type = fields.Char( - string='Device Type', - index=True, - help='Device type/category (e.g., Adult Wheeled Walker Type 1)', - ) - manufacturer = fields.Char( - string='Manufacturer', - index=True, - help='Device manufacturer', - ) - device_description = fields.Char( - string='Device Description', - help='Detailed device description from mobility manual', - ) - max_quantity = fields.Integer( - string='Max Quantity', - default=1, - help='Maximum quantity that can be billed per claim', - ) - adp_price = fields.Float( - string='ADP Price', - digits='Product Price', - help='Maximum price ADP will cover for this device', - ) - sn_required = fields.Boolean( - string='Serial Number Required', - default=False, - help='Is serial number required for this device?', - ) - - # ========================================================================== - # TRACKING - # ========================================================================== - active = fields.Boolean( - string='Active', - default=True, - ) - last_updated = fields.Datetime( - string='Last Updated', - default=fields.Datetime.now, - ) - - # ========================================================================== - # SQL CONSTRAINTS - # ========================================================================== - _sql_constraints = [ - ('device_code_uniq', 'unique(device_code)', - 'Device code must be unique!'), - ] - - # ========================================================================== - # COMPUTED FIELDS - # ========================================================================== - @api.depends('device_code', 'adp_price', 'device_type', 'device_description') - def _compute_name(self): - for record in self: - if record.device_code: - if record.device_description: - record.name = f"{record.device_code} - {record.device_description} (${record.adp_price:.2f})" - else: - record.name = f"{record.device_code} (${record.adp_price:.2f})" - else: - record.name = '' - - # ========================================================================== - # DEVICE TYPE LOOKUP (for wizard display) - # ========================================================================== - @api.model - def get_device_type_for_code(self, device_code): - """Get the device type for a given device code.""" - if not device_code: - return '' - device = self.search([('device_code', '=', device_code), ('active', '=', True)], limit=1) - return device.device_type or '' - - @api.model - def get_unique_device_types(self): - """Get list of unique device types from the database.""" - self.flush_model() - self.env.cr.execute(""" - SELECT DISTINCT device_type - FROM fusion_adp_device_code - WHERE device_type IS NOT NULL AND device_type != '' AND active = TRUE - ORDER BY device_type - """) - return [row[0] for row in self.env.cr.fetchall()] - - # ========================================================================== - # LOOKUP METHODS - # ========================================================================== - @api.model - def get_device_info(self, device_code): - """Get device info by code.""" - if not device_code: - return None - - device = self.search([('device_code', '=', device_code), ('active', '=', True)], limit=1) - if device: - return { - 'device_code': device.device_code, - 'max_quantity': device.max_quantity, - 'adp_price': device.adp_price, - 'sn_required': device.sn_required, - } - return None - - @api.model - def validate_device_code(self, device_code): - """Check if a device code exists in the mobility manual.""" - if not device_code: - return False - return bool(self.search([('device_code', '=', device_code), ('active', '=', True)], limit=1)) - - # ========================================================================== - # TEXT CLEANING UTILITIES - # ========================================================================== - @staticmethod - def _clean_text(text): - """Clean text from weird characters, normalize encoding.""" - if not text: - return '' - # Convert to string if not already - text = str(text) - # Remove or replace problematic characters - # Replace curly quotes with straight quotes - text = text.replace('"', '"').replace('"', '"') - text = text.replace(''', "'").replace(''', "'") - # Remove non-printable characters except newlines - text = ''.join(char if char.isprintable() or char in '\n\r\t' else ' ' for char in text) - # Normalize multiple spaces - text = re.sub(r'\s+', ' ', text) - # Strip leading/trailing whitespace - return text.strip() - - @staticmethod - def _parse_price(price_str): - """Parse price string like '$64.00' or '$2,578.00' to float.""" - if not price_str: - return 0.0 - # Remove currency symbols, commas, spaces, quotes - price_str = str(price_str).strip() - price_str = re.sub(r'[\$,"\'\s]', '', price_str) - try: - return float(price_str) - except ValueError: - return 0.0 - - # ========================================================================== - # IMPORT FROM JSON - # ========================================================================== - @api.model - def import_from_json(self, json_data): - """ - Import device codes from JSON data. - - Expected format (enhanced with device type, manufacturer, description): - [ - { - "Device Type": "Adult Wheeled Walker Type 1", - "Manufacturer": "Drive Medical", - "Device Description": "One Button Or Dual Trigger Release", - "Device Code": "MW1D50005", - "Quantity": 1, - "ADP Price": 64.00, - "SN Required": "Yes" - }, - ... - ] - """ - if isinstance(json_data, str): - try: - data = json.loads(json_data) - except json.JSONDecodeError as e: - raise UserError(_("Invalid JSON data: %s") % str(e)) - else: - data = json_data - - if not isinstance(data, list): - raise UserError(_("Expected a list of device codes")) - - created = 0 - updated = 0 - errors = [] - - for idx, item in enumerate(data): - try: - device_code = self._clean_text(item.get('Device Code', '') or item.get('device_code', '')) - if not device_code: - errors.append(f"Row {idx + 1}: Missing device code") - continue - - # Parse fields with cleaning - device_type = self._clean_text(item.get('Device Type', '') or item.get('device_type', '')) - manufacturer = self._clean_text(item.get('Manufacturer', '') or item.get('manufacturer', '')) - device_description = self._clean_text(item.get('Device Description', '') or item.get('device_description', '')) - - # Parse quantity - qty_val = item.get('Quantity', 1) or item.get('Qty', 1) or item.get('quantity', 1) - max_qty = int(qty_val) if qty_val else 1 - - # Parse price (handles both raw number and string format) - price_val = item.get('ADP Price', 0) or item.get('Approved Price', 0) or item.get('adp_price', 0) - if isinstance(price_val, (int, float)): - adp_price = float(price_val) - else: - adp_price = self._parse_price(price_val) - - # Parse serial requirement - handle boolean, string, and various formats - sn_raw = item.get('SN Required') or item.get('Serial') or item.get('SN') or item.get('sn_required') or 'No' - - # Handle boolean values directly - if isinstance(sn_raw, bool): - sn_required = sn_raw - else: - sn_val = str(sn_raw).upper().strip() - sn_required = sn_val in ('YES', 'Y', 'TRUE', '1', 'T') - - # Check if exists - existing = self.search([('device_code', '=', device_code)], limit=1) - - vals = { - 'device_type': device_type, - 'manufacturer': manufacturer, - 'device_description': device_description, - 'max_quantity': max_qty, - 'adp_price': adp_price, - 'sn_required': sn_required, - 'last_updated': fields.Datetime.now(), - 'active': True, - } - - if existing: - existing.write(vals) - updated += 1 - else: - vals['device_code'] = device_code - self.create(vals) - created += 1 - - except Exception as e: - errors.append(f"Row {idx + 1}: {str(e)}") - - return { - 'created': created, - 'updated': updated, - 'errors': errors, - } - - @api.model - def import_from_csv_file(self, file_path): - """Import device codes from a CSV file (ADP Mobility Manual format). - - Expected CSV columns: Device Type, Manufacturer, Device Description, Device Code, Qty, Approved Price, Serial - """ - import csv - - try: - data = [] - with open(file_path, 'r', encoding='utf-8-sig') as f: - reader = csv.DictReader(f) - for row in reader: - # Skip empty rows - device_code = (row.get('Device Code', '') or '').strip() - if not device_code: - continue - - data.append({ - 'Device Type': row.get('Device Type', ''), - 'Manufacturer': row.get('Manufacturer', ''), - 'Device Description': row.get('Device Description', ''), - 'Device Code': device_code, - 'Quantity': row.get('Qty', 1), - 'ADP Price': row.get(' Approved Price ', '') or row.get('Approved Price', ''), - 'SN Required': row.get('Serial', 'No'), - }) - - return self.import_from_json(data) - except FileNotFoundError: - raise UserError(_("File not found: %s") % file_path) - except Exception as e: - raise UserError(_("Error reading CSV file: %s") % str(e)) - - @api.model - def import_from_file(self, file_path): - """Import device codes from a JSON file.""" - try: - with open(file_path, 'r', encoding='utf-8') as f: - data = json.load(f) - return self.import_from_json(data) - except FileNotFoundError: - raise UserError(_("File not found: %s") % file_path) - except json.JSONDecodeError as e: - raise UserError(_("Invalid JSON file: %s") % str(e)) - except Exception as e: - raise UserError(_("Error reading file: %s") % str(e)) - - # ========================================================================== - # AUTO-LOAD FROM PACKAGED DATA FILE - # ========================================================================== - @api.model - def _load_packaged_device_codes(self): - """ - Load device codes from the packaged JSON file. - Called automatically on module install/upgrade via post_init_hook. - - The JSON file is located at: fusion_claims/data/device_codes/adp_mobility_manual.json - """ - _logger.info("Loading ADP Mobility Manual device codes from packaged data file...") - - # Get the path to the packaged JSON file - try: - json_path = get_resource_path('fusion_claims/data/device_codes/adp_mobility_manual.json') - except FileNotFoundError: - json_path = None - - if not json_path or not os.path.exists(json_path): - _logger.warning("ADP Mobility Manual JSON file not found at expected location.") - return {'created': 0, 'updated': 0, 'errors': ['JSON file not found']} - - try: - with open(json_path, 'r', encoding='utf-8') as f: - data = json.load(f) - - result = self.import_from_json(data) - - _logger.info( - "ADP Mobility Manual import complete: %d created, %d updated, %d errors", - result.get('created', 0), - result.get('updated', 0), - len(result.get('errors', [])) - ) - - if result.get('errors'): - for error in result['errors'][:10]: # Log first 10 errors - _logger.warning("Import error: %s", error) - - return result - - except Exception as e: - _logger.error("Error loading ADP Mobility Manual: %s", str(e)) - return {'created': 0, 'updated': 0, 'errors': [str(e)]} diff --git a/fusion_claims/fusion_claims/models/fusion_central_config.py b/fusion_claims/fusion_claims/models/fusion_central_config.py deleted file mode 100644 index 7d5710d..0000000 --- a/fusion_claims/fusion_claims/models/fusion_central_config.py +++ /dev/null @@ -1,126 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2025 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) -# Part of the Fusion Claim Assistant product family. - -import logging -from odoo import models, api, _ - -_logger = logging.getLogger(__name__) - - -class FusionCentralConfig(models.TransientModel): - _name = 'fusion_claims.config' - _description = 'Fusion Central Configuration Manager' - - # ========================================================================= - # ACTION METHODS - # ========================================================================= - - def action_detect_existing_fields(self): - """Detect existing custom x_* fields and map them.""" - ICP = self.env['ir.config_parameter'].sudo() - IrModelFields = self.env['ir.model.fields'].sudo() - detected = [] - detected_details = [] - - # Search for all custom fields on relevant models - models_to_search = ['sale.order', 'sale.order.line', 'account.move', 'account.move.line', 'product.template'] - - # Find all custom x_* fields - all_custom_fields = IrModelFields.search([ - ('model', 'in', models_to_search), - ('name', '=like', 'x_%'), - ('state', '=', 'manual'), - ]) - - _logger.debug("Found %d custom fields across models", len(all_custom_fields)) - - # Field patterns to detect (model, keywords, param_key, display_name) - # Keywords are checked if they appear anywhere in the field name - # NOTE: param_key must match the config_parameter in res_config_settings.py - field_mappings = [ - # Sale Order header fields - ('sale.order', ['sale_type', 'saletype', 'type_of_sale'], 'fusion_claims.field_sale_type', 'Sale Type'), - ('sale.order', ['client_type', 'clienttype', 'customer_type'], 'fusion_claims.field_so_client_type', 'SO Client Type'), - ('sale.order', ['authorizer', 'authorized', 'approver'], 'fusion_claims.field_so_authorizer', 'SO Authorizer'), - ('sale.order', ['claim_number', 'claimnumber', 'claim_no', 'claim_num'], 'fusion_claims.field_so_claim_number', 'SO Claim Number'), - ('sale.order', ['client_ref_1', 'clientref1', 'reference_1'], 'fusion_claims.field_so_client_ref_1', 'SO Client Ref 1'), - ('sale.order', ['client_ref_2', 'clientref2', 'reference_2'], 'fusion_claims.field_so_client_ref_2', 'SO Client Ref 2'), - ('sale.order', ['delivery_date', 'deliverydate', 'adp_delivery'], 'fusion_claims.field_so_delivery_date', 'SO Delivery Date'), - ('sale.order', ['service_start', 'servicestart'], 'fusion_claims.field_so_service_start', 'SO Service Start'), - ('sale.order', ['service_end', 'serviceend'], 'fusion_claims.field_so_service_end', 'SO Service End'), - ('sale.order', ['adp_status', 'adpstatus'], 'fusion_claims.field_so_adp_status', 'SO ADP Status'), - # Sale Order line fields - ('sale.order.line', ['serial', 'sn', 's_n'], 'fusion_claims.field_sol_serial', 'SO Line Serial'), - ('sale.order.line', ['placement', 'device_placement'], 'fusion_claims.field_sol_placement', 'SO Line Placement'), - # Invoice header fields - ('account.move', ['invoice_type', 'invoicetype', 'inv_type', 'type_of_invoice'], 'fusion_claims.field_invoice_type', 'Invoice Type'), - ('account.move', ['client_type', 'clienttype', 'customer_type'], 'fusion_claims.field_inv_client_type', 'Invoice Client Type'), - ('account.move', ['authorizer', 'authorized', 'approver'], 'fusion_claims.field_inv_authorizer', 'Invoice Authorizer'), - ('account.move', ['claim_number', 'claimnumber', 'claim_no'], 'fusion_claims.field_inv_claim_number', 'Invoice Claim Number'), - ('account.move', ['client_ref_1', 'clientref1', 'reference_1'], 'fusion_claims.field_inv_client_ref_1', 'Invoice Client Ref 1'), - ('account.move', ['client_ref_2', 'clientref2', 'reference_2'], 'fusion_claims.field_inv_client_ref_2', 'Invoice Client Ref 2'), - ('account.move', ['delivery_date', 'deliverydate', 'adp_delivery'], 'fusion_claims.field_inv_delivery_date', 'Invoice Delivery Date'), - ('account.move', ['service_start', 'servicestart'], 'fusion_claims.field_inv_service_start', 'Invoice Service Start'), - ('account.move', ['service_end', 'serviceend'], 'fusion_claims.field_inv_service_end', 'Invoice Service End'), - # Invoice line fields - ('account.move.line', ['serial', 'sn', 's_n'], 'fusion_claims.field_aml_serial', 'Invoice Line Serial'), - ('account.move.line', ['placement', 'device_placement'], 'fusion_claims.field_aml_placement', 'Invoice Line Placement'), - # Product fields - ('product.template', ['adp_device', 'adp_code', 'adp_sku', 'device_code', 'sku'], 'fusion_claims.field_product_code', 'Product ADP Code'), - ] - - for model, keywords, param_key, display_name in field_mappings: - # Find fields on this model that contain any of the keywords - model_fields = all_custom_fields.filtered(lambda f: f.model == model) - - model_fields_sorted = sorted(model_fields, key=lambda f: f.name) - - matched_field = None - for field in model_fields_sorted: - field_name_lower = field.name.lower() - for keyword in keywords: - if keyword in field_name_lower: - # Skip our own x_fc_* fields - we want to find other custom fields - if field.name.startswith('x_fc_'): - continue - matched_field = field - break - if matched_field: - break - - if matched_field: - ICP.set_param(param_key, matched_field.name) - detected.append(matched_field.name) - detected_details.append(f"• {display_name}: {matched_field.name} ({model})") - _logger.debug("Mapped %s -> %s on %s", param_key, matched_field.name, model) - - # Also list any unmapped custom fields for reference - unmapped = [] - for field in all_custom_fields: - if field.name not in detected: - unmapped.append(f"{field.model}.{field.name}") - - if detected_details: - message = _("Detected and mapped %d fields:\n%s") % (len(detected), "\n".join(detected_details)) - if unmapped: - message += _("\n\nOther custom fields found (not mapped):\n• ") + "\n• ".join(unmapped[:10]) - if len(unmapped) > 10: - message += f"\n... and {len(unmapped) - 10} more" - message += _("\n\n⚠️ IMPORTANT: Save settings and reload page to see changes.") - else: - message = _("No matching fields found.\n\nCustom fields found:\n• ") + "\n• ".join(unmapped[:15]) if unmapped else _("No custom fields found on relevant models.") - - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': _("Field Detection Complete"), - 'message': message, - 'type': 'success' if detected else 'warning', - 'sticky': True, - } - } - - # (Migration and field protection methods removed) diff --git a/fusion_claims/fusion_claims/models/fusion_loaner_checkout.py b/fusion_claims/fusion_claims/models/fusion_loaner_checkout.py deleted file mode 100644 index cfd54ad..0000000 --- a/fusion_claims/fusion_claims/models/fusion_loaner_checkout.py +++ /dev/null @@ -1,799 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) - -from odoo import models, fields, api, _ -from odoo.exceptions import UserError, ValidationError -from markupsafe import Markup -from datetime import timedelta -import logging - -_logger = logging.getLogger(__name__) - - -class FusionLoanerCheckout(models.Model): - """Track loaner equipment checkouts and returns.""" - _name = 'fusion.loaner.checkout' - _description = 'Loaner Equipment Checkout' - _order = 'checkout_date desc, id desc' - _inherit = ['mail.thread', 'mail.activity.mixin', 'fusion.email.builder.mixin'] - - # ========================================================================= - # REFERENCE FIELDS - # ========================================================================= - - name = fields.Char( - string='Reference', - required=True, - copy=False, - readonly=True, - default=lambda self: _('New'), - ) - sale_order_id = fields.Many2one( - 'sale.order', - string='Sale Order', - ondelete='set null', - tracking=True, - ) - partner_id = fields.Many2one( - 'res.partner', - string='Client', - required=True, - tracking=True, - ) - authorizer_id = fields.Many2one( - 'res.partner', - string='Authorizer', - help='Therapist/Authorizer associated with this loaner', - ) - sales_rep_id = fields.Many2one( - 'res.users', - string='Sales Rep', - default=lambda self: self.env.user, - tracking=True, - ) - company_id = fields.Many2one( - 'res.company', - string='Company', - default=lambda self: self.env.company, - ) - - # ========================================================================= - # PRODUCT & SERIAL - # ========================================================================= - - product_id = fields.Many2one( - 'product.product', - string='Product', - required=True, - domain="[('x_fc_can_be_loaned', '=', True)]", - tracking=True, - ) - lot_id = fields.Many2one( - 'stock.lot', - string='Serial Number', - domain="[('product_id', '=', product_id)]", - tracking=True, - ) - product_description = fields.Text( - string='Product Description', - related='product_id.description_sale', - ) - - # ========================================================================= - # DATES - # ========================================================================= - - checkout_date = fields.Date( - string='Checkout Date', - required=True, - default=fields.Date.context_today, - tracking=True, - ) - loaner_period_days = fields.Integer( - string='Loaner Period (Days)', - default=7, - help='Number of free loaner days before rental conversion', - ) - expected_return_date = fields.Date( - string='Expected Return Date', - compute='_compute_expected_return_date', - store=True, - ) - actual_return_date = fields.Date( - string='Actual Return Date', - tracking=True, - ) - days_out = fields.Integer( - string='Days Out', - compute='_compute_days_out', - ) - days_overdue = fields.Integer( - string='Days Overdue', - compute='_compute_days_overdue', - ) - - # ========================================================================= - # STATUS - # ========================================================================= - - state = fields.Selection([ - ('draft', 'Draft'), - ('checked_out', 'Checked Out'), - ('overdue', 'Overdue'), - ('rental_pending', 'Rental Conversion Pending'), - ('returned', 'Returned'), - ('converted_rental', 'Converted to Rental'), - ('lost', 'Lost/Write-off'), - ], string='Status', default='draft', tracking=True, required=True) - - # ========================================================================= - # LOCATION - # ========================================================================= - - delivery_address = fields.Text( - string='Delivery Address', - help='Where the loaner was delivered', - ) - return_location_id = fields.Many2one( - 'stock.location', - string='Return Location', - domain="[('usage', '=', 'internal')]", - help='Where the loaner was returned to (store, warehouse, etc.)', - tracking=True, - ) - checked_out_by_id = fields.Many2one( - 'res.users', - string='Checked Out By', - default=lambda self: self.env.user, - ) - returned_to_id = fields.Many2one( - 'res.users', - string='Returned To', - ) - - # ========================================================================= - # CHECKOUT CONDITION - # ========================================================================= - - checkout_condition = fields.Selection([ - ('excellent', 'Excellent'), - ('good', 'Good'), - ('fair', 'Fair'), - ('needs_repair', 'Needs Repair'), - ], string='Checkout Condition', default='excellent') - checkout_notes = fields.Text( - string='Checkout Notes', - ) - checkout_photo_ids = fields.Many2many( - 'ir.attachment', - 'fusion_loaner_checkout_photo_rel', - 'checkout_id', - 'attachment_id', - string='Checkout Photos', - ) - - # ========================================================================= - # RETURN CONDITION - # ========================================================================= - - return_condition = fields.Selection([ - ('excellent', 'Excellent'), - ('good', 'Good'), - ('fair', 'Fair'), - ('needs_repair', 'Needs Repair'), - ('damaged', 'Damaged'), - ], string='Return Condition') - return_notes = fields.Text( - string='Return Notes', - ) - return_photo_ids = fields.Many2many( - 'ir.attachment', - 'fusion_loaner_return_photo_rel', - 'checkout_id', - 'attachment_id', - string='Return Photos', - ) - - # ========================================================================= - # REMINDER TRACKING - # ========================================================================= - - reminder_day5_sent = fields.Boolean( - string='Day 5 Reminder Sent', - default=False, - ) - reminder_day8_sent = fields.Boolean( - string='Day 8 Warning Sent', - default=False, - ) - reminder_day10_sent = fields.Boolean( - string='Day 10 Final Notice Sent', - default=False, - ) - - # ========================================================================= - # RENTAL CONVERSION - # ========================================================================= - - rental_order_id = fields.Many2one( - 'sale.order', - string='Rental Order', - help='Sale order created when loaner converted to rental', - ) - rental_conversion_date = fields.Date( - string='Rental Conversion Date', - ) - - # ========================================================================= - # STOCK MOVES - # ========================================================================= - - checkout_move_id = fields.Many2one( - 'stock.move', - string='Checkout Stock Move', - ) - return_move_id = fields.Many2one( - 'stock.move', - string='Return Stock Move', - ) - - # ========================================================================= - # HISTORY - # ========================================================================= - - history_ids = fields.One2many( - 'fusion.loaner.history', - 'checkout_id', - string='History', - ) - history_count = fields.Integer( - compute='_compute_history_count', - string='History Count', - ) - - # ========================================================================= - # COMPUTED FIELDS - # ========================================================================= - - @api.depends('checkout_date', 'loaner_period_days') - def _compute_expected_return_date(self): - for record in self: - if record.checkout_date and record.loaner_period_days: - record.expected_return_date = record.checkout_date + timedelta(days=record.loaner_period_days) - else: - record.expected_return_date = False - - @api.depends('checkout_date', 'actual_return_date') - def _compute_days_out(self): - today = fields.Date.today() - for record in self: - if record.checkout_date: - end_date = record.actual_return_date or today - record.days_out = (end_date - record.checkout_date).days - else: - record.days_out = 0 - - @api.depends('expected_return_date', 'actual_return_date', 'state') - def _compute_days_overdue(self): - today = fields.Date.today() - for record in self: - if record.state in ('returned', 'converted_rental', 'lost'): - record.days_overdue = 0 - elif record.expected_return_date: - end_date = record.actual_return_date or today - overdue = (end_date - record.expected_return_date).days - record.days_overdue = max(0, overdue) - else: - record.days_overdue = 0 - - def _compute_history_count(self): - for record in self: - record.history_count = len(record.history_ids) - - # ========================================================================= - # ONCHANGE - # ========================================================================= - - @api.onchange('product_id') - def _onchange_product_id(self): - if self.product_id: - self.loaner_period_days = self.product_id.x_fc_loaner_period_days or 7 - self.lot_id = False - - @api.onchange('sale_order_id') - def _onchange_sale_order_id(self): - if self.sale_order_id: - self.partner_id = self.sale_order_id.partner_id - self.authorizer_id = self.sale_order_id.x_fc_authorizer_id - self.sales_rep_id = self.sale_order_id.user_id - self.delivery_address = self.sale_order_id.partner_shipping_id.contact_address if self.sale_order_id.partner_shipping_id else '' - - # ========================================================================= - # CRUD - # ========================================================================= - - @api.model_create_multi - def create(self, vals_list): - for vals in vals_list: - if vals.get('name', _('New')) == _('New'): - vals['name'] = self.env['ir.sequence'].next_by_code('fusion.loaner.checkout') or _('New') - records = super().create(vals_list) - for record in records: - record._log_history('create', 'Loaner checkout created') - return records - - # ========================================================================= - # ACTIONS - # ========================================================================= - - def action_checkout(self): - """Confirm the loaner checkout.""" - self.ensure_one() - if self.state != 'draft': - raise UserError(_("Can only checkout from draft state.")) - - if not self.product_id: - raise UserError(_("Please select a product.")) - - self.write({'state': 'checked_out'}) - self._log_history('checkout', f'Loaner checked out to {self.partner_id.name}') - # Stock move is non-blocking -- use savepoint so failure doesn't roll back checkout - try: - with self.env.cr.savepoint(): - self._create_checkout_stock_move() - except Exception as e: - _logger.warning(f"Stock move failed for checkout {self.name} (non-blocking): {e}") - self._send_checkout_email() - - # Post to chatter - self.message_post( - body=Markup( - '
      ' - f'Loaner Checked Out
      ' - f'Product: {self.product_id.name}
      ' - f'Serial: {self.lot_id.name if self.lot_id else "N/A"}
      ' - f'Expected Return: {self.expected_return_date}' - '
      ' - ), - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - - return True - - def action_return(self): - """Open return wizard.""" - self.ensure_one() - return { - 'name': _('Return Loaner'), - 'type': 'ir.actions.act_window', - 'res_model': 'fusion.loaner.return.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': { - 'default_checkout_id': self.id, - }, - } - - def action_process_return(self, return_condition, return_notes=None, return_photos=None, return_location_id=None): - """Process the loaner return.""" - self.ensure_one() - if self.state not in ('checked_out', 'overdue', 'rental_pending'): - raise UserError(_("Cannot return a loaner that is not checked out.")) - - vals = { - 'state': 'returned', - 'actual_return_date': fields.Date.today(), - 'return_condition': return_condition, - 'return_notes': return_notes, - 'returned_to_id': self.env.user.id, - } - if return_location_id: - vals['return_location_id'] = return_location_id - if return_photos: - vals['return_photo_ids'] = [(6, 0, return_photos)] - - self.write(vals) - self._log_history('return', f'Loaner returned in {return_condition} condition') - try: - with self.env.cr.savepoint(): - self._create_return_stock_move() - except Exception as e: - _logger.warning(f"Stock move failed for return {self.name} (non-blocking): {e}") - self._send_return_email() - - # Post to chatter - self.message_post( - body=Markup( - '
      ' - f'Loaner Returned
      ' - f'Condition: {return_condition}
      ' - f'Days Out: {self.days_out}' - '
      ' - ), - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - - return True - - def action_mark_lost(self): - """Mark loaner as lost.""" - self.ensure_one() - self.write({'state': 'lost'}) - self._log_history('lost', 'Loaner marked as lost/write-off') - - self.message_post( - body=Markup( - '
      ' - 'Loaner Marked as Lost
      ' - f'Product: {self.product_id.name}
      ' - f'Serial: {self.lot_id.name if self.lot_id else "N/A"}' - '
      ' - ), - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - - def action_convert_to_rental(self): - """Flag for rental conversion.""" - self.ensure_one() - self.write({ - 'state': 'rental_pending', - 'rental_conversion_date': fields.Date.today(), - }) - self._log_history('rental_pending', 'Loaner flagged for rental conversion') - self._send_rental_conversion_email() - - def action_view_history(self): - """View loaner history.""" - self.ensure_one() - return { - 'name': _('Loaner History'), - 'type': 'ir.actions.act_window', - 'res_model': 'fusion.loaner.history', - 'view_mode': 'tree,form', - 'domain': [('checkout_id', '=', self.id)], - 'context': {'default_checkout_id': self.id}, - } - - # ========================================================================= - # STOCK MOVES - # ========================================================================= - - def _get_loaner_location(self): - """Get the loaner stock location.""" - location = self.env.ref('fusion_claims.stock_location_loaner', raise_if_not_found=False) - if not location: - # Fallback to main stock - location = self.env.ref('stock.stock_location_stock') - return location - - def _get_customer_location(self): - """Get customer location for stock moves.""" - return self.env.ref('stock.stock_location_customers') - - def _create_checkout_stock_move(self): - """Create stock move for checkout. Non-blocking -- checkout proceeds even if move fails.""" - if not self.lot_id: - return # No serial tracking - - try: - source_location = self._get_loaner_location() - dest_location = self._get_customer_location() - - move_vals = { - 'name': f'Loaner Checkout: {self.name}', - 'product_id': self.product_id.id, - 'product_uom_qty': 1, - 'product_uom': self.product_id.uom_id.id, - 'location_id': source_location.id, - 'location_dest_id': dest_location.id, - 'origin': self.name, - 'company_id': self.company_id.id, - 'procure_method': 'make_to_stock', - } - move = self.env['stock.move'].sudo().create(move_vals) - move._action_confirm() - move._action_assign() - - # Set the lot on move line - if move.move_line_ids: - move.move_line_ids.write({'lot_id': self.lot_id.id}) - - move._action_done() - self.checkout_move_id = move.id - except Exception as e: - _logger.warning(f"Could not create checkout stock move (non-blocking): {e}") - - def _create_return_stock_move(self): - """Create stock move for return. Uses return_location_id if set, otherwise Loaner Stock.""" - if not self.lot_id: - return - - try: - source_location = self._get_customer_location() - dest_location = self.return_location_id or self._get_loaner_location() - - move_vals = { - 'name': f'Loaner Return: {self.name}', - 'product_id': self.product_id.id, - 'product_uom_qty': 1, - 'product_uom': self.product_id.uom_id.id, - 'location_id': source_location.id, - 'location_dest_id': dest_location.id, - 'origin': self.name, - 'company_id': self.company_id.id, - 'procure_method': 'make_to_stock', - } - move = self.env['stock.move'].sudo().create(move_vals) - move._action_confirm() - move._action_assign() - - if move.move_line_ids: - move.move_line_ids.write({'lot_id': self.lot_id.id}) - - move._action_done() - self.return_move_id = move.id - except Exception as e: - _logger.warning(f"Could not create return stock move: {e}") - - # ========================================================================= - # HISTORY LOGGING - # ========================================================================= - - def _log_history(self, action, notes=None): - """Log action to history.""" - self.ensure_one() - self.env['fusion.loaner.history'].create({ - 'checkout_id': self.id, - 'lot_id': self.lot_id.id if self.lot_id else False, - 'action': action, - 'notes': notes, - }) - - # ========================================================================= - # EMAIL METHODS - # ========================================================================= - - def _get_email_recipients(self): - """Get all email recipients for loaner notifications.""" - recipients = { - 'client_email': self.partner_id.email if self.partner_id else None, - 'authorizer_email': self.authorizer_id.email if self.authorizer_id else None, - 'sales_rep_email': self.sales_rep_id.email if self.sales_rep_id else None, - 'office_emails': [], - } - - # Get office emails from company - company = self.company_id or self.env.company - office_partners = company.sudo().x_fc_office_notification_ids - recipients['office_emails'] = [p.email for p in office_partners if p.email] - - return recipients - - def _send_checkout_email(self): - """Send checkout confirmation email to all parties.""" - self.ensure_one() - recipients = self._get_email_recipients() - to_emails = [e for e in [recipients['client_email'], recipients['authorizer_email']] if e] - cc_emails = [e for e in [recipients['sales_rep_email']] if e] + recipients['office_emails'] - if not to_emails: - return False - - client_name = self.partner_id.name or 'Client' - product_name = self.product_id.name or 'Product' - expected_return = self.expected_return_date.strftime('%B %d, %Y') if self.expected_return_date else 'N/A' - - body_html = self._email_build( - title='Loaner Equipment Checkout', - summary=f'Loaner equipment has been checked out for {client_name}.', - email_type='info', - sections=[('Loaner Details', [ - ('Reference', self.name), - ('Product', product_name), - ('Serial Number', self.lot_id.name if self.lot_id else None), - ('Checkout Date', self.checkout_date.strftime('%B %d, %Y') if self.checkout_date else None), - ('Expected Return', expected_return), - ('Loaner Period', f'{self.loaner_period_days} days'), - ])], - note='Important: Please return the loaner equipment by the expected return date. ' - 'If not returned on time, rental charges may apply.', - note_color='#d69e2e', - ) - try: - self.env['mail.mail'].sudo().create({ - 'subject': f'Loaner Checkout - {product_name} - {self.name}', - 'body_html': body_html, - 'email_to': ', '.join(to_emails), - 'email_cc': ', '.join(cc_emails) if cc_emails else '', - 'model': 'fusion.loaner.checkout', 'res_id': self.id, - }).send() - return True - except Exception as e: - _logger.error(f"Failed to send checkout email for {self.name}: {e}") - return False - - def _send_return_email(self): - """Send return confirmation email.""" - self.ensure_one() - recipients = self._get_email_recipients() - to_emails = [e for e in [recipients['client_email']] if e] - cc_emails = [e for e in [recipients['sales_rep_email']] if e] - if not to_emails: - return False - - client_name = self.partner_id.name or 'Client' - product_name = self.product_id.name or 'Product' - - body_html = self._email_build( - title='Loaner Equipment Returned', - summary=f'Thank you for returning the loaner equipment, {client_name}.', - email_type='success', - sections=[('Return Details', [ - ('Reference', self.name), - ('Product', product_name), - ('Return Date', self.actual_return_date.strftime('%B %d, %Y') if self.actual_return_date else None), - ('Condition', self.return_condition or None), - ('Days Out', str(self.days_out)), - ])], - ) - try: - self.env['mail.mail'].sudo().create({ - 'subject': f'Loaner Returned - {product_name} - {self.name}', - 'body_html': body_html, - 'email_to': ', '.join(to_emails), - 'email_cc': ', '.join(cc_emails) if cc_emails else '', - 'model': 'fusion.loaner.checkout', 'res_id': self.id, - }).send() - return True - except Exception as e: - _logger.error(f"Failed to send return email for {self.name}: {e}") - return False - - def _send_rental_conversion_email(self): - """Send rental conversion notification.""" - self.ensure_one() - recipients = self._get_email_recipients() - to_emails = [e for e in [recipients['client_email'], recipients['authorizer_email']] if e] - cc_emails = [e for e in [recipients['sales_rep_email']] if e] + recipients['office_emails'] - if not to_emails and not cc_emails: - return False - - client_name = self.partner_id.name or 'Client' - product_name = self.product_id.name or 'Product' - weekly_rate = self.product_id.x_fc_rental_price_weekly or 0 - monthly_rate = self.product_id.x_fc_rental_price_monthly or 0 - - body_html = self._email_build( - title='Loaner Rental Conversion Notice', - summary=f'The loaner equipment for {client_name} has exceeded the free loaner period.', - email_type='urgent', - sections=[('Equipment Details', [ - ('Reference', self.name), - ('Product', product_name), - ('Days Out', str(self.days_out)), - ('Days Overdue', str(self.days_overdue)), - ('Weekly Rental Rate', f'${weekly_rate:.2f}'), - ('Monthly Rental Rate', f'${monthly_rate:.2f}'), - ])], - note='Action required: Please return the equipment or contact us to arrange ' - 'a rental agreement. Rental charges will apply until the equipment is returned.', - note_color='#c53030', - ) - email_to = ', '.join(to_emails) if to_emails else ', '.join(cc_emails[:1]) - email_cc = ', '.join(cc_emails) if to_emails else ', '.join(cc_emails[1:]) - try: - self.env['mail.mail'].sudo().create({ - 'subject': f'Loaner Rental Conversion - {product_name} - {self.name}', - 'body_html': body_html, - 'email_to': email_to, 'email_cc': email_cc, - 'model': 'fusion.loaner.checkout', 'res_id': self.id, - }).send() - return True - except Exception as e: - _logger.error(f"Failed to send rental conversion email for {self.name}: {e}") - return False - - def _send_reminder_email(self, reminder_type): - """Send reminder email based on type (day5, day8, day10).""" - self.ensure_one() - recipients = self._get_email_recipients() - client_name = self.partner_id.name or 'Client' - product_name = self.product_id.name or 'Product' - expected_return = self.expected_return_date.strftime('%B %d, %Y') if self.expected_return_date else 'N/A' - - if reminder_type == 'day5': - to_emails = [e for e in [recipients['sales_rep_email']] if e] + recipients['office_emails'] - cc_emails = [] - subject = f'Loaner Reminder: {product_name} - Day 5' - email_type = 'attention' - message = (f'The loaner equipment for {client_name} has been out for 5 days. ' - f'Please follow up to arrange return.') - elif reminder_type == 'day8': - to_emails = [e for e in [recipients['client_email']] if e] - cc_emails = [e for e in [recipients['sales_rep_email']] if e] + recipients['office_emails'] - subject = f'Loaner Return Reminder - {product_name}' - email_type = 'attention' - message = (f'Your loaner equipment has been out for 8 days. ' - f'Please return it soon or it may be converted to a rental.') - else: - to_emails = [e for e in [recipients['client_email'], recipients['authorizer_email']] if e] - cc_emails = [e for e in [recipients['sales_rep_email']] if e] + recipients['office_emails'] - subject = f'Loaner Return Required - {product_name}' - email_type = 'urgent' - message = (f'Your loaner equipment has been out for {self.days_out} days. ' - f'If not returned, rental charges will apply.') - - if not to_emails: - return False - - body_html = self._email_build( - title='Loaner Equipment Reminder', - summary=message, - email_type=email_type, - sections=[('Loaner Details', [ - ('Reference', self.name), - ('Client', client_name), - ('Product', product_name), - ('Days Out', str(self.days_out)), - ('Expected Return', expected_return), - ])], - ) - try: - self.env['mail.mail'].sudo().create({ - 'subject': subject, - 'body_html': body_html, - 'email_to': ', '.join(to_emails), - 'email_cc': ', '.join(cc_emails) if cc_emails else '', - 'model': 'fusion.loaner.checkout', 'res_id': self.id, - }).send() - return True - except Exception as e: - _logger.error(f"Failed to send {reminder_type} reminder for {self.name}: {e}") - return False - - # ========================================================================= - # CRON METHODS - # ========================================================================= - - @api.model - def _cron_check_overdue_loaners(self): - """Daily cron to check for overdue loaners and send reminders.""" - today = fields.Date.today() - - # Find all active loaners - active_loaners = self.search([ - ('state', 'in', ['checked_out', 'overdue', 'rental_pending']), - ]) - - for loaner in active_loaners: - days_out = loaner.days_out - - # Update overdue status - if loaner.state == 'checked_out' and loaner.expected_return_date and today > loaner.expected_return_date: - loaner.write({'state': 'overdue'}) - loaner._log_history('overdue', f'Loaner is now overdue by {loaner.days_overdue} days') - - # Day 5 reminder - if days_out >= 5 and not loaner.reminder_day5_sent: - loaner._send_reminder_email('day5') - loaner.reminder_day5_sent = True - loaner._log_history('reminder_sent', 'Day 5 reminder sent') - - # Day 8 warning - if days_out >= 8 and not loaner.reminder_day8_sent: - loaner._send_reminder_email('day8') - loaner.reminder_day8_sent = True - loaner._log_history('reminder_sent', 'Day 8 rental warning sent') - - # Day 10 final notice - if days_out >= 10 and not loaner.reminder_day10_sent: - loaner._send_reminder_email('day10') - loaner.reminder_day10_sent = True - loaner._log_history('reminder_sent', 'Day 10 final notice sent') - - # Flag for rental conversion - if loaner.state != 'rental_pending': - loaner.action_convert_to_rental() diff --git a/fusion_claims/fusion_claims/models/fusion_loaner_history.py b/fusion_claims/fusion_claims/models/fusion_loaner_history.py deleted file mode 100644 index b451a59..0000000 --- a/fusion_claims/fusion_claims/models/fusion_loaner_history.py +++ /dev/null @@ -1,105 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) - -from odoo import models, fields, api, _ -import logging - -_logger = logging.getLogger(__name__) - - -class FusionLoanerHistory(models.Model): - """Audit trail for loaner equipment actions.""" - _name = 'fusion.loaner.history' - _description = 'Loaner History Log' - _order = 'action_date desc, id desc' - - # ========================================================================= - # REFERENCE FIELDS - # ========================================================================= - - checkout_id = fields.Many2one( - 'fusion.loaner.checkout', - string='Checkout Record', - ondelete='cascade', - required=True, - ) - lot_id = fields.Many2one( - 'stock.lot', - string='Serial Number', - help='The serial number this action relates to', - ) - product_id = fields.Many2one( - 'product.product', - string='Product', - related='checkout_id.product_id', - store=True, - ) - partner_id = fields.Many2one( - 'res.partner', - string='Client', - related='checkout_id.partner_id', - store=True, - ) - - # ========================================================================= - # ACTION DETAILS - # ========================================================================= - - action = fields.Selection([ - ('create', 'Created'), - ('checkout', 'Checked Out'), - ('return', 'Returned'), - ('condition_update', 'Condition Updated'), - ('reminder_sent', 'Reminder Sent'), - ('overdue', 'Marked Overdue'), - ('rental_pending', 'Rental Conversion Pending'), - ('rental_converted', 'Converted to Rental'), - ('lost', 'Marked as Lost'), - ('note', 'Note Added'), - ], string='Action', required=True) - - action_date = fields.Datetime( - string='Date/Time', - default=fields.Datetime.now, - required=True, - ) - user_id = fields.Many2one( - 'res.users', - string='User', - default=lambda self: self.env.user, - required=True, - ) - notes = fields.Text( - string='Notes', - ) - - # ========================================================================= - # DISPLAY - # ========================================================================= - - def _get_action_label(self): - """Get human-readable action label.""" - action_labels = dict(self._fields['action'].selection) - return action_labels.get(self.action, self.action) - - def name_get(self): - result = [] - for record in self: - name = f"{record.checkout_id.name} - {record._get_action_label()}" - result.append((record.id, name)) - return result - - # ========================================================================= - # SEARCH BY SERIAL - # ========================================================================= - - @api.model - def get_history_by_serial(self, lot_id): - """Get all history for a specific serial number.""" - return self.search([('lot_id', '=', lot_id)], order='action_date desc') - - @api.model - def get_history_by_product(self, product_id): - """Get all history for a specific product.""" - return self.search([('product_id', '=', product_id)], order='action_date desc') diff --git a/fusion_claims/fusion_claims/models/product_product.py b/fusion_claims/fusion_claims/models/product_product.py deleted file mode 100644 index 52b752b..0000000 --- a/fusion_claims/fusion_claims/models/product_product.py +++ /dev/null @@ -1,185 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2025 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) -# Part of the Fusion Claim Assistant product family. - -from odoo import models - - -class ProductProduct(models.Model): - _inherit = 'product.product' - - def get_adp_device_code(self): - """ - Get ADP device code from the field mapped in fusion settings. - - The field name is configured in Settings → Sales → Fusion Central → - Field Mappings → Product ADP Code Field. - - Checks the mapped field on the product variant first, then on template. - Returns the value from the mapped field, or empty string if not found. - """ - self.ensure_one() - - # Get the mapped field name from fusion settings - ICP = self.env['ir.config_parameter'].sudo() - field_name = ICP.get_param('fusion_claims.field_product_code', 'x_fc_adp_device_code') - - if not field_name: - return '' - - # Check if the mapped field exists on the product variant (product.product) - if field_name in self._fields: - value = getattr(self, field_name, '') or '' - if value: - return value - - # Check if the mapped field exists on the product template - if self.product_tmpl_id and field_name in self.product_tmpl_id._fields: - value = getattr(self.product_tmpl_id, field_name, '') or '' - if value: - return value - - return '' - - def get_adp_price(self): - """ - Get ADP price from the field mapped in fusion settings. - - The field name is configured in Settings → Sales → Fusion Central → - Field Mappings → Product ADP Price Field. - - Checks the mapped field on the product variant first, then on template. - Returns the value from the mapped field, or 0.0 if not found. - """ - self.ensure_one() - - # Get the mapped field name from fusion settings - ICP = self.env['ir.config_parameter'].sudo() - field_name = ICP.get_param('fusion_claims.field_product_adp_price', 'x_fc_adp_price') - - if not field_name: - return 0.0 - - # Check if the mapped field exists on the product variant (product.product) - if field_name in self._fields: - value = getattr(self, field_name, 0.0) or 0.0 - if value: - return value - - # Check if the mapped field exists on the product template - if self.product_tmpl_id and field_name in self.product_tmpl_id._fields: - value = getattr(self.product_tmpl_id, field_name, 0.0) or 0.0 - if value: - return value - - return 0.0 - - def is_non_adp_funded(self): - """ - Check if this product has a NON-ADP, NON-FUNDED, or UNFUNDED device code. - - Products with these device codes are not covered by ADP and should have: - - ADP portion = 0 - - Client portion = full amount - - NOT included in ADP invoices (only in client invoices) - - Returns True if the product is NOT funded by ADP. - """ - self.ensure_one() - - # Get the ADP device code - adp_code = self.get_adp_device_code() - if not adp_code: - return False - - # Check for non-funded codes (case-insensitive) - # These product codes indicate items NOT covered by ADP funding: - # - NON-ADP, NON-FUNDED, UNFUNDED: Explicitly not ADP funded - # - ACS: Accessibility items (client pays 100%) - # - ODS: ODSP items (client pays 100%) - # - OWP: Ontario Works items (client pays 100%) - non_funded_codes = [ - 'NON-ADP', 'NON ADP', 'NONADP', - 'NON-FUNDED', 'NON FUNDED', 'NONFUNDED', - 'UNFUNDED', 'NOT-FUNDED', 'NOT FUNDED', 'NOTFUNDED', - 'ACS', 'ODS', 'OWP' - ] - adp_code_upper = adp_code.upper().strip() - - for non_funded in non_funded_codes: - if adp_code_upper == non_funded or adp_code_upper.startswith(non_funded): - return True - - return False - - def action_sync_adp_price_from_database(self): - """ - Update product's ADP price from the device codes database. - - Looks up the product's ADP device code in the fusion.adp.device.code table - and updates the product's x_fc_adp_price field with the database value. - - Returns a notification with the result. - """ - ADPDevice = self.env['fusion.adp.device.code'].sudo() - updated = [] - not_found = [] - no_code = [] - - for product in self: - device_code = product.get_adp_device_code() - if not device_code: - no_code.append(product.name) - continue - - adp_device = ADPDevice.search([ - ('device_code', '=', device_code), - ('active', '=', True) - ], limit=1) - - if adp_device and adp_device.adp_price: - # Update product template - product_tmpl = product.product_tmpl_id - old_price = 0 - - if hasattr(product_tmpl, 'x_fc_adp_price'): - old_price = getattr(product_tmpl, 'x_fc_adp_price', 0) or 0 - product_tmpl.sudo().write({'x_fc_adp_price': adp_device.adp_price}) - updated.append({ - 'name': product.name, - 'code': device_code, - 'old_price': old_price, - 'new_price': adp_device.adp_price, - }) - else: - not_found.append(f"{product.name} ({device_code})") - - # Build result message - message_parts = [] - if updated: - msg = f"Updated {len(updated)} product(s):
        " - for u in updated: - msg += f"
      • {u['name']}: ${u['old_price']:.2f} → ${u['new_price']:.2f}
      • " - msg += "
      " - message_parts.append(msg) - - if not_found: - message_parts.append(f"Not found in database: {', '.join(not_found)}") - - if no_code: - message_parts.append(f"No ADP code: {', '.join(no_code)}") - - if not message_parts: - message_parts.append("No products to process.") - - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'ADP Price Sync', - 'message': '
      '.join(message_parts), - 'type': 'success' if updated else 'warning', - 'sticky': True, - } - } diff --git a/fusion_claims/fusion_claims/models/product_template.py b/fusion_claims/fusion_claims/models/product_template.py deleted file mode 100644 index 770eb5e..0000000 --- a/fusion_claims/fusion_claims/models/product_template.py +++ /dev/null @@ -1,109 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2025 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) -# Part of the Fusion Claim Assistant product family. - -from odoo import api, fields, models - - -class ProductTemplate(models.Model): - _inherit = 'product.template' - - # ========================================================================== - # ADP PRODUCT FIELDS - # These are the module's own fields - independent of Odoo Studio - # ========================================================================== - - x_fc_adp_device_code = fields.Char( - string='ADP Device Code', - help='Device code used for ADP claims export', - copy=True, - tracking=True, - ) - - x_fc_adp_price = fields.Float( - string='ADP Price', - digits='Product Price', - help='ADP retail price for this product. Used in ADP reports and claims.', - copy=True, - tracking=True, - ) - - x_fc_is_adp_product = fields.Boolean( - string='Is ADP Product', - compute='_compute_is_adp_product', - store=True, - help='Indicates if this product has ADP pricing set up', - ) - - # ========================================================================== - # LOANER PRODUCT FIELDS - # ========================================================================== - - x_fc_can_be_loaned = fields.Boolean( - string='Can be Loaned', - default=False, - help='If checked, this product can be loaned out to clients', - ) - x_fc_loaner_period_days = fields.Integer( - string='Loaner Period (Days)', - default=7, - help='Default number of free loaner days before rental conversion', - ) - x_fc_rental_price_weekly = fields.Float( - string='Weekly Rental Price', - digits='Product Price', - help='Rental price per week if loaner converts to rental', - ) - x_fc_rental_price_monthly = fields.Float( - string='Monthly Rental Price', - digits='Product Price', - help='Rental price per month if loaner converts to rental', - ) - - # ========================================================================== - # COMPUTED FIELDS - # ========================================================================== - - @api.depends('x_fc_adp_device_code', 'x_fc_adp_price') - def _compute_is_adp_product(self): - """Determine if this is an ADP product based on having device code or price.""" - for product in self: - product.x_fc_is_adp_product = bool( - product.x_fc_adp_device_code or product.x_fc_adp_price - ) - - # ========================================================================== - # HELPER METHODS - # ========================================================================== - - def get_adp_price(self): - """ - Get ADP price with fallback to Studio field. - - Checks in order: - 1. x_fc_adp_price (module field) - 2. list_price (default product price) - """ - self.ensure_one() - - if self.x_fc_adp_price: - return self.x_fc_adp_price - - return self.list_price or 0.0 - - def get_adp_device_code(self): - """ - Get ADP device code. - - Checks in order: - 1. x_fc_adp_device_code (module field) - 2. default_code (internal reference) - """ - self.ensure_one() - - if self.x_fc_adp_device_code: - return self.x_fc_adp_device_code - - return self.default_code or '' - diff --git a/fusion_claims/fusion_claims/models/push_subscription.py b/fusion_claims/fusion_claims/models/push_subscription.py deleted file mode 100644 index 19f9033..0000000 --- a/fusion_claims/fusion_claims/models/push_subscription.py +++ /dev/null @@ -1,73 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) - -""" -Web Push Subscription model for storing browser push notification subscriptions. -""" - -from odoo import models, fields, api -import logging - -_logger = logging.getLogger(__name__) - - -class FusionPushSubscription(models.Model): - _name = 'fusion.push.subscription' - _description = 'Web Push Subscription' - _order = 'create_date desc' - - user_id = fields.Many2one( - 'res.users', - string='User', - required=True, - ondelete='cascade', - index=True, - ) - endpoint = fields.Text( - string='Endpoint URL', - required=True, - ) - p256dh_key = fields.Text( - string='P256DH Key', - required=True, - ) - auth_key = fields.Text( - string='Auth Key', - required=True, - ) - browser_info = fields.Char( - string='Browser Info', - help='User agent or browser identification', - ) - active = fields.Boolean( - default=True, - ) - - _constraints = [ - models.Constraint( - 'unique(endpoint)', - 'This push subscription endpoint already exists.', - ), - ] - - @api.model - def register_subscription(self, user_id, endpoint, p256dh_key, auth_key, browser_info=None): - """Register or update a push subscription.""" - existing = self.sudo().search([('endpoint', '=', endpoint)], limit=1) - if existing: - existing.write({ - 'user_id': user_id, - 'p256dh_key': p256dh_key, - 'auth_key': auth_key, - 'browser_info': browser_info or existing.browser_info, - 'active': True, - }) - return existing - return self.sudo().create({ - 'user_id': user_id, - 'endpoint': endpoint, - 'p256dh_key': p256dh_key, - 'auth_key': auth_key, - 'browser_info': browser_info, - }) diff --git a/fusion_claims/fusion_claims/models/res_company.py b/fusion_claims/fusion_claims/models/res_company.py deleted file mode 100644 index 039be29..0000000 --- a/fusion_claims/fusion_claims/models/res_company.py +++ /dev/null @@ -1,69 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2025 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) -# Part of the Fusion Claim Assistant product family. - -from odoo import models, fields - - -class ResCompany(models.Model): - _inherit = 'res.company' - - # Store/Location Information - x_fc_store_address_1 = fields.Char( - string='Store Address Line 1', - help='First store/location address for reports (e.g., "Main Store - 123 Street, City, Province, Postal")', - ) - x_fc_store_address_2 = fields.Char( - string='Store Address Line 2', - help='Second store/location address for reports (optional)', - ) - x_fc_company_tagline = fields.Char( - string='Company Tagline', - help='Company tagline/slogan for reports (e.g., "Enhancing Accessibility, Improving Lives.")', - ) - - # Payment Information - x_fc_etransfer_email = fields.Char( - string='E-Transfer Email', - help='Email address for Interac e-Transfers', - ) - x_fc_cheque_payable_to = fields.Char( - string='Cheque Payable To', - help='Name for cheque payments (defaults to company name if empty)', - ) - x_fc_payment_terms_html = fields.Html( - string='Payment Terms', - help='Payment terms and conditions displayed on reports (supports HTML formatting)', - sanitize=True, - sanitize_overridable=True, - ) - - # Refund Policy - x_fc_include_refund_page = fields.Boolean( - string='Include Refund Policy Page', - default=True, - help='Include a separate refund policy page at the end of reports', - ) - x_fc_refund_policy_html = fields.Html( - string='Refund Policy', - help='Full refund policy displayed on a separate page (supports HTML formatting)', - sanitize=True, - sanitize_overridable=True, - ) - - # Office Notification Recipients - x_fc_office_notification_ids = fields.Many2many( - 'res.partner', - 'fc_company_office_notification_partners_rel', - 'company_id', - 'partner_id', - string='Office Notification Recipients', - help='Contacts who will receive a copy (CC) of all automated ADP notifications', - ) - - def _get_cheque_payable_name(self): - """Get the name for cheque payments, defaulting to company name.""" - self.ensure_one() - return self.x_fc_cheque_payable_to or self.name - diff --git a/fusion_claims/fusion_claims/models/res_config_settings.py b/fusion_claims/fusion_claims/models/res_config_settings.py deleted file mode 100644 index a8a09ab..0000000 --- a/fusion_claims/fusion_claims/models/res_config_settings.py +++ /dev/null @@ -1,602 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2025 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) -# Part of the Fusion Claim Assistant product family. - -import logging - -from odoo import models, fields, api - -_logger = logging.getLogger(__name__) - - -class ResConfigSettings(models.TransientModel): - _inherit = 'res.config.settings' - - # ========================================================================= - # COMPANY SETTINGS (Related to res.company) - # ========================================================================= - - fc_store_address_1 = fields.Char( - related='company_id.x_fc_store_address_1', - readonly=False, - string='Store Address Line 1', - ) - fc_store_address_2 = fields.Char( - related='company_id.x_fc_store_address_2', - readonly=False, - string='Store Address Line 2', - ) - fc_company_tagline = fields.Char( - related='company_id.x_fc_company_tagline', - readonly=False, - string='Company Tagline', - ) - fc_etransfer_email = fields.Char( - related='company_id.x_fc_etransfer_email', - readonly=False, - string='E-Transfer Email', - ) - fc_cheque_payable_to = fields.Char( - related='company_id.x_fc_cheque_payable_to', - readonly=False, - string='Cheque Payable To', - ) - fc_payment_terms_html = fields.Html( - related='company_id.x_fc_payment_terms_html', - readonly=False, - string='Payment Terms', - ) - fc_include_refund_page = fields.Boolean( - related='company_id.x_fc_include_refund_page', - readonly=False, - string='Include Refund Policy Page', - ) - fc_refund_policy_html = fields.Html( - related='company_id.x_fc_refund_policy_html', - readonly=False, - string='Refund Policy', - ) - - # ========================================================================= - # ADP BILLING SETTINGS - # ========================================================================= - - fc_vendor_code = fields.Char( - string='ADP Vendor Code', - config_parameter='fusion_claims.vendor_code', - help='Your ADP vendor/location code for claim submissions', - ) - - # ========================================================================= - # FIELD MAPPINGS - # ========================================================================= - - fc_field_sale_type = fields.Char( - string='Sale Type Field', - config_parameter='fusion_claims.field_sale_type', - help='Field name for sale type on sale.order', - ) - fc_field_so_client_type = fields.Char( - string='SO Client Type Field', - config_parameter='fusion_claims.field_so_client_type', - help='Field name for client type on sale.order', - ) - fc_field_so_authorizer = fields.Char( - string='SO Authorizer Field', - config_parameter='fusion_claims.field_so_authorizer', - help='Field name for authorizer on sale.order', - ) - fc_field_invoice_type = fields.Char( - string='Invoice Type Field', - config_parameter='fusion_claims.field_invoice_type', - help='Field name for invoice type on account.move', - ) - fc_field_inv_client_type = fields.Char( - string='Invoice Client Type Field', - config_parameter='fusion_claims.field_inv_client_type', - help='Field name for client type on account.move', - ) - fc_field_inv_authorizer = fields.Char( - string='Invoice Authorizer Field', - config_parameter='fusion_claims.field_inv_authorizer', - help='Field name for authorizer on account.move', - ) - fc_field_product_code = fields.Char( - string='Product ADP Code Field', - config_parameter='fusion_claims.field_product_code', - help='Field name for ADP device code on product.template', - ) - fc_field_sol_serial = fields.Char( - string='SO Line Serial Field', - config_parameter='fusion_claims.field_sol_serial', - help='Field name for serial number on sale.order.line', - ) - fc_field_aml_serial = fields.Char( - string='Invoice Line Serial Field', - config_parameter='fusion_claims.field_aml_serial', - help='Field name for serial number on account.move.line', - ) - - # ========================================================================= - # ADDITIONAL SALE ORDER FIELD MAPPINGS - # ========================================================================= - - fc_field_so_claim_number = fields.Char( - string='SO Claim Number Field', - config_parameter='fusion_claims.field_so_claim_number', - help='Field name for claim number on sale.order', - ) - fc_field_so_client_ref_1 = fields.Char( - string='SO Client Ref 1 Field', - config_parameter='fusion_claims.field_so_client_ref_1', - help='Field name for client reference 1 on sale.order', - ) - fc_field_so_client_ref_2 = fields.Char( - string='SO Client Ref 2 Field', - config_parameter='fusion_claims.field_so_client_ref_2', - help='Field name for client reference 2 on sale.order', - ) - fc_field_so_delivery_date = fields.Char( - string='SO Delivery Date Field', - config_parameter='fusion_claims.field_so_delivery_date', - help='Field name for ADP delivery date on sale.order', - ) - fc_field_so_adp_status = fields.Char( - string='SO ADP Status Field', - config_parameter='fusion_claims.field_so_adp_status', - help='Field name for ADP status on sale.order', - ) - fc_field_so_service_start = fields.Char( - string='SO Service Start Date Field', - config_parameter='fusion_claims.field_so_service_start', - help='Field name for service start date on sale.order', - ) - fc_field_so_service_end = fields.Char( - string='SO Service End Date Field', - config_parameter='fusion_claims.field_so_service_end', - help='Field name for service end date on sale.order', - ) - - # ========================================================================= - # ADDITIONAL INVOICE FIELD MAPPINGS - # ========================================================================= - - fc_field_inv_claim_number = fields.Char( - string='Invoice Claim Number Field', - config_parameter='fusion_claims.field_inv_claim_number', - help='Field name for claim number on account.move', - ) - fc_field_inv_client_ref_1 = fields.Char( - string='Invoice Client Ref 1 Field', - config_parameter='fusion_claims.field_inv_client_ref_1', - help='Field name for client reference 1 on account.move', - ) - fc_field_inv_client_ref_2 = fields.Char( - string='Invoice Client Ref 2 Field', - config_parameter='fusion_claims.field_inv_client_ref_2', - help='Field name for client reference 2 on account.move', - ) - fc_field_inv_delivery_date = fields.Char( - string='Invoice Delivery Date Field', - config_parameter='fusion_claims.field_inv_delivery_date', - help='Field name for ADP delivery date on account.move', - ) - fc_field_inv_service_start = fields.Char( - string='Invoice Service Start Date Field', - config_parameter='fusion_claims.field_inv_service_start', - help='Field name for service start date on account.move', - ) - fc_field_inv_service_end = fields.Char( - string='Invoice Service End Date Field', - config_parameter='fusion_claims.field_inv_service_end', - help='Field name for service end date on account.move', - ) - - # ========================================================================= - # SALE ORDER LINE FIELD MAPPINGS - # ========================================================================= - - fc_field_sol_placement = fields.Char( - string='SO Line Placement Field', - config_parameter='fusion_claims.field_sol_placement', - help='Field name for device placement on sale.order.line', - ) - - # ========================================================================= - # INVOICE LINE FIELD MAPPINGS - # ========================================================================= - - fc_field_aml_placement = fields.Char( - string='Invoice Line Placement Field', - config_parameter='fusion_claims.field_aml_placement', - help='Field name for device placement on account.move.line', - ) - - # ========================================================================= - # PRODUCT FIELD MAPPINGS - # ========================================================================= - - fc_field_product_adp_price = fields.Char( - string='Product ADP Price Field', - config_parameter='fusion_claims.field_product_adp_price', - help='Field name for ADP price on product.template', - ) - - # ========================================================================= - # HEADER-LEVEL SERIAL NUMBER MAPPINGS - # ========================================================================= - - fc_field_so_primary_serial = fields.Char( - string='SO Primary Serial Field', - config_parameter='fusion_claims.field_so_primary_serial', - help='Field name for primary serial number on sale.order (header level)', - ) - fc_field_inv_primary_serial = fields.Char( - string='Invoice Primary Serial Field', - config_parameter='fusion_claims.field_inv_primary_serial', - help='Field name for primary serial number on account.move (header level)', - ) - - # ========================================================================= - # ADP POSTING SCHEDULE SETTINGS - # ========================================================================= - - fc_adp_posting_base_date = fields.Char( - string='ADP Posting Base Date', - config_parameter='fusion_claims.adp_posting_base_date', - help='Reference date for calculating bi-weekly posting schedule (a known posting day). Format: YYYY-MM-DD', - ) - fc_adp_posting_frequency_days = fields.Integer( - string='Posting Frequency (Days)', - config_parameter='fusion_claims.adp_posting_frequency_days', - help='Number of days between ADP posting cycles (typically 14 days)', - ) - fc_adp_billing_reminder_user_id = fields.Many2one( - 'res.users', - string='Billing Deadline Reminder Person', - # NOTE: stored manually via get_values/set_values (not config_parameter) - # because Many2one + config_parameter causes double-write conflicts - help='Person to remind on Monday to complete ADP billing by Wednesday 6 PM', - ) - fc_adp_correction_reminder_user_ids = fields.Many2many( - 'res.users', - 'fc_config_correction_reminder_users_rel', - 'config_id', - 'user_id', - string='Correction Alert Recipients', - help='People to notify when an ADP invoice needs correction/resubmission', - ) - - # ========================================================================= - # EMAIL NOTIFICATION SETTINGS - # ========================================================================= - - fc_enable_email_notifications = fields.Boolean( - string='Enable Automated Email Notifications', - config_parameter='fusion_claims.enable_email_notifications', - help='Enable/disable automated email notifications for ADP workflow events', - ) - fc_office_notification_ids = fields.Many2many( - related='company_id.x_fc_office_notification_ids', - readonly=False, - string='Office Notification Recipients', - ) - fc_application_reminder_days = fields.Integer( - string='First Reminder Days', - config_parameter='fusion_claims.application_reminder_days', - help='Number of days after assessment completion to send first application reminder to therapist', - ) - fc_application_reminder_2_days = fields.Integer( - string='Second Reminder Days (After First)', - config_parameter='fusion_claims.application_reminder_2_days', - help='Number of days after first reminder to send second application reminder to therapist', - ) - - # ========================================================================= - # WORKFLOW LOCK SETTINGS - # ========================================================================= - - fc_allow_sale_type_override = fields.Boolean( - string='Allow Sale Type Override', - config_parameter='fusion_claims.allow_sale_type_override', - help='If enabled, allows changing Sale Type even after application is submitted (for cases where additional benefits are discovered)', - ) - - fc_allow_document_lock_override = fields.Boolean( - string='Allow Document Lock Override', - config_parameter='fusion_claims.allow_document_lock_override', - help='When enabled, users in the "Document Lock Override" group can edit locked documents on old cases. ' - 'Disable this once all legacy cases have been processed to enforce strict workflow.', - ) - - fc_designated_vendor_signer = fields.Many2one( - 'res.users', - string='Designated Vendor Signer', - help='The user who signs Page 12 on behalf of the company', - ) - - # ========================================================================= - # GOOGLE MAPS API SETTINGS - # ========================================================================= - - fc_google_maps_api_key = fields.Char( - string='Google Maps API Key', - config_parameter='fusion_claims.google_maps_api_key', - help='API key for Google Maps Places autocomplete in address fields', - ) - - # ------------------------------------------------------------------ - # AI CLIENT INTELLIGENCE - # ------------------------------------------------------------------ - fc_ai_api_key = fields.Char( - string='AI API Key', - config_parameter='fusion_claims.ai_api_key', - help='OpenAI API key for Client Intelligence chat', - ) - fc_ai_model = fields.Selection([ - ('gpt-4o-mini', 'GPT-4o Mini (Fast, Lower Cost)'), - ('gpt-4o', 'GPT-4o (Best Quality)'), - ('gpt-4.1-mini', 'GPT-4.1 Mini'), - ('gpt-4.1', 'GPT-4.1'), - ], string='AI Model', - config_parameter='fusion_claims.ai_model', - ) - fc_auto_parse_xml = fields.Boolean( - string='Auto-Parse XML Files', - config_parameter='fusion_claims.auto_parse_xml', - help='Automatically parse ADP XML files when uploaded and create/update client profiles', - ) - - # ------------------------------------------------------------------ - # TECHNICIAN MANAGEMENT - # ------------------------------------------------------------------ - fc_store_open_hour = fields.Float( - string='Store Open Time', - config_parameter='fusion_claims.store_open_hour', - help='Store opening time for technician scheduling (e.g. 9.0 = 9:00 AM)', - ) - fc_store_close_hour = fields.Float( - string='Store Close Time', - config_parameter='fusion_claims.store_close_hour', - help='Store closing time for technician scheduling (e.g. 18.0 = 6:00 PM)', - ) - fc_google_distance_matrix_enabled = fields.Boolean( - string='Enable Distance Matrix', - config_parameter='fusion_claims.google_distance_matrix_enabled', - help='Enable Google Distance Matrix API for travel time calculations between technician tasks', - ) - fc_technician_start_address = fields.Char( - string='Technician Start Address', - config_parameter='fusion_claims.technician_start_address', - help='Default start location for technician travel calculations (e.g. warehouse/office address)', - ) - fc_location_retention_days = fields.Char( - string='Location History Retention (Days)', - config_parameter='fusion_claims.location_retention_days', - help='How many days to keep technician location history. ' - 'Leave empty = 30 days (1 month). ' - '0 = delete at end of each day. ' - '1+ = keep for that many days.', - ) - - # ------------------------------------------------------------------ - # WEB PUSH NOTIFICATIONS - # ------------------------------------------------------------------ - fc_push_enabled = fields.Boolean( - string='Enable Push Notifications', - config_parameter='fusion_claims.push_enabled', - help='Enable web push notifications for technician tasks', - ) - fc_vapid_public_key = fields.Char( - string='VAPID Public Key', - config_parameter='fusion_claims.vapid_public_key', - help='Public key for Web Push VAPID authentication (auto-generated)', - ) - fc_vapid_private_key = fields.Char( - string='VAPID Private Key', - config_parameter='fusion_claims.vapid_private_key', - help='Private key for Web Push VAPID authentication (auto-generated)', - ) - fc_push_advance_minutes = fields.Integer( - string='Notification Advance (min)', - config_parameter='fusion_claims.push_advance_minutes', - help='Send push notifications this many minutes before a scheduled task', - ) - - # ------------------------------------------------------------------ - # TWILIO SMS SETTINGS - # ------------------------------------------------------------------ - fc_twilio_enabled = fields.Boolean( - string='Enable Twilio SMS', - config_parameter='fusion_claims.twilio_enabled', - help='Enable SMS notifications via Twilio for assessment bookings and key status updates', - ) - fc_twilio_account_sid = fields.Char( - string='Twilio Account SID', - config_parameter='fusion_claims.twilio_account_sid', - groups='fusion_claims.group_fusion_claims_manager', - ) - fc_twilio_auth_token = fields.Char( - string='Twilio Auth Token', - config_parameter='fusion_claims.twilio_auth_token', - groups='fusion_claims.group_fusion_claims_manager', - ) - fc_twilio_phone_number = fields.Char( - string='Twilio Phone Number', - config_parameter='fusion_claims.twilio_phone_number', - help='Your Twilio phone number for sending SMS (e.g. +1234567890)', - ) - - # ------------------------------------------------------------------ - # MARCH OF DIMES SETTINGS - # ------------------------------------------------------------------ - fc_mod_default_email = fields.Char( - string='MOD Default Email', - config_parameter='fusion_claims.mod_default_email', - help='Default email for sending quotations and documents to March of Dimes (e.g. hvmp@marchofdimes.ca)', - ) - fc_mod_vendor_code = fields.Char( - string='March of Dimes Vendor Code', - config_parameter='fusion_claims.mod_vendor_code', - help='Your vendor code assigned by March of Dimes (e.g. TRD0001234)', - ) - - # ------------------------------------------------------------------ - # MOD FOLLOW-UP SETTINGS - # ------------------------------------------------------------------ - fc_mod_followup_interval_days = fields.Integer( - string='Follow-up Interval (Days)', - config_parameter='fusion_claims.mod_followup_interval_days', - help='Number of days between follow-up reminders for MOD cases awaiting funding (default: 14)', - ) - fc_mod_followup_escalation_days = fields.Integer( - string='Escalation Delay (Days)', - config_parameter='fusion_claims.mod_followup_escalation_days', - help='Days after a follow-up activity is due before auto-sending email to client (default: 3)', - ) - - # ------------------------------------------------------------------ - # ODSP CONFIGURATION - # ------------------------------------------------------------------ - fc_sa_mobility_email = fields.Char( - string='SA Mobility Email', - config_parameter='fusion_claims.sa_mobility_email', - help='Email address for SA Mobility submissions (default: samobility@ontario.ca)', - ) - fc_sa_mobility_phone = fields.Char( - string='SA Mobility Phone', - config_parameter='fusion_claims.sa_mobility_phone', - help='SA Mobility phone number (default: 1-888-222-5099)', - ) - fc_odsp_default_office_id = fields.Many2one( - 'res.partner', - string='Default ODSP Office', - domain="[('x_fc_contact_type', '=', 'odsp_office')]", - help='Default ODSP office contact for new ODSP cases', - ) - - @api.model - def get_values(self): - res = super().get_values() - ICP = self.env['ir.config_parameter'].sudo() - - # Get billing reminder user - billing_user_id = ICP.get_param('fusion_claims.adp_billing_reminder_user_id', False) - if billing_user_id: - try: - res['fc_adp_billing_reminder_user_id'] = int(billing_user_id) - except (ValueError, TypeError): - res['fc_adp_billing_reminder_user_id'] = False - - # Get correction reminder users (stored as comma-separated IDs) - correction_user_ids = ICP.get_param('fusion_claims.adp_correction_reminder_user_ids', '') - if correction_user_ids: - try: - user_ids = [int(x.strip()) for x in correction_user_ids.split(',') if x.strip()] - res['fc_adp_correction_reminder_user_ids'] = [(6, 0, user_ids)] - except (ValueError, TypeError): - res['fc_adp_correction_reminder_user_ids'] = [(6, 0, [])] - - # Get designated vendor signer - vendor_signer_id = ICP.get_param('fusion_claims.designated_vendor_signer', False) - if vendor_signer_id: - try: - res['fc_designated_vendor_signer'] = int(vendor_signer_id) - except (ValueError, TypeError): - res['fc_designated_vendor_signer'] = False - - # Get default ODSP office - odsp_office_id = ICP.get_param('fusion_claims.odsp_default_office_id', False) - if odsp_office_id: - try: - res['fc_odsp_default_office_id'] = int(odsp_office_id) - except (ValueError, TypeError): - res['fc_odsp_default_office_id'] = False - - return res - - def set_values(self): - ICP = self.env['ir.config_parameter'].sudo() - - # --- Protect sensitive config_parameter fields from accidental blanking --- - # These are keys where a blank/default value should NOT overwrite - # an existing non-empty value (e.g. API keys, user-customized settings). - _protected_keys = [ - 'fusion_claims.ai_api_key', - 'fusion_claims.google_maps_api_key', - 'fusion_claims.vendor_code', - 'fusion_claims.ai_model', - 'fusion_claims.adp_posting_base_date', - 'fusion_claims.application_reminder_days', - 'fusion_claims.application_reminder_2_days', - 'fusion_claims.store_open_hour', - 'fusion_claims.store_close_hour', - 'fusion_claims.technician_start_address', - ] - # Snapshot existing values BEFORE super().set_values() runs - _existing = {} - for key in _protected_keys: - val = ICP.get_param(key, '') - if val: - _existing[key] = val - - super().set_values() - - # Restore any protected values that were blanked by the save - for key, old_val in _existing.items(): - new_val = ICP.get_param(key, '') - if not new_val and old_val: - ICP.set_param(key, old_val) - _logger.warning( - "Settings protection: restored %s (was blanked during save)", key - ) - - # Store billing reminder user (Many2one - manual handling) - if self.fc_adp_billing_reminder_user_id: - ICP.set_param('fusion_claims.adp_billing_reminder_user_id', - str(self.fc_adp_billing_reminder_user_id.id)) - # Only clear if explicitly set to empty AND there was no existing value - elif not ICP.get_param('fusion_claims.adp_billing_reminder_user_id', ''): - ICP.set_param('fusion_claims.adp_billing_reminder_user_id', '') - - # Store correction reminder users as comma-separated IDs - if self.fc_adp_correction_reminder_user_ids: - user_ids = ','.join(str(u.id) for u in self.fc_adp_correction_reminder_user_ids) - ICP.set_param('fusion_claims.adp_correction_reminder_user_ids', user_ids) - # Only clear if explicitly empty AND no existing value - elif not ICP.get_param('fusion_claims.adp_correction_reminder_user_ids', ''): - ICP.set_param('fusion_claims.adp_correction_reminder_user_ids', '') - - # Office notification recipients are stored via related field on res.company - # No need to store in ir.config_parameter - - # Store designated vendor signer (Many2one - manual handling) - if self.fc_designated_vendor_signer: - ICP.set_param('fusion_claims.designated_vendor_signer', - str(self.fc_designated_vendor_signer.id)) - elif not ICP.get_param('fusion_claims.designated_vendor_signer', ''): - ICP.set_param('fusion_claims.designated_vendor_signer', '') - - # Store default ODSP office (Many2one - manual handling) - if self.fc_odsp_default_office_id: - ICP.set_param('fusion_claims.odsp_default_office_id', - str(self.fc_odsp_default_office_id.id)) - elif not ICP.get_param('fusion_claims.odsp_default_office_id', ''): - ICP.set_param('fusion_claims.odsp_default_office_id', '') - - # ========================================================================= - # ACTION METHODS - # ========================================================================= - - def action_open_field_mapping_wizard(self): - """Open the field mapping configuration wizard.""" - return { - 'type': 'ir.actions.act_window', - 'name': 'Field Mapping Configuration', - 'res_model': 'fusion_claims.field_mapping_config', - 'view_mode': 'form', - 'target': 'new', - 'context': {}, - } - diff --git a/fusion_claims/fusion_claims/models/res_partner.py b/fusion_claims/fusion_claims/models/res_partner.py deleted file mode 100644 index 8ddc9f0..0000000 --- a/fusion_claims/fusion_claims/models/res_partner.py +++ /dev/null @@ -1,82 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) - -from odoo import models, fields, api - - -class ResPartner(models.Model): - _inherit = 'res.partner' - - x_fc_start_address = fields.Char( - string='Start Location', - help='Technician daily start location (home, warehouse, etc.). ' - 'Used as origin for first travel time calculation. ' - 'If empty, the company default HQ address is used.', - ) - - # ========================================================================== - # CONTACT TYPE - # ========================================================================== - x_fc_contact_type = fields.Selection( - selection=[ - ('adp_customer', 'ADP Customer'), - ('adp_odsp_customer', 'ADP-ODSP Customer'), - ('odsp_customer', 'ODSP Customer'), - ('mod_customer', 'MOD Customer'), - ('private_customer', 'Private Customer'), - ('wsib_customer', 'WSIB Customer'), - ('acsd_customer', 'ACSD Customer'), - ('private_insurance', 'Private Insurance'), - ('adp_agent', 'ADP Agent'), - ('odsp_agent', 'ODSP Agent'), - ('muscular_dystrophy', 'Muscular Dystrophy'), - ('occupational_therapist', 'Occupational Therapist'), - ('physiotherapist', 'Physiotherapist'), - ('vendor', 'Vendor'), - ('funding_agency', 'Funding Agency'), - ('government_agency', 'Government Agency'), - ('company_contact', 'Company Contact'), - ('long_term_care_home', 'Long Term Care Home'), - ('retirement_home', 'Retirement Home'), - ('odsp_office', 'ODSP Office'), - ('other', 'Other'), - ], - string='Contact Type', - tracking=True, - index=True, - ) - - # ========================================================================== - # ODSP FIELDS - # ========================================================================== - x_fc_odsp_member_id = fields.Char( - string='ODSP Member ID', - size=9, - tracking=True, - help='9-digit Ontario Disability Support Program Member ID', - ) - x_fc_case_worker_id = fields.Many2one( - 'res.partner', - string='ODSP Case Worker', - tracking=True, - help='ODSP Case Worker assigned to this client', - ) - x_fc_date_of_birth = fields.Date( - string='Date of Birth', - tracking=True, - ) - x_fc_healthcard_number = fields.Char( - string='Healthcard Number', - tracking=True, - ) - x_fc_is_odsp_office = fields.Boolean( - compute='_compute_is_odsp_office', - string='Is ODSP Office', - store=True, - ) - - @api.depends('x_fc_contact_type') - def _compute_is_odsp_office(self): - for partner in self: - partner.x_fc_is_odsp_office = partner.x_fc_contact_type == 'odsp_office' diff --git a/fusion_claims/fusion_claims/models/res_users.py b/fusion_claims/fusion_claims/models/res_users.py deleted file mode 100644 index f17757b..0000000 --- a/fusion_claims/fusion_claims/models/res_users.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) - -from odoo import models, fields, api - - -class ResUsers(models.Model): - _inherit = 'res.users' - - x_fc_is_field_staff = fields.Boolean( - string='Field Staff', - default=False, - help='Check this to show the user in the Technician/Field Staff dropdown when scheduling tasks.', - ) - x_fc_start_address = fields.Char( - related='partner_id.x_fc_start_address', - readonly=False, - string='Start Location', - ) - x_fc_tech_sync_id = fields.Char( - string='Tech Sync ID', - help='Shared identifier for this technician across Odoo instances. ' - 'Must be the same value on all instances for the same person.', - copy=False, - ) \ No newline at end of file diff --git a/fusion_claims/fusion_claims/models/sale_order.py b/fusion_claims/fusion_claims/models/sale_order.py deleted file mode 100644 index 3a47fba..0000000 --- a/fusion_claims/fusion_claims/models/sale_order.py +++ /dev/null @@ -1,7817 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2025 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) -# Part of the Fusion Claim Assistant product family. - -import logging -import re -from markupsafe import Markup -from odoo import models, fields, api -from odoo.exceptions import ValidationError, UserError - -_logger = logging.getLogger(__name__) - - -class SaleOrder(models.Model): - _name = 'sale.order' - _inherit = ['sale.order', 'fusion_claims.adp.posting.schedule.mixin', 'fusion.email.builder.mixin'] - _rec_names_search = ['name', 'partner_id.name'] - - @api.depends('name', 'partner_id.name') - def _compute_display_name(self): - for order in self: - name = order.name or '' - if order.partner_id and order.partner_id.name: - name = f"{name} -- {order.partner_id.name}" - order.display_name = name - - # ========================================================================== - # FIELD FLAGS - # ========================================================================== - x_fc_is_adp_sale = fields.Boolean( - compute='_compute_is_adp_sale', - store=True, - string='Is ADP Sale', - help='True only for ADP or ADP/ODSP sale types', - ) - - # ========================================================================== - # INVOICE COUNT FIELDS (Separate ADP and Client invoices) - # ========================================================================== - x_fc_adp_invoice_count = fields.Integer( - compute='_compute_invoice_counts', - string='ADP Invoices', - ) - x_fc_client_invoice_count = fields.Integer( - compute='_compute_invoice_counts', - string='Client Invoices', - ) - - @api.depends('x_fc_adp_invoice_id', 'x_fc_client_invoice_id') - def _compute_invoice_counts(self): - """Compute separate counts for ADP and Client invoices. - - Uses x_fc_source_sale_order_id for direct linking instead of invoice_ids - which only works when invoice lines have sale_line_ids. - Also includes manually mapped invoices from x_fc_adp_invoice_id and x_fc_client_invoice_id. - """ - AccountMove = self.env['account.move'].sudo() - for order in self: - # Search for invoices directly linked to this order via x_fc_source_sale_order_id - adp_invoices = AccountMove.search([ - ('x_fc_source_sale_order_id', '=', order.id), - ('x_fc_adp_invoice_portion', '=', 'adp'), - ('state', '!=', 'cancel'), - ]) - client_invoices = AccountMove.search([ - ('x_fc_source_sale_order_id', '=', order.id), - ('x_fc_adp_invoice_portion', '=', 'client'), - ('state', '!=', 'cancel'), - ]) - - # Also include manually mapped invoices from Invoice Mapping section - if order.x_fc_adp_invoice_id and order.x_fc_adp_invoice_id.state != 'cancel': - adp_invoices |= order.x_fc_adp_invoice_id - if order.x_fc_client_invoice_id and order.x_fc_client_invoice_id.state != 'cancel': - client_invoices |= order.x_fc_client_invoice_id - - order.x_fc_adp_invoice_count = len(adp_invoices) - order.x_fc_client_invoice_count = len(client_invoices) - - # ========================================================================== - # MOD INVOICE COUNT FIELDS (Separate MOD and Client invoices) - # ========================================================================== - x_fc_mod_invoice_count = fields.Integer( - compute='_compute_mod_invoice_counts', - string='MOD Invoices', - ) - x_fc_mod_client_invoice_count = fields.Integer( - compute='_compute_mod_invoice_counts', - string='Client Invoices (MOD)', - ) - - @api.depends('order_line') - def _compute_mod_invoice_counts(self): - """Compute separate counts for MOD and Client invoices on MOD cases.""" - AccountMove = self.env['account.move'].sudo() - for order in self: - if not order.x_fc_is_mod_sale: - order.x_fc_mod_invoice_count = 0 - order.x_fc_mod_client_invoice_count = 0 - continue - # MOD portion invoices (full or adp = MOD's share) - mod_invoices = AccountMove.search([ - ('x_fc_source_sale_order_id', '=', order.id), - ('x_fc_adp_invoice_portion', 'in', ('full', 'adp')), - ('state', '!=', 'cancel'), - ]) - # Client portion invoices - client_invoices = AccountMove.search([ - ('x_fc_source_sale_order_id', '=', order.id), - ('x_fc_adp_invoice_portion', '=', 'client'), - ('state', '!=', 'cancel'), - ]) - order.x_fc_mod_invoice_count = len(mod_invoices) - order.x_fc_mod_client_invoice_count = len(client_invoices) - - def action_view_mod_invoices(self): - """Open MOD portion invoices for this order.""" - self.ensure_one() - invoices = self.env['account.move'].sudo().search([ - ('x_fc_source_sale_order_id', '=', self.id), - ('x_fc_adp_invoice_portion', 'in', ('full', 'adp')), - ('state', '!=', 'cancel'), - ]) - action = { - 'name': 'MOD Invoices', - 'type': 'ir.actions.act_window', - 'res_model': 'account.move', - 'view_mode': 'list,form', - 'domain': [('id', 'in', invoices.ids)], - 'context': {'default_move_type': 'out_invoice'}, - } - if len(invoices) == 1: - action['view_mode'] = 'form' - action['res_id'] = invoices.id - return action - - def action_view_mod_client_invoices(self): - """Open Client portion invoices for MOD cases.""" - self.ensure_one() - invoices = self.env['account.move'].sudo().search([ - ('x_fc_source_sale_order_id', '=', self.id), - ('x_fc_adp_invoice_portion', '=', 'client'), - ('state', '!=', 'cancel'), - ]) - action = { - 'name': 'Client Invoices', - 'type': 'ir.actions.act_window', - 'res_model': 'account.move', - 'view_mode': 'list,form', - 'domain': [('id', 'in', invoices.ids)], - 'context': {'default_move_type': 'out_invoice'}, - } - if len(invoices) == 1: - action['view_mode'] = 'form' - action['res_id'] = invoices.id - return action - - # ========================================================================== - # VENDOR BILL LINKING (for audit trail) - # ========================================================================== - x_fc_vendor_bill_ids = fields.Many2many( - 'account.move', - 'sale_order_vendor_bill_rel', - 'sale_order_id', - 'move_id', - string='Vendor Bills', - domain=[('move_type', '=', 'in_invoice')], - help='Vendor bills/invoices linked to this sales order for audit trail purposes.', - ) - x_fc_vendor_bill_count = fields.Integer( - compute='_compute_vendor_bill_count', - string='Vendor Bills', - ) - - @api.depends('x_fc_vendor_bill_ids') - def _compute_vendor_bill_count(self): - """Compute count of linked vendor bills.""" - for order in self: - order.x_fc_vendor_bill_count = len(order.x_fc_vendor_bill_ids) - - def action_view_vendor_bills(self): - """Open view of linked vendor bills.""" - self.ensure_one() - action = { - 'name': 'Vendor Bills', - 'type': 'ir.actions.act_window', - 'res_model': 'account.move', - 'view_mode': 'list,form', - 'domain': [('id', 'in', self.x_fc_vendor_bill_ids.ids)], - 'context': {'default_move_type': 'in_invoice'}, - } - if len(self.x_fc_vendor_bill_ids) == 1: - action['view_mode'] = 'form' - action['res_id'] = self.x_fc_vendor_bill_ids.id - return action - - # ========================================================================== - # SUBMISSION HISTORY (for tracking all submissions/resubmissions to ADP) - # ========================================================================== - x_fc_submission_history_ids = fields.One2many( - 'fusion.submission.history', - 'sale_order_id', - string='Submission History', - help='History of all submissions and resubmissions to ADP', - ) - x_fc_submission_count = fields.Integer( - string='Submissions', - compute='_compute_submission_count', - ) - - @api.depends('x_fc_submission_history_ids') - def _compute_submission_count(self): - """Compute the number of submissions for this order.""" - for order in self: - order.x_fc_submission_count = len(order.x_fc_submission_history_ids) - - def action_view_submission_history(self): - """Open the submission history for this order.""" - self.ensure_one() - return { - 'name': 'Submission History', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion.submission.history', - 'view_mode': 'list,form', - 'domain': [('sale_order_id', '=', self.id)], - 'context': {'default_sale_order_id': self.id}, - } - - # ========================================================================== - # TECHNICIAN TASKS - # ========================================================================== - x_fc_technician_task_ids = fields.One2many( - 'fusion.technician.task', - 'sale_order_id', - string='Technician Tasks', - ) - x_fc_technician_task_count = fields.Integer( - string='Tasks', - compute='_compute_technician_task_count', - ) - - @api.depends('x_fc_technician_task_ids') - def _compute_technician_task_count(self): - for order in self: - order.x_fc_technician_task_count = len(order.x_fc_technician_task_ids) - - def action_view_technician_tasks(self): - """Open the technician tasks linked to this order.""" - self.ensure_one() - action = { - 'name': 'Technician Tasks', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion.technician.task', - 'view_mode': 'list,form', - 'domain': [('sale_order_id', '=', self.id)], - 'context': {'default_sale_order_id': self.id}, - } - if len(self.x_fc_technician_task_ids) == 1: - action['view_mode'] = 'form' - action['res_id'] = self.x_fc_technician_task_ids.id - return action - - # LOANER EQUIPMENT TRACKING - # ========================================================================== - x_fc_loaner_checkout_ids = fields.One2many( - 'fusion.loaner.checkout', - 'sale_order_id', - string='Loaner Checkouts', - help='Loaner equipment checked out for this order', - ) - x_fc_loaner_count = fields.Integer( - string='Loaners', - compute='_compute_loaner_count', - ) - x_fc_active_loaner_count = fields.Integer( - string='Active Loaners', - compute='_compute_loaner_count', - ) - x_fc_has_overdue_loaner = fields.Boolean( - string='Has Overdue Loaner', - compute='_compute_loaner_count', - help='True if any active loaner is past its expected return date', - ) - - @api.depends('x_fc_loaner_checkout_ids', 'x_fc_loaner_checkout_ids.state', - 'x_fc_loaner_checkout_ids.expected_return_date') - def _compute_loaner_count(self): - """Compute loaner counts and overdue status for this order.""" - today = fields.Date.today() - for order in self: - active = order.x_fc_loaner_checkout_ids.filtered( - lambda l: l.state in ('checked_out', 'overdue', 'rental_pending') - ) - order.x_fc_loaner_count = len(order.x_fc_loaner_checkout_ids) - order.x_fc_active_loaner_count = len(active) - order.x_fc_has_overdue_loaner = any( - l.state == 'overdue' or (l.expected_return_date and l.expected_return_date < today) - for l in active - ) - - def action_view_loaners(self): - """Open the loaner checkouts for this order.""" - self.ensure_one() - action = { - 'name': 'Loaner Checkouts', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion.loaner.checkout', - 'view_mode': 'tree,form', - 'domain': [('sale_order_id', '=', self.id)], - 'context': {'default_sale_order_id': self.id}, - } - if len(self.x_fc_loaner_checkout_ids) == 1: - action['view_mode'] = 'form' - action['res_id'] = self.x_fc_loaner_checkout_ids.id - return action - - def action_checkout_loaner(self): - """Open the loaner checkout wizard.""" - self.ensure_one() - return { - 'name': 'Checkout Loaner', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion.loaner.checkout.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': { - 'default_sale_order_id': self.id, - 'default_partner_id': self.partner_id.id, - 'default_authorizer_id': self.x_fc_authorizer_id.id if self.x_fc_authorizer_id else False, - }, - } - - def action_checkin_loaner(self): - """Open the return wizard for the active loaner on this order.""" - self.ensure_one() - active_loaners = self.x_fc_loaner_checkout_ids.filtered( - lambda l: l.state in ('checked_out', 'overdue', 'rental_pending') - ) - if not active_loaners: - raise UserError("No active loaners to check in for this order.") - if len(active_loaners) == 1: - return active_loaners.action_return() - # Multiple active loaners - show the list so user can pick which one to return - return { - 'name': 'Return Loaner', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion.loaner.checkout', - 'view_mode': 'tree,form', - 'domain': [('id', 'in', active_loaners.ids)], - 'target': 'current', - } - - def action_ready_for_delivery(self): - """Open the task scheduling form to schedule a delivery task. - - Instead of a separate wizard, this opens the full technician task - form pre-filled with delivery defaults. When the task is saved, - the sale order is automatically marked as Ready for Delivery. - """ - self.ensure_one() - - # Validate the order can be marked ready for delivery - if not self._is_adp_sale(): - raise UserError("Ready for Delivery is only available for ADP sales.") - - valid_statuses = ('approved', 'approved_deduction') - if self.x_fc_early_delivery: - valid_statuses = ('submitted', 'accepted', 'approved', 'approved_deduction') - - if self.x_fc_adp_application_status not in valid_statuses: - if self.x_fc_early_delivery: - raise UserError( - "For early delivery, the application must be at least Submitted.\n" - f"Current status: {dict(self._fields['x_fc_adp_application_status'].selection).get(self.x_fc_adp_application_status)}" - ) - else: - raise UserError( - "The application must be Approved before marking Ready for Delivery.\n" - "To deliver before approval, check 'Early Delivery' first.\n" - f"Current status: {dict(self._fields['x_fc_adp_application_status'].selection).get(self.x_fc_adp_application_status)}" - ) - - return { - 'name': 'Schedule Delivery Task', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion.technician.task', - 'view_mode': 'form', - 'target': 'new', - 'context': { - 'default_task_type': 'delivery', - 'default_sale_order_id': self.id, - 'default_partner_id': self.partner_id.id, - 'default_pod_required': True, - 'mark_ready_for_delivery': True, - }, - } - - @api.depends('x_fc_sale_type') - def _compute_is_adp_sale(self): - """Compute if this is an ADP sale - only ADP or ADP/ODSP sale types.""" - for order in self: - order.x_fc_is_adp_sale = order._is_adp_sale() - - # ========================================================================== - # SALE TYPE AND CLIENT TYPE FIELDS - # ========================================================================== - x_fc_sale_type = fields.Selection( - selection=[ - ('adp', 'ADP'), - ('adp_odsp', 'ADP/ODSP'), - ('odsp', 'ODSP'), - ('wsib', 'WSIB'), - ('direct_private', 'Direct/Private'), - ('insurance', 'Insurance'), - ('march_of_dimes', 'March of Dimes'), - ('muscular_dystrophy', 'Muscular Dystrophy'), - ('other', 'Others'), - ('rental', 'Rentals'), - ('hardship', 'Hardship Funding'), - ], - string='Sale Type', - index=True, - copy=True, - tracking=True, - help='Type of sale for billing purposes. This field determines the workflow and billing rules.', - ) - - x_fc_sale_type_locked = fields.Boolean( - string='Sale Type Locked', - compute='_compute_sale_type_locked', - help='Sale type is locked after application is submitted to ADP', - ) - - @api.depends('x_fc_adp_application_status') - def _compute_sale_type_locked(self): - """Sale type is locked once application is submitted to ADP.""" - locked_statuses = [ - 'submitted', 'accepted', 'rejected', 'resubmitted', - 'approved', 'approved_deduction', 'ready_bill', 'billed', 'case_closed', - ] - for order in self: - order.x_fc_sale_type_locked = order.x_fc_adp_application_status in locked_statuses - - x_fc_client_type = fields.Selection( - selection=[ - ('REG', 'REG'), - ('ODS', 'ODS'), - ('OWP', 'OWP'), - ('ACS', 'ACS'), - ('LTC', 'LTC'), - ('SEN', 'SEN'), - ('CCA', 'CCA'), - ], - string='Client Type', - tracking=True, - help='Client type for ADP portion calculations. REG = 75%/25%, others = 100%/0%', - ) - - # Authorizer Required field - only for certain sale types - # For: odsp, direct_private, insurance, other, rental - x_fc_authorizer_required = fields.Selection( - selection=[ - ('yes', 'Yes'), - ('no', 'No'), - ], - string='Authorizer Required?', - help='For ODSP, Direct/Private, Insurance, Others, and Rentals - specify if an authorizer is needed.', - ) - - # Computed field to determine if authorizer should be shown - x_fc_show_authorizer = fields.Boolean( - compute='_compute_show_authorizer', - string='Show Authorizer', - ) - - @api.depends('x_fc_sale_type', 'x_fc_authorizer_required') - def _compute_show_authorizer(self): - """Compute whether to show the authorizer field based on sale type and authorizer_required.""" - # Sale types that require the "Authorizer Required?" question - optional_auth_types = ('odsp', 'direct_private', 'insurance', 'other', 'rental') - # Sale types where authorizer is always shown/required - always_auth_types = ('adp', 'adp_odsp', 'wsib', 'march_of_dimes', 'muscular_dystrophy') - - for order in self: - sale_type = order.x_fc_sale_type - if sale_type in always_auth_types: - # Always show authorizer for ADP-related types - order.x_fc_show_authorizer = True - elif sale_type in optional_auth_types: - # Show authorizer only if user selected "Yes" - order.x_fc_show_authorizer = order.x_fc_authorizer_required == 'yes' - else: - # No sale type selected - don't show - order.x_fc_show_authorizer = False - - # Computed field to determine if "Authorizer Required?" question should be shown - x_fc_show_authorizer_question = fields.Boolean( - compute='_compute_show_authorizer_question', - string='Show Authorizer Question', - ) - - @api.depends('x_fc_sale_type') - def _compute_show_authorizer_question(self): - """Compute whether to show the 'Authorizer Required?' field.""" - optional_auth_types = ('odsp', 'direct_private', 'insurance', 'other', 'rental') - for order in self: - order.x_fc_show_authorizer_question = order.x_fc_sale_type in optional_auth_types - - # ========================================================================== - # MARCH OF DIMES FIELDS - # ========================================================================== - x_fc_mod_status = fields.Selection( - selection=[ - ('need_to_schedule', 'Schedule Assessment'), - ('assessment_scheduled', 'Assessment Booked'), - ('assessment_completed', 'Assessment Done'), - ('processing_drawings', 'Processing Drawing'), - ('quote_submitted', 'Quote Sent'), - ('awaiting_funding', 'Awaiting Funding'), - ('funding_approved', 'Approved'), - ('funding_denied', 'Denied'), - ('contract_received', 'PCA Received'), - ('in_production', 'In Production'), - ('project_complete', 'Complete'), - ('pod_submitted', 'POD Sent'), - ('case_closed', 'Closed'), - ('on_hold', 'On Hold'), - ('cancelled', 'Cancelled'), - ], - string='MOD Status', - default='need_to_schedule', - tracking=True, - group_expand='_expand_mod_statuses', - help='March of Dimes case workflow status', - ) - - @api.model - def _expand_mod_statuses(self, states, domain): - """Return the main MOD workflow statuses for kanban columns. - Always shows core statuses; special statuses (funding_denied, on_hold, - cancelled) only appear when records exist in them.""" - main = [ - 'need_to_schedule', 'assessment_scheduled', 'assessment_completed', - 'processing_drawings', 'quote_submitted', 'awaiting_funding', - 'funding_approved', 'contract_received', 'in_production', - 'project_complete', 'pod_submitted', 'case_closed', - ] - result = list(main) - for s in (states or []): - if s and s not in result: - result.append(s) - return result - - # --- Case contacts (per-order MOD contacts) --- - x_fc_case_handler = fields.Many2one( - 'res.partner', - string='MOD Case Handler', - tracking=True, - help='March of Dimes case handler / counsellor (e.g. Barrier Free Design Counsellor)', - ) - - x_fc_case_worker = fields.Many2one( - 'res.partner', - string='Case Worker', - tracking=True, - help='Case worker assigned to this order', - ) - - x_fc_mod_contact_name = fields.Char( - string='MOD Contact Person', - tracking=True, - help='Legacy field - kept for backwards compatibility', - ) - x_fc_mod_contact_email = fields.Char( - string='Case Worker Email', - tracking=True, - help='Case worker email - assigned after funding approval. ' - 'Completion photos and POD are sent to this email.', - ) - x_fc_mod_contact_phone = fields.Char( - string='Case Worker Phone', - tracking=True, - ) - - # --- Case identifiers --- - x_fc_case_reference = fields.Char( - string='HVMP Reference Number', - tracking=True, - help='March of Dimes HVMP Reference Number (e.g. HVW38845)', - ) - x_fc_mod_vendor_code = fields.Char( - string='MOD Vendor Code', - tracking=True, - help='Vendor code assigned by March of Dimes (e.g. TRD0001662)', - ) - - # --- Key dates --- - x_fc_case_submitted = fields.Date( - string='Quote Submitted Date', - tracking=True, - help='Legacy field - kept for backwards compatibility', - ) - x_fc_case_approved = fields.Date( - string='Funding Approved Date', - tracking=True, - help='Date funding was approved by March of Dimes', - ) - x_fc_estimated_completion_date = fields.Date( - string='Estimated Completion Date', - tracking=True, - help='Estimated project completion date. Auto-calculated from weeks if funding is approved.', - ) - x_fc_mod_estimated_weeks = fields.Integer( - string='Est. Completion (Weeks)', - tracking=True, - help='Estimated completion time in weeks from funding approval date.', - ) - - @api.onchange('x_fc_mod_estimated_weeks') - def _onchange_mod_estimated_weeks(self): - """When weeks change, compute the completion date from approval date.""" - if self.x_fc_mod_estimated_weeks and self.x_fc_mod_estimated_weeks > 0: - from datetime import timedelta - base = self.x_fc_case_approved or fields.Date.today() - self.x_fc_estimated_completion_date = base + timedelta(weeks=self.x_fc_mod_estimated_weeks) - - @api.onchange('x_fc_estimated_completion_date') - def _onchange_mod_estimated_completion_date(self): - """When date changes, compute weeks from approval date.""" - if self.x_fc_estimated_completion_date: - base = self.x_fc_case_approved or fields.Date.today() - delta = self.x_fc_estimated_completion_date - base - weeks = max(1, delta.days // 7) - self.x_fc_mod_estimated_weeks = weeks - - # --- MOD Documents --- - x_fc_mod_drawing = fields.Binary( - string='Drawing', - attachment=True, - help='Technical drawing for the accessibility modification', - ) - x_fc_mod_drawing_filename = fields.Char(string='Drawing Filename') - - x_fc_mod_initial_photos = fields.Binary( - string='Initial Photos', - attachment=True, - help='Photos taken during the initial assessment', - ) - x_fc_mod_initial_photos_filename = fields.Char(string='Initial Photos Filename') - - x_fc_mod_pca_document = fields.Binary( - string='PCA Document', - attachment=True, - help='Payment Commitment Agreement from March of Dimes', - ) - x_fc_mod_pca_filename = fields.Char(string='PCA Filename') - - x_fc_mod_proof_of_delivery = fields.Binary( - string='Proof of Delivery', - attachment=True, - help='Signed proof of delivery and installation document', - ) - x_fc_mod_pod_filename = fields.Char(string='POD Filename') - - x_fc_mod_initial_payment_amount = fields.Monetary( - string='Initial Payment Amount', - currency_field='currency_id', - help='Amount received as initial payment from March of Dimes', - ) - x_fc_mod_initial_payment_date = fields.Date( - string='Initial Payment Date', - help='Date the initial payment was received', - ) - x_fc_mod_final_payment_amount = fields.Monetary( - string='Final Payment Amount', - currency_field='currency_id', - help='Final payment amount received from March of Dimes', - ) - x_fc_mod_final_payment_date = fields.Date( - string='Final Payment Date', - help='Date the final payment was received', - ) - - x_fc_mod_completion_photos = fields.Binary( - string='Completion Photos', - attachment=True, - help='Photos of the completed installation', - ) - x_fc_mod_completion_photos_filename = fields.Char(string='Completion Photos Filename') - - # Trail computed fields for MOD documents - x_fc_mod_trail_has_drawing = fields.Boolean(compute='_compute_mod_trail', string='Has Drawing') - x_fc_mod_trail_has_initial_photos = fields.Boolean(compute='_compute_mod_trail', string='Has Initial Photos') - x_fc_mod_trail_has_pca = fields.Boolean(compute='_compute_mod_trail', string='Has PCA') - x_fc_mod_trail_has_pod = fields.Boolean(compute='_compute_mod_trail', string='Has POD') - x_fc_mod_trail_has_completion_photos = fields.Boolean(compute='_compute_mod_trail', string='Has Completion Photos') - - @api.depends('x_fc_mod_drawing', 'x_fc_mod_initial_photos', 'x_fc_mod_pca_document', - 'x_fc_mod_proof_of_delivery', 'x_fc_mod_completion_photos') - def _compute_mod_trail(self): - for order in self: - order.x_fc_mod_trail_has_drawing = bool(order.x_fc_mod_drawing) - order.x_fc_mod_trail_has_initial_photos = bool(order.x_fc_mod_initial_photos) - order.x_fc_mod_trail_has_pca = bool(order.x_fc_mod_pca_document) - order.x_fc_mod_trail_has_pod = bool(order.x_fc_mod_proof_of_delivery) - order.x_fc_mod_trail_has_completion_photos = bool(order.x_fc_mod_completion_photos) - - # --- PCA terms --- - x_fc_mod_project_completion_date = fields.Date( - string='PCA Completion Deadline', - tracking=True, - help='Project Completion Date as stated in the PCA', - ) - x_fc_mod_payment_commitment = fields.Monetary( - string='Payment Commitment', - tracking=True, - currency_field='currency_id', - help='Legacy field - kept for backwards compatibility', - ) - - # --- MOD Funding --- - x_fc_mod_approved_amount = fields.Monetary( - string='MOD Approved Amount', - currency_field='currency_id', - tracking=True, - help='Amount approved by March of Dimes', - ) - x_fc_mod_approval_type = fields.Selection( - selection=[('full', 'Full Approval'), ('partial', 'Partial Approval')], - string='Approval Type', - tracking=True, - ) - - # --- Product type and production stage --- - x_fc_mod_product_type = fields.Selection( - selection=[ - ('stairlift', 'Stairlift'), - ('vpl', 'Vertical Platform Lift / Porch Lift'), - ('ceiling_lift', 'Ceiling Lift'), - ('ramp', 'Custom Ramp'), - ('bathroom', 'Bathroom Modification'), - ('other', 'Other'), - ], - string='Product Type', - tracking=True, - help='Type of accessibility product/modification for this project', - ) - - x_fc_mod_production_status = fields.Selection( - selection=[ - # --- Stairlift stages --- - ('sl_photo_survey_booked', 'Photo Survey Booked'), - ('sl_photo_survey_done', 'Photo Survey Completed'), - ('sl_sent_to_engineering', 'Sent to Engineering'), - ('sl_engineering_received', 'Engineering Drawing Received'), - ('sl_drawing_signing', 'Drawing Signing & Acceptance'), - ('sl_in_production', 'Stairlift in Production'), - ('sl_payment_processing', 'Payment Processing for Manufacturer'), - ('sl_shipping', 'Stairlift Shipping'), - ('sl_received', 'Stairlift Received'), - ('sl_install_scheduled', 'Installation Scheduled'), - ('sl_install_complete', 'Installation Complete'), - # --- VPL / Porch Lift stages --- - ('vpl_survey_complete', 'Final Survey & Marking Complete'), - ('vpl_lift_ordered', 'Lift Ordered'), - ('vpl_concrete_poured', 'Concrete Base Poured'), - ('vpl_concrete_curing', 'Concrete Curing'), - ('vpl_install_complete', 'Lift & Safety Gate Installed'), - # --- Ceiling Lift stages --- - ('cl_marking_done', 'Lift Marking Completed'), - ('cl_anchors_installed', 'Anchors Installed'), - ('cl_curing', 'Epoxy Curing (24 hrs)'), - ('cl_track_installed', 'Track & Lift Installed'), - ('cl_safety_tested', 'Safety & Deflection Tests Passed'), - ('cl_ready_for_use', 'Ready for Use'), - # --- Ramp stages --- - ('rp_permit_check', 'Checking Municipality Permit'), - ('rp_permit_obtained', 'Permit Obtained'), - ('rp_ordered', 'Ramp Ordered'), - ('rp_received', 'Ramp Received in Warehouse'), - ('rp_install_scheduled', 'Installation Scheduled'), - ('rp_install_complete', 'Installation Complete'), - # --- Bathroom Modification stages --- - ('br_demolition', 'Demolition of Existing Bathroom'), - ('br_design_changes', 'Final Design Changes Discussed'), - ('br_construction', 'Construction in Progress'), - ('br_construction_done', 'Construction Finished'), - ('br_safety_check', 'Safety Check Complete'), - ('br_ready_for_use', 'Ready for Use'), - # --- Common --- - ('completed', 'Stage Completed'), - ('on_hold', 'On Hold'), - ], - string='Production Stage', - tracking=True, - help='Detailed production/installation stage for the product', - ) - - # --- Follow-up tracking --- - x_fc_mod_last_followup_date = fields.Date( - string='Last Follow-up Date', - help='Date of the last follow-up call or email', - ) - x_fc_mod_next_followup_date = fields.Date( - string='Next Follow-up Date', - help='Scheduled date for the next follow-up', - ) - x_fc_mod_followup_count = fields.Integer( - string='Follow-up Count', - default=0, - help='Number of follow-up attempts made', - ) - x_fc_mod_followup_escalated = fields.Boolean( - string='Follow-up Escalated', - default=False, - help='True if an automatic follow-up email was sent because activity was not completed', - ) - - # --- MOD Audit Trail dates --- - x_fc_mod_assessment_scheduled_date = fields.Date(string='Assessment Scheduled', tracking=True) - x_fc_mod_assessment_completed_date = fields.Date(string='Assessment Completed', tracking=True) - x_fc_mod_drawing_submitted_date = fields.Date(string='Drawing Submitted', tracking=True) - x_fc_mod_application_submitted_date = fields.Date( - string='Application Submitted to MOD', - tracking=True, - help='Date the application/proposal was submitted to March of Dimes for funding review', - ) - x_fc_mod_pca_received_date = fields.Date(string='PCA Received', tracking=True) - x_fc_mod_production_started_date = fields.Date(string='Production Started', tracking=True) - x_fc_mod_project_completed_date = fields.Date(string='Project Completed', tracking=True) - x_fc_mod_pod_submitted_date = fields.Date(string='POD Submitted', tracking=True) - x_fc_mod_case_closed_date = fields.Date(string='Case Closed', tracking=True) - - # Trail computed booleans - x_fc_mod_trail_assessment_done = fields.Boolean(compute='_compute_mod_audit_trail') - x_fc_mod_trail_drawing_done = fields.Boolean(compute='_compute_mod_audit_trail') - x_fc_mod_trail_app_submitted = fields.Boolean(compute='_compute_mod_audit_trail') - x_fc_mod_trail_funding_approved = fields.Boolean(compute='_compute_mod_audit_trail') - x_fc_mod_trail_pca_received = fields.Boolean(compute='_compute_mod_audit_trail') - x_fc_mod_trail_production_started = fields.Boolean(compute='_compute_mod_audit_trail') - x_fc_mod_trail_project_completed = fields.Boolean(compute='_compute_mod_audit_trail') - x_fc_mod_trail_pod_sent = fields.Boolean(compute='_compute_mod_audit_trail') - x_fc_mod_trail_case_closed = fields.Boolean(compute='_compute_mod_audit_trail') - - @api.depends('x_fc_mod_assessment_completed_date', 'x_fc_mod_drawing_submitted_date', - 'x_fc_mod_application_submitted_date', 'x_fc_case_approved', - 'x_fc_mod_pca_received_date', 'x_fc_mod_production_started_date', - 'x_fc_mod_project_completed_date', 'x_fc_mod_pod_submitted_date', - 'x_fc_mod_case_closed_date') - def _compute_mod_audit_trail(self): - for order in self: - order.x_fc_mod_trail_assessment_done = bool(order.x_fc_mod_assessment_completed_date) - order.x_fc_mod_trail_drawing_done = bool(order.x_fc_mod_drawing_submitted_date) - order.x_fc_mod_trail_app_submitted = bool(order.x_fc_mod_application_submitted_date) - order.x_fc_mod_trail_funding_approved = bool(order.x_fc_case_approved) - order.x_fc_mod_trail_pca_received = bool(order.x_fc_mod_pca_received_date) - order.x_fc_mod_trail_production_started = bool(order.x_fc_mod_production_started_date) - order.x_fc_mod_trail_project_completed = bool(order.x_fc_mod_project_completed_date) - order.x_fc_mod_trail_pod_sent = bool(order.x_fc_mod_pod_submitted_date) - order.x_fc_mod_trail_case_closed = bool(order.x_fc_mod_case_closed_date) - - # --- Computed helpers --- - x_fc_show_mod_fields = fields.Boolean( - compute='_compute_show_mod_fields', - string='Show MOD Fields', - ) - x_fc_is_mod_sale = fields.Boolean( - compute='_compute_is_mod_sale', - string='Is MOD Sale', - ) - - @api.depends('x_fc_sale_type') - def _compute_show_mod_fields(self): - """Compute whether to show March of Dimes case fields.""" - for order in self: - order.x_fc_show_mod_fields = order.x_fc_sale_type == 'march_of_dimes' - - @api.depends('x_fc_sale_type') - def _compute_is_mod_sale(self): - """Compute if this is a March of Dimes sale.""" - for order in self: - order.x_fc_is_mod_sale = order.x_fc_sale_type == 'march_of_dimes' - - def _is_mod_sale(self): - """Helper: check if this order is a March of Dimes sale.""" - self.ensure_one() - return self.x_fc_sale_type == 'march_of_dimes' - - # ========================================================================== - # ODSP (Ontario Disability Support Program) FIELDS - # ========================================================================== - x_fc_odsp_division = fields.Selection( - selection=[ - ('standard', 'ODSP Standard'), - ('sa_mobility', 'SA Mobility'), - ('ontario_works', 'Ontario Works'), - ], - string='ODSP Division', - tracking=True, - help='ODSP sub-division handling this case', - ) - x_fc_is_odsp_sale = fields.Boolean( - compute='_compute_is_odsp_sale', - store=True, - string='Is ODSP Sale', - help='True when sale type is ODSP or ADP-ODSP', - ) - x_fc_odsp_member_id = fields.Char( - related='partner_id.x_fc_odsp_member_id', - string='ODSP Member ID', - readonly=False, - store=True, - help='ODSP Member ID from contact (editable per order)', - ) - x_fc_odsp_office_id = fields.Many2one( - 'res.partner', - string='ODSP Office', - tracking=True, - domain="[('x_fc_contact_type', '=', 'odsp_office')]", - help='ODSP office handling this case', - ) - x_fc_odsp_case_worker_name = fields.Char( - string='ODSP Case Worker', - tracking=True, - help='Case worker name for this order', - ) - - # --- SA Mobility status --- - x_fc_sa_status = fields.Selection( - selection=[ - ('quotation', 'Quotation'), - ('form_ready', 'SA Form Ready'), - ('submitted_to_sa', 'Submitted to SA Mobility'), - ('pre_approved', 'Pre-Approved'), - ('ready_delivery', 'Ready for Delivery'), - ('delivered', 'Delivered'), - ('pod_submitted', 'POD Submitted'), - ('payment_received', 'Payment Received'), - ('case_closed', 'Case Closed'), - ('on_hold', 'On Hold'), - ('cancelled', 'Cancelled'), - ('denied', 'Denied'), - ], - string='SA Mobility Status', - default='quotation', - tracking=True, - group_expand='_expand_sa_statuses', - ) - - @api.model - def _expand_sa_statuses(self, states, domain): - main = [ - 'quotation', 'form_ready', 'submitted_to_sa', - 'pre_approved', 'ready_delivery', 'delivered', - 'pod_submitted', 'payment_received', 'case_closed', - ] - result = list(main) - for s in (states or []): - if s and s not in result: - result.append(s) - return result - - # --- Standard ODSP status --- - x_fc_odsp_std_status = fields.Selection( - selection=[ - ('quotation', 'Quotation'), - ('submitted_to_odsp', 'Submitted to ODSP'), - ('pre_approved', 'Pre-Approved'), - ('ready_delivery', 'Ready for Delivery'), - ('delivered', 'Delivered'), - ('pod_submitted', 'POD Submitted'), - ('payment_received', 'Payment Received'), - ('case_closed', 'Case Closed'), - ('on_hold', 'On Hold'), - ('cancelled', 'Cancelled'), - ('denied', 'Denied'), - ], - string='ODSP Status', - default='quotation', - tracking=True, - group_expand='_expand_odsp_std_statuses', - ) - - @api.model - def _expand_odsp_std_statuses(self, states, domain): - main = [ - 'quotation', 'submitted_to_odsp', - 'pre_approved', 'ready_delivery', 'delivered', - 'pod_submitted', 'payment_received', 'case_closed', - ] - result = list(main) - for s in (states or []): - if s and s not in result: - result.append(s) - return result - - # --- Ontario Works status --- - x_fc_ow_status = fields.Selection( - selection=[ - ('quotation', 'Quotation'), - ('documents_ready', 'Documents Ready'), - ('submitted_to_ow', 'Submitted to Ontario Works'), - ('payment_received', 'Payment Received'), - ('ready_delivery', 'Ready for Delivery'), - ('delivered', 'Delivered'), - ('case_closed', 'Case Closed'), - ('on_hold', 'On Hold'), - ('cancelled', 'Cancelled'), - ('denied', 'Denied'), - ], - string='Ontario Works Status', - default='quotation', - tracking=True, - group_expand='_expand_ow_statuses', - ) - - @api.model - def _expand_ow_statuses(self, states, domain): - main = [ - 'quotation', 'documents_ready', 'submitted_to_ow', - 'payment_received', 'ready_delivery', 'delivered', - 'case_closed', - ] - result = list(main) - for s in (states or []): - if s and s not in result: - result.append(s) - return result - - # --- Division-to-status field mapping --- - _ODSP_STATUS_FIELD_MAP = { - 'sa_mobility': 'x_fc_sa_status', - 'standard': 'x_fc_odsp_std_status', - 'ontario_works': 'x_fc_ow_status', - } - - def _get_odsp_status_field(self): - """Return the status field name for this order's division.""" - self.ensure_one() - return self._ODSP_STATUS_FIELD_MAP.get( - self.x_fc_odsp_division, 'x_fc_odsp_std_status') - - def _get_odsp_status(self): - """Return the current division-specific status value.""" - self.ensure_one() - return getattr(self, self._get_odsp_status_field(), '') or '' - - # --- ODSP computed helpers --- - x_fc_show_odsp_fields = fields.Boolean( - compute='_compute_show_odsp_fields', - string='Show ODSP Fields', - ) - - @api.depends('x_fc_sale_type') - def _compute_is_odsp_sale(self): - """Compute if this is an ODSP sale.""" - for order in self: - order.x_fc_is_odsp_sale = order.x_fc_sale_type in ('odsp', 'adp_odsp') - - @api.depends('x_fc_sale_type') - def _compute_show_odsp_fields(self): - """Compute whether to show ODSP case fields.""" - for order in self: - order.x_fc_show_odsp_fields = order.x_fc_sale_type in ('odsp', 'adp_odsp') - - def _is_odsp_sale(self): - """Helper: check if this order is an ODSP sale.""" - self.ensure_one() - return self.x_fc_sale_type in ('odsp', 'adp_odsp') - - @api.onchange('partner_id') - def _onchange_partner_odsp_case_worker(self): - """Auto-populate ODSP case worker from partner when partner changes.""" - if self.partner_id and self.partner_id.x_fc_case_worker_id: - self.x_fc_odsp_case_worker_name = self.partner_id.x_fc_case_worker_id.name - - # --- SA Mobility form data (persisted for wizard reuse) --- - x_fc_sa_relationship = fields.Selection([ - ('self', 'Self'), ('spouse', 'Spouse'), ('dependent', 'Dependent'), - ], string='SA Relationship', default='self') - x_fc_sa_device_type = fields.Selection([ - ('manual_wheelchair', 'Manual Wheelchair'), - ('high_tech_wheelchair', 'High Technology Wheelchair'), - ('mobility_scooter', 'Mobility Scooter'), - ('walker', 'Walker'), - ('lifting_device', 'Lifting Device'), - ('other', 'Other'), - ], string='SA Device Type') - x_fc_sa_device_other = fields.Char(string='SA Device Other Description') - x_fc_sa_serial_number = fields.Char(string='SA Serial Number') - x_fc_sa_year = fields.Char(string='SA Year') - x_fc_sa_make = fields.Char(string='SA Make') - x_fc_sa_model = fields.Char(string='SA Model') - x_fc_sa_warranty = fields.Boolean(string='SA Warranty in Effect') - x_fc_sa_warranty_desc = fields.Char(string='SA Warranty Description') - x_fc_sa_after_hours = fields.Boolean(string='SA After-hours Work') - x_fc_sa_request_type = fields.Selection([ - ('batteries', 'Batteries'), ('repair', 'Repair / Maintenance'), - ], string='SA Request Type', default='repair') - x_fc_sa_notes = fields.Text(string='SA Notes / Comments') - - # --- SA Mobility signature fields --- - x_fc_sa_client_name = fields.Char( - string='SA Client Name (Printed)', - help='Client printed name on SA Mobility form Page 2', - ) - x_fc_sa_client_signature = fields.Binary( - string='SA Client Signature', - help='Client signature image on SA Mobility form Page 2', - ) - x_fc_sa_client_signed_date = fields.Date( - string='SA Signed Date', - ) - x_fc_sa_signed_form = fields.Binary( - string='SA Signed Form', - help='Final signed SA Mobility PDF', - ) - x_fc_sa_signed_form_filename = fields.Char( - string='SA Signed Form Filename', - ) - x_fc_sa_physical_signed_copy = fields.Binary( - string='Physical Signed Copy', - attachment=True, - help='Upload a scanned/photographed copy of the physically signed SA Mobility form. ' - 'Use this when the client signs a paper copy instead of the digital e-signature.', - ) - x_fc_sa_physical_signed_copy_filename = fields.Char( - string='Physical Copy Filename', - ) - # --- SA Mobility approval form fields --- - x_fc_sa_approval_form = fields.Binary( - string='SA Approval Form', - help='ODSP approval PDF uploaded during pre-approval', - ) - x_fc_sa_approval_form_filename = fields.Char( - string='SA Approval Form Filename', - ) - x_fc_sa_signature_page = fields.Integer( - string='Signature Page', - default=2, - help='Page number in approval form where signature should be placed (1-indexed)', - ) - - # --- Ontario Works document fields --- - x_fc_ow_discretionary_form = fields.Binary( - string='Discretionary Benefits Form', - attachment=True, - help='Auto-populated when the Discretionary Benefits form is generated via wizard.', - ) - x_fc_ow_discretionary_form_filename = fields.Char( - string='Discretionary Form Filename', - ) - x_fc_ow_authorizer_letter = fields.Binary( - string='Authorizer Letter', - attachment=True, - help='Optional authorizer letter for this Ontario Works case.', - ) - x_fc_ow_authorizer_letter_filename = fields.Char( - string='Authorizer Letter Filename', - ) - - # --- Standard ODSP document fields --- - x_fc_odsp_approval_document = fields.Binary( - string='ODSP Approval Document', - attachment=True, - help='Upload the approval document received from ODSP.', - ) - x_fc_odsp_approval_document_filename = fields.Char( - string='Approval Document Filename', - ) - x_fc_odsp_authorizer_letter = fields.Binary( - string='Authorizer Letter', - attachment=True, - help='Optional authorizer letter for this ODSP case.', - ) - x_fc_odsp_authorizer_letter_filename = fields.Char( - string='Authorizer Letter Filename', - ) - - def action_open_sa_mobility_wizard(self): - """Open the SA Mobility form filling wizard.""" - self.ensure_one() - return { - 'name': 'SA Mobility Form', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion_claims.sa.mobility.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': {'active_id': self.id}, - } - - def action_open_discretionary_wizard(self): - """Open the Discretionary Benefits form filling wizard.""" - self.ensure_one() - return { - 'name': 'Discretionary Benefits Form', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion_claims.discretionary.benefit.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': {'active_id': self.id}, - } - - def action_open_submit_to_odsp_wizard(self): - """Open the Submit to ODSP wizard (quotation + authorizer letter).""" - self.ensure_one() - return { - 'name': 'Submit to ODSP', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion_claims.submit.to.odsp.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': {'active_id': self.id}, - } - - # --- ODSP workflow step actions --- - - def _odsp_advance_status(self, new_status, log_message): - """Advance the division-specific ODSP status and log to chatter.""" - self.ensure_one() - field = self._get_odsp_status_field() - setattr(self, field, new_status) - self.message_post(body=log_message, message_type='comment') - - def action_odsp_submitted(self): - self.ensure_one() - self._odsp_advance_status('submitted_to_odsp', "Application submitted to ODSP.") - - def action_odsp_submitted_ow(self): - self.ensure_one() - self._odsp_advance_status('submitted_to_ow', "Application submitted to Ontario Works.") - - def action_odsp_pre_approved(self): - self.ensure_one() - if self.x_fc_odsp_division in ('sa_mobility', 'standard'): - return { - 'type': 'ir.actions.act_window', - 'name': 'Upload ODSP Approval Document', - 'res_model': 'fusion_claims.odsp.pre.approved.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': {'active_id': self.id}, - } - self._odsp_advance_status('pre_approved', "ODSP pre-approval received.") - - def action_odsp_ready_delivery(self): - self.ensure_one() - if self.x_fc_odsp_division == 'sa_mobility' and self.x_fc_sa_approval_form: - return { - 'type': 'ir.actions.act_window', - 'name': 'Ready for Delivery - Signature Setup', - 'res_model': 'fusion_claims.odsp.ready.delivery.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': {'active_id': self.id}, - } - if self.x_fc_odsp_division in ('ontario_works', 'standard'): - return { - 'name': 'Schedule Delivery Task', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion.technician.task', - 'view_mode': 'form', - 'target': 'new', - 'context': { - 'default_task_type': 'delivery', - 'default_sale_order_id': self.id, - 'default_partner_id': self.partner_id.id, - 'default_pod_required': True, - 'mark_odsp_ready_for_delivery': True, - }, - } - self._odsp_advance_status('ready_delivery', "Order is ready for delivery.") - - def action_odsp_delivered(self): - self.ensure_one() - if self.x_fc_odsp_division == 'sa_mobility': - has_signed_form = self.x_fc_sa_signed_form or self.x_fc_sa_physical_signed_copy - if has_signed_form: - self._odsp_advance_status('delivered', - "Delivery completed. SA form is signed.") - else: - self._odsp_advance_status('delivered', "Delivery completed.") - else: - self._odsp_advance_status('delivered', "Delivery completed.") - - def action_odsp_pod_submitted(self): - self.ensure_one() - if self.x_fc_odsp_division == 'sa_mobility': - self._sa_mobility_submit_documents() - elif self.x_fc_odsp_division == 'standard': - self._odsp_std_submit_documents() - self._odsp_advance_status('pod_submitted', "Proof of Delivery submitted to ODSP.") - - def _sa_mobility_submit_documents(self): - """Collect signed SA form, internal POD, and invoice, then email to SA Mobility.""" - self.ensure_one() - import base64 - Attachment = self.env['ir.attachment'].sudo() - att_ids = [] - att_names = [] - - # 1. Signed SA Form -- reuse existing attachment created by attachment=True - signed_field = 'x_fc_sa_signed_form' if self.x_fc_sa_signed_form else ( - 'x_fc_sa_physical_signed_copy' if self.x_fc_sa_physical_signed_copy else None) - if signed_field: - att = Attachment.search([ - ('res_model', '=', 'sale.order'), - ('res_id', '=', self.id), - ('res_field', '=', signed_field), - ], order='id desc', limit=1) - if att: - att_ids.append(att.id) - att_names.append('Signed SA Form') - - # 2. Internal POD -- generate on-the-fly from the standard report - try: - pod_pdf, pod_fname = self._get_sa_pod_pdf() - att = Attachment.create({ - 'name': pod_fname, - 'type': 'binary', - 'datas': base64.b64encode(pod_pdf), - 'res_model': 'sale.order', - 'res_id': self.id, - }) - att_ids.append(att.id) - att_names.append('Proof of Delivery') - except Exception as e: - _logger.warning("Could not generate POD PDF for %s: %s", self.name, e) - - # 3. Invoice PDF -- generate from the latest posted invoice - invoices = self.invoice_ids.filtered(lambda inv: inv.state == 'posted') - if invoices: - invoice = invoices[0] - try: - report = self.env.ref('account.account_invoices') - pdf_content, _ct = report._render_qweb_pdf(report.id, [invoice.id]) - att = Attachment.create({ - 'name': f'Invoice_{invoice.name}.pdf', - 'type': 'binary', - 'datas': base64.b64encode(pdf_content), - 'res_model': 'sale.order', - 'res_id': self.id, - }) - att_ids.append(att.id) - att_names.append(f'Invoice ({invoice.name})') - except Exception as e: - _logger.warning("Could not generate invoice PDF for %s: %s", self.name, e) - - self._send_sa_mobility_completion_email(attachment_ids=att_ids) - - if att_names: - self.message_post( - body=Markup( - '
      ' - 'Documents submitted to SA Mobility' - '
        ' - + ''.join(f'
      • {n}
      • ' for n in att_names) - + '
      ' - ), - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - - def _odsp_std_submit_documents(self): - """Standard ODSP: collect approval doc, POD, and invoice, then email to ODSP office.""" - self.ensure_one() - import base64 - Attachment = self.env['ir.attachment'].sudo() - att_ids = [] - att_names = [] - - # 1. Approval document - if self.x_fc_odsp_approval_document: - att = Attachment.search([ - ('res_model', '=', 'sale.order'), - ('res_id', '=', self.id), - ('res_field', '=', 'x_fc_odsp_approval_document'), - ], order='id desc', limit=1) - if att: - att_ids.append(att.id) - att_names.append('ODSP Approval Document') - - # 2. Internal POD - try: - pod_pdf, pod_fname = self._get_sa_pod_pdf() - att = Attachment.create({ - 'name': pod_fname, - 'type': 'binary', - 'datas': base64.b64encode(pod_pdf), - 'res_model': 'sale.order', - 'res_id': self.id, - }) - att_ids.append(att.id) - att_names.append('Proof of Delivery') - except Exception as e: - _logger.warning("Could not generate POD PDF for %s: %s", self.name, e) - - # 3. Invoice PDF - invoices = self.invoice_ids.filtered(lambda inv: inv.state == 'posted') - if not invoices: - if self.state != 'sale': - self.action_confirm() - invoices = self._create_invoices() - invoices.write({'x_fc_source_sale_order_id': self.id}) - if invoices: - invoice = invoices[0] - try: - report = self.env.ref('account.account_invoices') - pdf_content, _ct = report._render_qweb_pdf(report.id, [invoice.id]) - att = Attachment.create({ - 'name': f'Invoice_{invoice.name}.pdf', - 'type': 'binary', - 'datas': base64.b64encode(pdf_content), - 'res_model': 'sale.order', - 'res_id': self.id, - }) - att_ids.append(att.id) - att_names.append(f'Invoice ({invoice.name})') - except Exception as e: - _logger.warning("Could not generate invoice PDF for %s: %s", self.name, e) - - self._send_odsp_submission_email(attachment_ids=att_ids) - - if att_names: - self.message_post( - body=Markup( - '
      ' - 'Documents submitted to ODSP' - '
        ' - + ''.join(f'
      • {n}
      • ' for n in att_names) - + '
      ' - ), - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - - def action_odsp_payment_received(self): - self.ensure_one() - if self.x_fc_odsp_division == 'ontario_works': - return self._ow_payment_create_invoice() - self._odsp_advance_status('payment_received', "Payment received from ODSP.") - - def _ow_payment_create_invoice(self): - """Ontario Works: create invoice from SO, advance status, open invoice.""" - self.ensure_one() - if self.state != 'sale': - self.action_confirm() - - invoice = self._create_invoices() - invoice.write({'x_fc_source_sale_order_id': self.id}) - - self._odsp_advance_status('payment_received', - "Ontario Works payment confirmed. Invoice %s created." % invoice.name) - - return { - 'type': 'ir.actions.act_window', - 'name': 'Invoice', - 'res_model': 'account.move', - 'view_mode': 'form', - 'res_id': invoice.id, - 'target': 'current', - } - - def action_odsp_close_case(self): - self.ensure_one() - self._odsp_advance_status('case_closed', "ODSP case closed.") - - def action_odsp_on_hold(self): - self.ensure_one() - self._odsp_advance_status('on_hold', "ODSP case placed on hold.") - - def action_odsp_resume(self): - """Resume from on_hold -- go back to the previous logical status.""" - self.ensure_one() - self._odsp_advance_status('quotation', "ODSP case resumed.") - - def action_odsp_denied(self): - self.ensure_one() - self._odsp_advance_status('denied', "ODSP application denied.") - - def action_sign_sa_mobility_form(self): - """Overlay client signature onto Page 2 of the approved SA Mobility form. - - Uses the PDFTemplateFiller overlay approach: - - Reads the last attached SA Mobility form - - Overlays client printed name, signature image, and date on Page 2 - - Stores result in x_fc_sa_signed_form - """ - self.ensure_one() - if not self.x_fc_sa_client_signature: - from odoo.exceptions import UserError - raise UserError("Client signature is required to sign the SA Mobility form.") - - # Find the most recent SA Mobility form attachment - attachment = self.env['ir.attachment'].search([ - ('res_model', '=', 'sale.order'), - ('res_id', '=', self.id), - ('name', 'like', 'SA_Mobility_Form_'), - ], order='create_date desc', limit=1) - - if not attachment: - from odoo.exceptions import UserError - raise UserError("No SA Mobility form found. Please fill the form first.") - - import base64 - from io import BytesIO - try: - from reportlab.pdfgen import canvas as rl_canvas - from reportlab.lib.utils import ImageReader - from odoo.tools.pdf import PdfFileReader, PdfFileWriter - except ImportError: - from odoo.exceptions import UserError - raise UserError("Required PDF libraries not available.") - - # Read the existing filled form - pdf_bytes = base64.b64decode(attachment.datas) - original = PdfFileReader(BytesIO(pdf_bytes)) - output = PdfFileWriter() - num_pages = original.getNumPages() - - for page_idx in range(num_pages): - page = original.getPage(page_idx) - - if page_idx == 1: # Page 2 (0-based index) - page_w = float(page.mediaBox.getWidth()) - page_h = float(page.mediaBox.getHeight()) - - overlay_buf = BytesIO() - c = rl_canvas.Canvas(overlay_buf, pagesize=(page_w, page_h)) - - # Text103 area - client printed name (upper confirmation line) - if self.x_fc_sa_client_name: - c.setFont('Helvetica', 11) - c.drawString(180, page_h - 180, self.x_fc_sa_client_name) - - # Text104 area - printed name on lower line - if self.x_fc_sa_client_name: - c.setFont('Helvetica', 11) - c.drawString(72, page_h - 560, self.x_fc_sa_client_name) - - # Text105 area - date - if self.x_fc_sa_client_signed_date: - from odoo import fields as odoo_fields - date_str = odoo_fields.Date.to_string(self.x_fc_sa_client_signed_date) - c.setFont('Helvetica', 11) - c.drawString(350, page_h - 560, date_str) - - # Signature image overlay on the signature line - if self.x_fc_sa_client_signature: - sig_data = base64.b64decode(self.x_fc_sa_client_signature) - sig_image = ImageReader(BytesIO(sig_data)) - c.drawImage(sig_image, 72, page_h - 540, width=200, height=50, - preserveAspectRatio=True, mask='auto') - - c.save() - overlay_buf.seek(0) - overlay_pdf = PdfFileReader(overlay_buf) - page.mergePage(overlay_pdf.getPage(0)) - - output.addPage(page) - - result_buf = BytesIO() - output.write(result_buf) - signed_pdf = result_buf.getvalue() - - filename = f'SA_Mobility_Signed_{self.name}.pdf' - self.write({ - 'x_fc_sa_signed_form': base64.b64encode(signed_pdf), - 'x_fc_sa_signed_form_filename': filename, - }) - - self.message_post( - body="SA Mobility form signed by client: %s" % self.x_fc_sa_client_name, - message_type='comment', - ) - - return {'type': 'ir.actions.act_window_close'} - - def _apply_pod_signature_to_approval_form(self): - """Auto-overlay POD signature onto the ODSP approval form. - - Uses the ODSP PDF Template (fusion.pdf.template, category=odsp) for - field positions, and the per-case signature page number. - """ - self.ensure_one() - if not all([ - self.x_fc_odsp_division == 'sa_mobility', - self.x_fc_sa_approval_form, - self.x_fc_sa_signature_page, - self.x_fc_pod_signature, - ]): - return - - import base64 - from odoo.addons.fusion_authorizer_portal.utils.pdf_filler import PDFTemplateFiller - - tpl = self.env['fusion.pdf.template'].search([ - ('category', '=', 'odsp'), ('state', '=', 'active'), - ], limit=1) - if not tpl: - _logger.warning("No active ODSP PDF template found for signing %s", self.name) - return - - sig_page = self.x_fc_sa_signature_page or 2 - - fields_by_page = {} - for field in tpl.field_ids.filtered(lambda f: f.is_active): - page = sig_page - if page not in fields_by_page: - fields_by_page[page] = [] - fields_by_page[page].append({ - 'field_name': field.name, - 'field_key': field.field_key or field.name, - 'pos_x': field.pos_x, - 'pos_y': field.pos_y, - 'width': field.width, - 'height': field.height, - 'field_type': field.field_type, - 'font_size': field.font_size, - 'font_name': field.font_name or 'Helvetica', - 'text_align': field.text_align or 'left', - }) - - client_name = self.x_fc_pod_client_name or self.x_fc_sa_client_name or self.partner_id.name or '' - sign_date = self.x_fc_pod_signature_date or self.x_fc_sa_client_signed_date - context_data = { - 'sa_client_name': client_name, - 'sa_sign_date': sign_date.strftime('%b %d, %Y') if sign_date else '', - } - signatures = { - 'sa_signature': base64.b64decode(self.x_fc_pod_signature), - } - - pdf_bytes = base64.b64decode(self.x_fc_sa_approval_form) - try: - signed_pdf = PDFTemplateFiller.fill_template( - pdf_bytes, fields_by_page, context_data, signatures, - ) - except Exception as e: - _logger.error("Failed to apply signature to approval form for %s: %s", self.name, e) - return - - filename = f'SA_Approval_Signed_{self.name}.pdf' - self.with_context(skip_pod_signature_hook=True).write({ - 'x_fc_sa_signed_form': base64.b64encode(signed_pdf), - 'x_fc_sa_signed_form_filename': filename, - }) - - att = self.env['ir.attachment'].create({ - 'name': filename, - 'type': 'binary', - 'datas': base64.b64encode(signed_pdf), - 'res_model': 'sale.order', - 'res_id': self.id, - 'mimetype': 'application/pdf', - }) - self.message_post( - body="POD signature applied to ODSP approval form (page %s)." % sig_page, - message_type='comment', - attachment_ids=[att.id], - ) - _logger.info("POD signature applied to approval form for %s", self.name) - - # ========================================================================== - # DELIVERY STATUS FIELDS - # ========================================================================== - x_fc_delivery_status = fields.Selection( - selection=[ - ('waiting', 'Waiting'), - ('waiting_approval', 'Waiting for Approval'), - ('ready', 'Ready for Delivery'), - ('scheduled', 'Delivery Scheduled'), - ('shipped_warehouse', 'Shipped to Warehouse'), - ('received_warehouse', 'Received in Warehouse'), - ('delivered', 'Delivered'), - ('hold', 'Hold'), - ('cancelled', 'Cancelled'), - ], - string='Delivery Status', - tracking=True, - help='Current delivery status of the order', - ) - - x_fc_delivery_datetime = fields.Datetime( - string='Delivery Date & Time', - tracking=True, - help='Scheduled or actual delivery date and time', - ) - - # Computed field to show/hide delivery datetime - x_fc_show_delivery_datetime = fields.Boolean( - compute='_compute_show_delivery_datetime', - string='Show Delivery DateTime', - ) - - @api.depends('x_fc_delivery_status') - def _compute_show_delivery_datetime(self): - """Compute whether to show delivery datetime field.""" - for order in self: - order.x_fc_show_delivery_datetime = order.x_fc_delivery_status in ('scheduled', 'delivered') - - # ========================================================================== - # ADP CLAIM FIELDS - # ========================================================================== - x_fc_claim_number = fields.Char( - string='Claim Number', - tracking=True, - copy=False, - help='ADP Claim Number assigned after submission', - ) - x_fc_client_ref_1 = fields.Char( - string='Client Reference 1', - help='Primary client reference (e.g., Health Card Number)', - ) - x_fc_client_ref_2 = fields.Char( - string='Client Reference 2', - help='Secondary client reference', - ) - x_fc_adp_delivery_date = fields.Date( - string='ADP Delivery Date', - help='Date the product was delivered to the client (for ADP billing)', - ) - x_fc_service_start_date = fields.Date( - string='Service Start Date', - help='Service period start date (optional, for rentals/services)', - ) - x_fc_service_end_date = fields.Date( - string='Service End Date', - help='Service period end date (optional, for rentals/services)', - ) - x_fc_authorizer_id = fields.Many2one( - 'res.partner', - string='Authorizer', - help='Authorizer contact for this order', - domain="[('is_company', '=', False)]", - ) - - x_fc_primary_serial = fields.Char( - string='Primary Serial Number', - help='Primary serial number for the order (header level). ' - 'Line-level serials are tracked on individual order lines.', - copy=False, - ) - - # ========================================================================== - # ADP WORKFLOW STATUS (Legacy - keeping for backward compatibility) - # ========================================================================== - x_fc_adp_status = fields.Selection( - selection=[ - ('quote', 'Quote'), - ('submitted', 'Submitted to ADP'), - ('approved', 'ADP Approved'), - ('client_paid', 'Client Paid (25%)'), - ('delivered', 'Delivered'), - ('billed', 'Billed to ADP (75%)'), - ('closed', 'Closed'), - ], - string='ADP Status (Legacy)', - default='quote', - tracking=True, - help='Legacy status field - use x_fc_adp_application_status instead', - ) - - # ========================================================================== - # ADP APPLICATION STATUS (New comprehensive status field) - # ========================================================================== - x_fc_adp_application_status = fields.Selection( - selection=[ - ('quotation', 'Quotation Stage'), - ('assessment_scheduled', 'Assessment Scheduled'), - ('assessment_completed', 'Assessment Completed'), - ('waiting_for_application', 'Waiting for Application'), - ('application_received', 'Application Received'), - ('ready_submission', 'Ready for Submission'), - ('submitted', 'Application Submitted'), - ('accepted', 'Accepted by ADP'), # New: ADP accepted submission (within 24 hours) - ('rejected', 'Rejected by ADP'), # New: ADP rejected submission (errors, need correction) - ('resubmitted', 'Application Resubmitted'), - ('needs_correction', 'Application Needs Correction'), - ('approved', 'Application Approved'), - ('approved_deduction', 'Approved with Deduction'), - ('ready_delivery', 'Ready for Delivery'), # After approved OR when early delivery - ('denied', 'Application Denied'), - ('withdrawn', 'Application Withdrawn'), - ('ready_bill', 'Ready to Bill'), - ('billed', 'Billed to ADP'), - ('case_closed', 'Case Closed'), - ('on_hold', 'On Hold'), - ('cancelled', 'Cancelled'), - ('expired', 'Application Expired'), - ], - string='ADP Application Status', - default='quotation', - tracking=True, - copy=False, - group_expand='_expand_adp_application_statuses', - help='Comprehensive ADP application workflow status', - ) - - @api.model - def _expand_adp_application_statuses(self, states, domain): - """Return the main workflow statuses for kanban columns. - Always shows core statuses; special statuses (on_hold, denied, etc.) - only appear when records exist in them.""" - main = [ - 'quotation', 'assessment_scheduled', 'waiting_for_application', - 'application_received', 'ready_submission', 'submitted', - 'needs_correction', 'approved', 'ready_delivery', - 'ready_bill', 'billed', 'case_closed', - ] - # Also include any special status that currently has records - result = list(main) - for s in (states or []): - if s and s not in result: - result.append(s) - return result - - x_fc_status_sequence = fields.Integer( - string='Status Sequence', - compute='_compute_status_sequence', - store=True, - index=True, - help='Numeric workflow order for sorting when grouping by status', - ) - - _STATUS_ORDER = { - 'quotation': 10, - 'assessment_scheduled': 20, - 'assessment_completed': 30, - 'waiting_for_application': 40, - 'application_received': 50, - 'ready_submission': 60, - 'submitted': 70, - 'accepted': 80, - 'rejected': 85, - 'resubmitted': 75, - 'needs_correction': 65, - 'approved': 90, - 'approved_deduction': 91, - 'ready_delivery': 95, - 'ready_bill': 100, - 'billed': 110, - 'case_closed': 120, - 'on_hold': 130, - 'denied': 140, - 'withdrawn': 150, - 'cancelled': 160, - 'expired': 170, - } - - @api.depends('x_fc_adp_application_status') - def _compute_status_sequence(self): - for order in self: - order.x_fc_status_sequence = self._STATUS_ORDER.get( - order.x_fc_adp_application_status, 999 - ) - - @api.model - def _read_group(self, domain, groupby=(), aggregates=(), having=(), offset=0, limit=None, order=None): - """Override to sort groups by workflow order when grouping by ADP status.""" - result = super()._read_group( - domain, groupby=groupby, aggregates=aggregates, - having=having, offset=offset, limit=limit, order=order, - ) - if groupby and groupby[0] == 'x_fc_adp_application_status': - status_order = self._STATUS_ORDER - result = sorted(result, key=lambda r: status_order.get(r[0], 999)) - return result - - # ========================================================================== - # SERVICE FLAG (for service start/end date visibility) - # ========================================================================== - x_fc_has_service = fields.Boolean( - string='Is Service?', - default=False, - help='Check if this order includes a service component (shows service date fields)', - ) - - # ========================================================================== - # ON HOLD TRACKING - # ========================================================================== - x_fc_on_hold_date = fields.Date( - string='On Hold Since', - tracking=True, - help='Date when the application was put on hold', - ) - x_fc_previous_status_before_hold = fields.Char( - string='Previous Status Before Hold', - help='Status before the application was put on hold (for resuming)', - ) - - x_fc_status_before_delivery = fields.Char( - string='Status Before Delivery', - help='Status before the order was marked Ready for Delivery (for reverting if task cancelled)', - ) - - # ========================================================================== - # DELIVERY TECHNICIAN TRACKING - # ========================================================================== - x_fc_early_delivery = fields.Boolean( - string='Early Delivery', - default=False, - tracking=True, - help='Check if delivery will occur before ADP approval (client pays their portion upfront)', - ) - x_fc_delivery_technician_ids = fields.Many2many( - 'res.users', - 'sale_order_delivery_technician_rel', - 'sale_order_id', - 'user_id', - string='Delivery Technicians', - tracking=True, - help='Field technicians assigned to deliver this order', - ) - x_fc_ready_for_delivery_date = fields.Datetime( - string='Ready for Delivery Date', - tracking=True, - help='Date/time when the order was marked ready for delivery', - ) - x_fc_scheduled_delivery_datetime = fields.Datetime( - string='Scheduled Delivery', - tracking=True, - help='Scheduled date and time for delivery', - ) - - # ========================================================================== - # REJECTION REASON TRACKING (Initial rejection by ADP - within 24 hours) - # ========================================================================== - x_fc_rejection_reason = fields.Selection( - selection=[ - ('name_correction', 'Name Correction Needed'), - ('healthcard_correction', 'Health Card Correction Needed'), - ('duplicate_claim', 'Duplicate Claim Exists'), - ('xml_format_error', 'XML Format/Validation Error'), - ('missing_info', 'Missing Required Information'), - ('other', 'Other'), - ], - string='Rejection Reason', - tracking=True, - help='Reason for initial rejection by ADP (within 24 hours of submission)', - ) - x_fc_rejection_reason_other = fields.Text( - string='Rejection Details', - tracking=True, - help='Additional details when rejection reason is "Other"', - ) - x_fc_rejection_date = fields.Date( - string='Rejection Date', - tracking=True, - help='Date when ADP rejected the submission', - ) - x_fc_rejection_count = fields.Integer( - string='Rejection Count', - default=0, - help='Number of times this application has been rejected by ADP', - ) - - # ========================================================================== - # DENIAL REASON TRACKING (Funding denied after review - 2-3 weeks) - # ========================================================================== - x_fc_denial_reason = fields.Selection( - selection=[ - ('eligibility', 'Client Eligibility Issues'), - ('recent_funding', 'Previous Funding Within 5 Years'), - ('medical_justification', 'Insufficient Medical Justification'), - ('equipment_not_covered', 'Equipment Not Covered by ADP'), - ('documentation_incomplete', 'Documentation Incomplete'), - ('other', 'Other'), - ], - string='Denial Reason', - tracking=True, - help='Reason for denial of funding by ADP (after 2-3 week review)', - ) - x_fc_denial_reason_other = fields.Text( - string='Denial Details', - tracking=True, - help='Additional details when denial reason is "Other"', - ) - x_fc_denial_date = fields.Date( - string='Denial Date', - tracking=True, - help='Date when ADP denied the funding', - ) - - # ========================================================================== - # EMAIL NOTIFICATION TRACKING - # ========================================================================== - x_fc_application_reminder_sent = fields.Boolean( - string='Application Reminder Sent', - default=False, - copy=False, - help='Whether the first application reminder email has been sent', - ) - x_fc_application_reminder_2_sent = fields.Boolean( - string='Application Reminder 2 Sent', - default=False, - copy=False, - help='Whether the second application reminder email has been sent', - ) - x_fc_acceptance_reminder_sent = fields.Boolean( - string='Acceptance Reminder Sent', - default=False, - copy=False, - help='Whether the acceptance reminder email has been sent for submitted orders', - ) - - # ========================================================================== - # VALIDITY & EXPIRY TRACKING - # ========================================================================== - x_fc_assessment_validity_days = fields.Integer( - string='Assessment Validity (Days)', - compute='_compute_validity_expiry', - help='Days remaining before assessment expires (valid for 3 months)', - ) - x_fc_assessment_expired = fields.Boolean( - string='Assessment Expired', - compute='_compute_validity_expiry', - help='True if assessment is more than 3 months old', - ) - x_fc_approval_expiry_days = fields.Integer( - string='Approval Expiry (Days)', - compute='_compute_validity_expiry', - help='Days remaining before approval expires (valid for 6 months)', - ) - x_fc_approval_expired = fields.Boolean( - string='Approval Expired', - compute='_compute_validity_expiry', - help='True if approval is more than 6 months old', - ) - x_fc_billing_warning = fields.Boolean( - string='Billing Warning', - compute='_compute_validity_expiry', - help='True if more than 1 year since approval (verbal ADP permission needed)', - ) - x_fc_show_expiry_card = fields.Boolean( - string='Show Expiry Card', - compute='_compute_validity_expiry', - help='True if expiry card should be shown', - ) - - @api.depends('x_fc_assessment_end_date', 'x_fc_claim_approval_date', 'x_fc_adp_application_status', 'x_fc_claim_number') - def _compute_validity_expiry(self): - """Compute validity and expiry information for assessments and approvals.""" - from datetime import date as date_class - today = date_class.today() - - # Statuses that show expiry card - expiry_card_statuses = ['approved', 'approved_deduction', 'on_hold'] - - for order in self: - # Assessment validity (3 months = 90 days) - if order.x_fc_assessment_end_date: - days_since_assessment = (today - order.x_fc_assessment_end_date).days - order.x_fc_assessment_validity_days = max(0, 90 - days_since_assessment) - order.x_fc_assessment_expired = days_since_assessment > 90 - else: - order.x_fc_assessment_validity_days = 0 - order.x_fc_assessment_expired = False - - # Approval expiry (6 months = 180 days) - if order.x_fc_claim_approval_date: - days_since_approval = (today - order.x_fc_claim_approval_date).days - order.x_fc_approval_expiry_days = max(0, 180 - days_since_approval) - order.x_fc_approval_expired = days_since_approval > 180 - # Billing warning (1 year = 365 days) - order.x_fc_billing_warning = days_since_approval > 365 - else: - order.x_fc_approval_expiry_days = 0 - order.x_fc_approval_expired = False - order.x_fc_billing_warning = False - - # Show expiry card for approved/approved_deduction/on_hold (with claim number) - status = order.x_fc_adp_application_status - if status in expiry_card_statuses and order.x_fc_claim_approval_date: - # For on_hold, only show if has claim number - if status == 'on_hold': - order.x_fc_show_expiry_card = bool(order.x_fc_claim_number) - else: - order.x_fc_show_expiry_card = True - else: - order.x_fc_show_expiry_card = False - - # ========================================================================== - # WORKFLOW STAGE FLAGS (computed for view visibility) - # ========================================================================== - x_fc_stage_after_assessment_initiated = fields.Boolean( - compute='_compute_workflow_stages', - string='After Assessment Initiated Stage', - ) - x_fc_stage_after_assessment_completed = fields.Boolean( - compute='_compute_workflow_stages', - string='After Assessment Completed Stage', - ) - x_fc_stage_after_application_received = fields.Boolean( - compute='_compute_workflow_stages', - string='After Application Received Stage', - ) - x_fc_stage_after_ready_submission = fields.Boolean( - compute='_compute_workflow_stages', - string='After Ready Submission Stage', - ) - x_fc_stage_after_submitted = fields.Boolean( - compute='_compute_workflow_stages', - string='After Submitted Stage', - ) - x_fc_stage_after_accepted = fields.Boolean( - compute='_compute_workflow_stages', - string='After Accepted Stage', - ) - x_fc_stage_after_approved = fields.Boolean( - compute='_compute_workflow_stages', - string='After Approved Stage', - ) - x_fc_stage_after_ready_bill = fields.Boolean( - compute='_compute_workflow_stages', - string='After Ready Bill Stage', - ) - x_fc_stage_after_billed = fields.Boolean( - compute='_compute_workflow_stages', - string='After Billed Stage', - ) - x_fc_requires_previous_funding = fields.Boolean( - compute='_compute_workflow_stages', - string='Requires Previous Funding Date', - ) - - @api.depends('x_fc_adp_application_status', 'x_fc_reason_for_application') - def _compute_workflow_stages(self): - """Compute workflow stage flags for conditional visibility in views. - - Terminal statuses (cancelled, denied, withdrawn, expired) should NOT make - later-stage fields required - only 'on_hold' preserves field requirements - since the case can resume. - """ - # Terminal statuses - these end the workflow, no further fields required - terminal_statuses = ['cancelled', 'denied', 'withdrawn', 'expired'] - - # On-hold preserves visibility but we handle it specially - # so fields remain visible but not required - - # Define status groups - each list includes the starting status and all subsequent - after_assessment_initiated_statuses = [ - 'assessment_scheduled', 'assessment_completed', 'waiting_for_application', - 'application_received', - 'ready_submission', 'submitted', 'accepted', 'rejected', 'resubmitted', 'needs_correction', - 'approved', 'approved_deduction', - 'ready_bill', 'billed', 'case_closed', 'on_hold', - ] - - after_assessment_completed_statuses = [ - 'assessment_completed', 'waiting_for_application', 'application_received', - 'ready_submission', - 'submitted', 'accepted', 'rejected', 'resubmitted', 'needs_correction', - 'approved', 'approved_deduction', - 'ready_bill', 'billed', 'case_closed', 'on_hold', - ] - - after_application_received_statuses = [ - 'application_received', 'ready_submission', 'submitted', 'accepted', 'rejected', - 'resubmitted', 'needs_correction', 'approved', 'approved_deduction', - 'ready_bill', 'billed', 'case_closed', 'on_hold', - ] - - after_ready_submission_statuses = [ - 'ready_submission', 'submitted', 'accepted', 'rejected', 'resubmitted', 'needs_correction', - 'approved', 'approved_deduction', - 'ready_bill', 'billed', 'case_closed', 'on_hold', - ] - - after_submitted_statuses = [ - 'submitted', 'accepted', 'rejected', 'resubmitted', 'needs_correction', - 'approved', 'approved_deduction', - 'ready_bill', 'billed', 'case_closed', 'on_hold', - ] - - # New: After accepted by ADP (waiting for approval decision) - after_accepted_statuses = [ - 'accepted', 'approved', 'approved_deduction', - 'ready_bill', 'billed', 'case_closed', 'on_hold', - ] - - after_approved_statuses = [ - 'approved', 'approved_deduction', 'ready_bill', 'billed', 'case_closed', - 'on_hold', - ] - - after_ready_bill_statuses = [ - 'ready_bill', 'billed', 'case_closed', - # NOT on_hold here - if on_hold before ready_bill, these shouldn't be required - ] - - after_billed_statuses = [ - 'billed', 'case_closed', - ] - - # Reasons that DON'T require previous funding date - no_prev_funding_reasons = ['first_access', 'mod_non_adp'] - - for order in self: - status = order.x_fc_adp_application_status or '' - reason = order.x_fc_reason_for_application or '' - - order.x_fc_stage_after_assessment_initiated = status in after_assessment_initiated_statuses - order.x_fc_stage_after_assessment_completed = status in after_assessment_completed_statuses - order.x_fc_stage_after_application_received = status in after_application_received_statuses - order.x_fc_stage_after_ready_submission = status in after_ready_submission_statuses - order.x_fc_stage_after_submitted = status in after_submitted_statuses - order.x_fc_stage_after_accepted = status in after_accepted_statuses - order.x_fc_stage_after_approved = status in after_approved_statuses - order.x_fc_stage_after_ready_bill = status in after_ready_bill_statuses - order.x_fc_stage_after_billed = status in after_billed_statuses - # Previous funding required if reason is set AND not in exempt list - order.x_fc_requires_previous_funding = bool(reason) and reason not in no_prev_funding_reasons - - # ========================================================================== - # REASON FOR APPLICATION - # ========================================================================== - x_fc_reason_for_application = fields.Selection( - selection=[ - ('first_access', 'First Time Access - NO previous ADP'), - ('additions', 'Additions'), - ('mod_non_adp', 'Modification/Upgrade - Original NOT through ADP'), - ('mod_adp', 'Modification/Upgrade - Original through ADP'), - ('replace_status', 'Replacement - Change in Status'), - ('replace_size', 'Replacement - Change in Body Size'), - ('replace_worn', 'Replacement - Worn out (past useful life)'), - ('replace_lost', 'Replacement - Lost'), - ('replace_stolen', 'Replacement - Stolen'), - ('replace_damaged', 'Replacement - Damaged beyond repair'), - ('replace_no_longer_meets', 'Replacement - No longer meets needs'), - ('growth', 'Growth/Change in condition'), - ], - string='Reason for Application', - tracking=True, - help='Reason for the ADP application - affects invoice creation rules', - ) - - x_fc_previous_funding_date = fields.Date( - string='Previous Funding Date', - tracking=True, - help='Date of previous ADP funding for replacement applications', - ) - - x_fc_years_since_funding = fields.Float( - string='Years Since Funding', - compute='_compute_years_since_funding', - store=True, - help='Number of years since previous funding', - ) - - x_fc_under_5_years = fields.Boolean( - string='Under 5 Years', - compute='_compute_years_since_funding', - store=True, - help='True if less than 5 years since previous funding (may have deductions)', - ) - - # ========================================================================== - # ADP DATE CLASSIFICATIONS (6 dates) - # ========================================================================== - x_fc_assessment_start_date = fields.Date( - string='Assessment Start Date', - tracking=True, - help='Date when the assessment started', - ) - - x_fc_assessment_end_date = fields.Date( - string='Assessment End Date', - tracking=True, - help='Date when the assessment was completed', - ) - - x_fc_claim_authorization_date = fields.Date( - string='Claim Authorization Date', - tracking=True, - help='Date when the claim was authorized by the OT/Authorizer', - ) - - x_fc_claim_submission_date = fields.Date( - string='Claim Submission Date', - tracking=True, - help='Date when the claim was submitted to ADP', - ) - - x_fc_claim_acceptance_date = fields.Date( - string='ADP Acceptance Date', - tracking=True, - help='Date when ADP accepted the submission (within 24 hours of submission)', - ) - - x_fc_claim_approval_date = fields.Date( - string='Claim Approval Date', - tracking=True, - help='Date when ADP approved the claim', - ) - - x_fc_billing_date = fields.Date( - string='Billing Date', - tracking=True, - help='Date when the ADP invoice was created/billed', - ) - - # ========================================================================== - # ADP DOCUMENT ATTACHMENTS - # ========================================================================== - x_fc_original_application = fields.Binary( - string='Original ADP Application', - attachment=True, - help='The original ADP application document received from the authorizer', - ) - x_fc_original_application_filename = fields.Char( - string='Original Application Filename', - ) - - x_fc_signed_pages_11_12 = fields.Binary( - string='Page 11 & 12 (Signed)', - attachment=True, - help='Signed pages 11 and 12 of the ADP application', - ) - x_fc_signed_pages_filename = fields.Char( - string='Signed Pages Filename', - ) - - # ========================================================================== - # PAGE 11 SIGNATURE TRACKING (Client/Agent Signature) - # Page 11 must be signed by: Client, Spouse, Parent, Legal Guardian, POA, or Public Trustee - # ========================================================================== - x_fc_page11_signer_type = fields.Selection( - selection=[ - ('client', 'Client (Self)'), - ('spouse', 'Spouse'), - ('parent', 'Parent'), - ('legal_guardian', 'Legal Guardian'), - ('poa', 'Power of Attorney'), - ('public_trustee', 'Public Trustee'), - ], - string='Page 11 Signed By', - tracking=True, - help='Who signed Page 11 of the ADP application (client consent page)', - ) - x_fc_page11_signer_name = fields.Char( - string='Page 11 Signer Name', - tracking=True, - help='Name of the person who signed Page 11', - ) - x_fc_page11_signer_relationship = fields.Char( - string='Relationship to Client', - help='Relationship of the signer to the client (if not client self)', - ) - x_fc_page11_signed_date = fields.Date( - string='Page 11 Signed Date', - tracking=True, - help='Date when Page 11 was signed', - ) - - # ========================================================================== - # PAGE 12 SIGNATURE TRACKING (Authorizer + Vendor Signature) - # Page 12 must be signed by: Authorizer (OT) and Vendor (our company) - # ========================================================================== - x_fc_page12_authorizer_signed = fields.Boolean( - string='Authorizer Signed Page 12', - default=False, - tracking=True, - help='Whether the authorizer/OT has signed Page 12', - ) - x_fc_page12_authorizer_signed_date = fields.Date( - string='Authorizer Signed Date', - tracking=True, - help='Date when the authorizer signed Page 12', - ) - x_fc_page12_vendor_signed = fields.Boolean( - string='Vendor Signed Page 12', - default=False, - tracking=True, - help='Whether the vendor (our company) has signed Page 12', - ) - x_fc_page12_vendor_signer_id = fields.Many2one( - 'res.users', - string='Vendor Signer', - tracking=True, - help='The user who signed Page 12 on behalf of the company', - ) - x_fc_page12_vendor_signed_date = fields.Date( - string='Vendor Signed Date', - tracking=True, - help='Date when the vendor signed Page 12', - ) - - x_fc_final_submitted_application = fields.Binary( - string='Final Submitted Application', - attachment=True, - help='The final ADP application as submitted to ADP', - ) - x_fc_final_application_filename = fields.Char( - string='Final Application Filename', - ) - - x_fc_xml_file = fields.Binary( - string='XML File', - attachment=True, - help='The XML data file submitted to ADP', - ) - x_fc_xml_filename = fields.Char( - string='XML Filename', - ) - - x_fc_approval_letter = fields.Binary( - string='ADP Approval Letter', - attachment=True, - help='ADP approval letter document', - ) - x_fc_approval_letter_filename = fields.Char( - string='Approval Letter Filename', - ) - x_fc_approval_photo_ids = fields.Many2many( - 'ir.attachment', - 'sale_order_approval_photo_rel', - 'sale_order_id', - 'attachment_id', - string='Approval Screenshots', - help='Upload approval screenshots/photos from ADP portal', - ) - x_fc_approval_photo_count = fields.Integer( - string='Approval Photos', - compute='_compute_approval_photo_count', - ) - - @api.depends('x_fc_approval_photo_ids') - def _compute_approval_photo_count(self): - """Count approval photos.""" - for order in self: - order.x_fc_approval_photo_count = len(order.x_fc_approval_photo_ids) - - x_fc_proof_of_delivery = fields.Binary( - string='Proof of Delivery', - attachment=True, - help='Proof of delivery document - required before creating ADP invoice', - ) - x_fc_proof_of_delivery_filename = fields.Char( - string='Proof of Delivery Filename', - ) - - # POD Digital Signature Fields (captured via portal) - x_fc_pod_signature = fields.Binary( - string='POD Client Signature', - attachment=True, - help='Digital signature captured from client via portal', - ) - x_fc_pod_client_name = fields.Char( - string='POD Client Name', - help='Name of the person who signed the Proof of Delivery', - ) - x_fc_pod_signature_date = fields.Date( - string='POD Signature Date', - help='Date specified on the Proof of Delivery (optional)', - ) - x_fc_pod_signed_by_user_id = fields.Many2one( - 'res.users', - string='POD Collected By', - help='The sales rep or technician who collected the POD signature', - ) - x_fc_pod_signed_datetime = fields.Datetime( - string='POD Collection Timestamp', - help='When the POD signature was collected', - ) - - # ========================================================================== - # VERIFICATION TRACKING - # ========================================================================== - x_fc_submission_verified = fields.Boolean( - string='Submission Verified', - default=False, - copy=False, - help='True when user has verified device types for submission via the wizard', - ) - - x_fc_submitted_device_types = fields.Text( - string='Submitted Device Types (JSON)', - copy=False, - help='JSON storing which device types were selected for submission', - ) - - # ========================================================================== - # COMPUTED TOTALS FOR ADP PORTIONS - # ========================================================================== - x_fc_adp_portion_total = fields.Monetary( - string='Total ADP Portion', - compute='_compute_adp_totals', - store=True, - currency_field='currency_id', - help='Total ADP portion for all lines', - ) - x_fc_client_portion_total = fields.Monetary( - string='Total Client Portion', - compute='_compute_adp_totals', - store=True, - currency_field='currency_id', - help='Total client portion for all lines', - ) - - # ========================================================================== - # COMPUTED FIELDS FOR SPLIT INVOICE TRACKING - # ========================================================================== - x_fc_has_client_invoice = fields.Boolean( - string='Has Client Invoice', - compute='_compute_adp_invoice_status', - help='Whether a client portion (25%) invoice has been created', - ) - x_fc_has_adp_invoice = fields.Boolean( - string='Has ADP Invoice', - compute='_compute_adp_invoice_status', - help='Whether an ADP portion (75%/100%) invoice has been created', - ) - - # ========================================================================== - # COMPUTED FIELD FOR PRODUCT-ONLY LINES (for ADP Summary) - # ========================================================================== - x_fc_product_lines = fields.One2many( - 'sale.order.line', - compute='_compute_product_lines', - string='Product Lines Only', - help='Only product lines (excludes sections, notes, and empty lines)', - ) - - # ========================================================================== - # DEVICE APPROVAL TRACKING - # ========================================================================== - x_fc_has_unapproved_devices = fields.Boolean( - string='Has Unapproved Devices', - compute='_compute_device_approval_status', - help='True if there are devices that have not been marked as approved by ADP', - ) - x_fc_device_verification_complete = fields.Boolean( - string='Verification Complete', - default=False, - copy=False, - help='True if the user has completed device verification via the wizard. ' - 'Set when user clicks Confirm in the Device Approval wizard.', - ) - x_fc_device_approval_done = fields.Boolean( - string='All Devices Approved', - compute='_compute_device_approval_status', - help='True if ALL ADP devices have been approved. For display purposes only.', - ) - x_fc_approved_device_count = fields.Integer( - string='Approved Device Count', - compute='_compute_device_approval_status', - ) - x_fc_total_device_count = fields.Integer( - string='Total Device Count', - compute='_compute_device_approval_status', - ) - - # ========================================================================== - # CASE LOCK - # ========================================================================== - x_fc_case_locked = fields.Boolean( - string='Case Locked', - default=False, - copy=False, - tracking=True, - help='When enabled, all ADP-related fields become read-only and cannot be modified.', - ) - - # ========================================================================== - # INVOICE MAPPING (for linking legacy invoices) - # ========================================================================== - x_fc_adp_invoice_id = fields.Many2one( - 'account.move', - string='ADP Invoice', - domain="[('move_type', 'in', ['out_invoice', 'out_refund'])]", - copy=False, - help='Link to the ADP invoice for this order', - ) - x_fc_client_invoice_id = fields.Many2one( - 'account.move', - string='Client Invoice', - domain="[('move_type', 'in', ['out_invoice', 'out_refund'])]", - copy=False, - help='Link to the client portion invoice for this order', - ) - - # ========================================================================== - # (Legacy studio fields removed - all data migrated to x_fc_* fields) - # ========================================================================== - - # ========================================================================== - # ORDER TRAIL CHECKLIST (computed for display) - # ========================================================================== - x_fc_trail_has_assessment_dates = fields.Boolean( - string='Assessment Dates Set', - compute='_compute_order_trail', - ) - x_fc_trail_has_authorization = fields.Boolean( - string='Authorization Date Set', - compute='_compute_order_trail', - ) - x_fc_trail_has_original_app = fields.Boolean( - string='Original Application Uploaded', - compute='_compute_order_trail', - ) - x_fc_trail_has_signed_pages = fields.Boolean( - string='Signed Pages 11 & 12 Uploaded', - compute='_compute_order_trail', - ) - x_fc_trail_has_final_app = fields.Boolean( - string='Final Application Uploaded', - compute='_compute_order_trail', - ) - x_fc_trail_has_xml = fields.Boolean( - string='XML File Uploaded', - compute='_compute_order_trail', - ) - x_fc_trail_has_approval_letter = fields.Boolean( - string='Approval Letter Uploaded', - compute='_compute_order_trail', - ) - x_fc_trail_has_pod = fields.Boolean( - string='Proof of Delivery Uploaded', - compute='_compute_order_trail', - ) - x_fc_trail_has_vendor_bills = fields.Boolean( - string='Vendor Bills Linked', - compute='_compute_order_trail', - ) - x_fc_trail_invoices_posted = fields.Boolean( - string='Invoices Posted', - compute='_compute_order_trail', - ) - - @api.depends( - 'x_fc_assessment_start_date', 'x_fc_assessment_end_date', - 'x_fc_claim_authorization_date', 'x_fc_original_application', - 'x_fc_signed_pages_11_12', 'x_fc_final_submitted_application', - 'x_fc_xml_file', 'x_fc_approval_letter', 'x_fc_proof_of_delivery', - 'x_fc_vendor_bill_ids', 'invoice_ids', 'invoice_ids.state' - ) - def _compute_order_trail(self): - for order in self: - order.x_fc_trail_has_assessment_dates = bool( - order.x_fc_assessment_start_date and order.x_fc_assessment_end_date - ) - order.x_fc_trail_has_authorization = bool(order.x_fc_claim_authorization_date) - order.x_fc_trail_has_original_app = bool(order.x_fc_original_application) - order.x_fc_trail_has_signed_pages = bool(order.x_fc_signed_pages_11_12) - order.x_fc_trail_has_final_app = bool(order.x_fc_final_submitted_application) - order.x_fc_trail_has_xml = bool(order.x_fc_xml_file) - order.x_fc_trail_has_approval_letter = bool(order.x_fc_approval_letter) - order.x_fc_trail_has_pod = bool(order.x_fc_proof_of_delivery) - order.x_fc_trail_has_vendor_bills = bool(order.x_fc_vendor_bill_ids) - # Check if there are posted invoices - order.x_fc_trail_invoices_posted = any( - inv.state == 'posted' for inv in order.invoice_ids - ) - - # ========================================================================== - # DEDUCTION TRACKING - # ========================================================================== - x_fc_has_deductions = fields.Boolean( - string='Has Deductions', - compute='_compute_has_deductions', - help='True if any line has a deduction applied', - ) - x_fc_total_deduction_amount = fields.Monetary( - string='Total Deduction Amount', - compute='_compute_has_deductions', - currency_field='currency_id', - help='Total amount of deductions applied to ADP portion', - ) - - # ========================================================================== - # COMPUTED METHODS - # ========================================================================== - @api.depends('order_line.x_fc_adp_portion', 'order_line.x_fc_client_portion') - def _compute_adp_totals(self): - for order in self: - order.x_fc_adp_portion_total = sum(order.order_line.mapped('x_fc_adp_portion')) - order.x_fc_client_portion_total = sum(order.order_line.mapped('x_fc_client_portion')) - - def _compute_adp_invoice_status(self): - """Check if client/ADP split invoices have already been created.""" - for order in self: - client_invoice_exists = False - adp_invoice_exists = False - - # Check linked invoices for the portion type - invoices = order.invoice_ids.filtered(lambda inv: inv.state != 'cancel') - for invoice in invoices: - if hasattr(invoice, 'x_fc_adp_invoice_portion'): - if invoice.x_fc_adp_invoice_portion == 'client': - client_invoice_exists = True - elif invoice.x_fc_adp_invoice_portion == 'adp': - adp_invoice_exists = True - - order.x_fc_has_client_invoice = client_invoice_exists - order.x_fc_has_adp_invoice = adp_invoice_exists - - @api.depends('order_line', 'order_line.product_id', 'order_line.product_uom_qty', 'order_line.display_type') - def _compute_product_lines(self): - """Compute filtered list of only actual product lines (no sections, notes, or empty lines).""" - for order in self: - order.x_fc_product_lines = order.order_line.filtered( - lambda l: not l.display_type and l.product_id and l.product_uom_qty > 0 - ) - - @api.depends('order_line.x_fc_adp_approved', 'order_line.product_id', 'order_line.display_type') - def _compute_device_approval_status(self): - """Compute device approval status for ADP orders. - - Only counts lines with valid ADP device codes in the database. - Non-ADP items are ignored for verification purposes. - """ - ADPDevice = self.env['fusion.adp.device.code'].sudo() - - for order in self: - # Get lines with device codes (actual ADP billable products) - product_lines = order.order_line.filtered( - lambda l: not l.display_type - and l.product_id - and l.product_uom_qty > 0 - ) - - # Filter to only lines with valid ADP device codes in the database - device_lines = self.env['sale.order.line'] - for line in product_lines: - device_code = line._get_adp_device_code() - if device_code: - # Check if this code exists in ADP database - if ADPDevice.search_count([('device_code', '=', device_code), ('active', '=', True)]) > 0: - device_lines |= line - - total_count = len(device_lines) - approved_count = len(device_lines.filtered(lambda l: l.x_fc_adp_approved)) - - order.x_fc_total_device_count = total_count - order.x_fc_approved_device_count = approved_count - order.x_fc_has_unapproved_devices = approved_count < total_count and total_count > 0 - - # Verification is "done" only if ALL ADP devices have been approved - # If there are no ADP devices, verification is automatically done - order.x_fc_device_approval_done = (approved_count == total_count) or total_count == 0 - - @api.depends('order_line.x_fc_deduction_type', 'order_line.x_fc_deduction_value', - 'order_line.x_fc_adp_portion', 'order_line.product_id') - def _compute_has_deductions(self): - """Compute if order has any deductions and total deduction amount.""" - for order in self: - product_lines = order.order_line.filtered( - lambda l: not l.display_type - and l.product_id - and l.product_uom_qty > 0 - ) - - # Check if any line has a deduction - has_deductions = any( - line.x_fc_deduction_type and line.x_fc_deduction_type != 'none' - for line in product_lines - ) - - # Calculate total deduction impact (difference from full ADP coverage) - total_deduction = 0.0 - if has_deductions: - for line in product_lines: - if line.x_fc_deduction_type == 'amt' and line.x_fc_deduction_value: - total_deduction += line.x_fc_deduction_value - elif line.x_fc_deduction_type == 'pct' and line.x_fc_deduction_value: - # For percentage, calculate the reduction from normal - # If normally 75% ADP, and now 50%, the deduction is 25% of total - client_type = order._get_client_type() - base_pct = 0.75 if client_type == 'REG' else 1.0 - adp_price = line.x_fc_adp_max_price or line.price_unit - normal_adp = adp_price * line.product_uom_qty * base_pct - actual_adp = line.x_fc_adp_portion - total_deduction += max(0, normal_adp - actual_adp) - - order.x_fc_has_deductions = has_deductions - order.x_fc_total_deduction_amount = total_deduction - - @api.depends('x_fc_previous_funding_date') - def _compute_years_since_funding(self): - """Compute years since previous funding and 5-year flag.""" - from datetime import date - today = date.today() - for order in self: - if order.x_fc_previous_funding_date: - delta = today - order.x_fc_previous_funding_date - years = delta.days / 365.25 - order.x_fc_years_since_funding = round(years, 2) - order.x_fc_under_5_years = years < 5 - else: - order.x_fc_years_since_funding = 0 - order.x_fc_under_5_years = False - - # ========================================================================== - # PREVIOUS FUNDING WARNING MESSAGE - # ========================================================================== - x_fc_funding_warning_message = fields.Char( - string='Funding Warning', - compute='_compute_funding_warning_message', - help='Warning message for recent previous funding', - ) - - x_fc_funding_warning_level = fields.Selection( - selection=[ - ('none', 'None'), - ('warning', 'Warning'), - ('danger', 'Danger'), - ], - string='Warning Level', - compute='_compute_funding_warning_message', - help='Level of warning for previous funding', - ) - - @api.depends('x_fc_previous_funding_date') - def _compute_funding_warning_message(self): - """Compute warning message for previous funding with time elapsed.""" - from datetime import date - today = date.today() - for order in self: - if order.x_fc_previous_funding_date: - delta = today - order.x_fc_previous_funding_date - total_months = delta.days / 30.44 # Average days per month - years = int(total_months // 12) - months = int(total_months % 12) - - if years == 0: - time_str = f"{months} month{'s' if months != 1 else ''}" - elif months == 0: - time_str = f"{years} year{'s' if years != 1 else ''}" - else: - time_str = f"{years} year{'s' if years != 1 else ''} and {months} month{'s' if months != 1 else ''}" - - order.x_fc_funding_warning_message = f"Previous funding was {time_str} ago ({order.x_fc_previous_funding_date.strftime('%B %d, %Y')})" - - # Set warning level - red if within 1 year - if total_months < 12: - order.x_fc_funding_warning_level = 'danger' - elif total_months < 60: # Less than 5 years - order.x_fc_funding_warning_level = 'warning' - else: - order.x_fc_funding_warning_level = 'none' - else: - order.x_fc_funding_warning_message = False - order.x_fc_funding_warning_level = 'none' - - # ========================================================================== - # FIELD VALIDATION CONSTRAINTS - # ========================================================================== - @api.constrains('x_fc_claim_number') - def _check_claim_number(self): - """Validate claim number: 10 digits only, numbers only.""" - for order in self: - if order.x_fc_claim_number: - # Remove any whitespace - claim = order.x_fc_claim_number.strip() - if not re.match(r'^\d{10}$', claim): - raise ValidationError( - "Claim Number must be exactly 10 digits (numbers only).\n" - f"Current value: '{order.x_fc_claim_number}'" - ) - - @api.constrains('x_fc_client_ref_1') - def _check_client_ref_1(self): - """Validate client reference 1: up to 4 letters, comma allowed.""" - for order in self: - if order.x_fc_client_ref_1: - # Allow letters and comma only, max 4 characters (excluding comma) - ref = order.x_fc_client_ref_1.strip().upper() - # Remove commas for letter count - letters_only = ref.replace(',', '') - if len(letters_only) > 4: - raise ValidationError( - "Client Reference 1 can only have up to 4 letters.\n" - f"Current value: '{order.x_fc_client_ref_1}'" - ) - if not re.match(r'^[A-Za-z,]+$', ref): - raise ValidationError( - "Client Reference 1 can only contain letters and comma.\n" - f"Current value: '{order.x_fc_client_ref_1}'" - ) - - @api.constrains('x_fc_client_ref_2') - def _check_client_ref_2(self): - """Validate client reference 2: exactly 4 digits, numbers only.""" - for order in self: - if order.x_fc_client_ref_2: - ref = order.x_fc_client_ref_2.strip() - if not re.match(r'^\d{4}$', ref): - raise ValidationError( - "Client Reference 2 must be exactly 4 digits (numbers only).\n" - f"Current value: '{order.x_fc_client_ref_2}'" - ) - - @api.constrains('x_fc_original_application_filename') - def _check_original_application_pdf(self): - """Validate that Original ADP Application is a PDF file.""" - for order in self: - if order.x_fc_original_application_filename: - if not order.x_fc_original_application_filename.lower().endswith('.pdf'): - raise ValidationError( - "Original ADP Application must be a PDF file.\n" - f"Uploaded file: '{order.x_fc_original_application_filename}'" - ) - - @api.constrains('x_fc_signed_pages_filename') - def _check_signed_pages_pdf(self): - """Validate that Page 11 & 12 is a PDF file.""" - for order in self: - if order.x_fc_signed_pages_filename: - if not order.x_fc_signed_pages_filename.lower().endswith('.pdf'): - raise ValidationError( - "Page 11 & 12 (Signed) must be a PDF file.\n" - f"Uploaded file: '{order.x_fc_signed_pages_filename}'" - ) - - @api.constrains('x_fc_final_application_filename') - def _check_final_application_pdf(self): - """Validate that Final Submitted Application is a PDF file.""" - for order in self: - if order.x_fc_final_application_filename: - if not order.x_fc_final_application_filename.lower().endswith('.pdf'): - raise ValidationError( - "Final Submitted Application must be a PDF file.\n" - f"Uploaded file: '{order.x_fc_final_application_filename}'" - ) - - @api.constrains('x_fc_xml_filename') - def _check_xml_file(self): - """Validate that XML File is an XML file.""" - for order in self: - if order.x_fc_xml_filename: - if not order.x_fc_xml_filename.lower().endswith('.xml'): - raise ValidationError( - "XML File must be an XML file (.xml).\n" - f"Uploaded file: '{order.x_fc_xml_filename}'" - ) - - @api.constrains('x_fc_proof_of_delivery_filename') - def _check_proof_of_delivery_pdf(self): - """Validate that Proof of Delivery is a PDF file.""" - for order in self: - if order.x_fc_proof_of_delivery_filename: - if not order.x_fc_proof_of_delivery_filename.lower().endswith('.pdf'): - raise ValidationError( - "Proof of Delivery must be a PDF file.\n" - f"Uploaded file: '{order.x_fc_proof_of_delivery_filename}'" - ) - - @api.constrains('x_fc_adp_delivery_date', 'x_fc_claim_approval_date') - def _check_delivery_date_after_approval(self): - """Validate that delivery date is not before approval date. - - Per business rule: The delivery date on POD cannot be before the approval date. - If client takes delivery before approval (early delivery case), the POD - should show the approval date, not the actual delivery date. - """ - for order in self: - if order.x_fc_adp_delivery_date and order.x_fc_claim_approval_date: - if order.x_fc_adp_delivery_date < order.x_fc_claim_approval_date: - raise ValidationError( - "Delivery Date cannot be before Approval Date.\n\n" - f"Delivery Date: {order.x_fc_adp_delivery_date.strftime('%B %d, %Y')}\n" - f"Approval Date: {order.x_fc_claim_approval_date.strftime('%B %d, %Y')}\n\n" - "For early delivery cases (delivery before approval), the Proof of Delivery " - "document should show the approval date, not the actual delivery date.\n\n" - "Please correct the delivery date and re-upload the Proof of Delivery." - ) - - # ========================================================================== - # PDF DOCUMENT PREVIEW ACTIONS (opens in new tab using browser/system PDF handler) - # ========================================================================== - def _get_document_attachment(self, field_name): - """Get the ir.attachment record for a binary field stored as attachment.""" - self.ensure_one() - # Find the attachment by field name - get most recent one - attachment = self.env['ir.attachment'].sudo().search([ - ('res_model', '=', 'sale.order'), - ('res_id', '=', self.id), - ('res_field', '=', field_name), - ], order='create_date desc', limit=1) - return attachment - - def _get_or_create_attachment(self, field_name, document_label): - """Get the current attachment for a binary field (attachment=True). - - For attachment=True fields, Odoo creates attachments automatically. - We find the one with res_field set and return it. - """ - self.ensure_one() - - data = getattr(self, field_name) - if not data: - return None - - # For attachment=True fields, Odoo creates/updates an attachment with res_field set - attachment = self.env['ir.attachment'].sudo().search([ - ('res_model', '=', 'sale.order'), - ('res_id', '=', self.id), - ('res_field', '=', field_name), - ], order='id desc', limit=1) - - if attachment: - # If attachment name is the field name (Odoo default), use the actual filename - if attachment.name == field_name: - filename_mapping = { - 'x_fc_original_application': 'x_fc_original_application_filename', - 'x_fc_signed_pages_11_12': 'x_fc_signed_pages_filename', - 'x_fc_final_submitted_application': 'x_fc_final_application_filename', - 'x_fc_xml_file': 'x_fc_xml_filename', - 'x_fc_proof_of_delivery': 'x_fc_proof_of_delivery_filename', - } - filename_field = filename_mapping.get(field_name) - if filename_field: - filename = getattr(self, filename_field, None) - if filename and filename != field_name: - attachment.sudo().write({'name': filename}) - return attachment - - # Fallback: create attachment manually (shouldn't happen for attachment=True fields) - filename_mapping = { - 'x_fc_original_application': 'x_fc_original_application_filename', - 'x_fc_signed_pages_11_12': 'x_fc_signed_pages_filename', - 'x_fc_final_submitted_application': 'x_fc_final_application_filename', - 'x_fc_xml_file': 'x_fc_xml_filename', - 'x_fc_proof_of_delivery': 'x_fc_proof_of_delivery_filename', - } - filename_field = filename_mapping.get(field_name) - filename = getattr(self, filename_field) if filename_field else f'{document_label}.pdf' - - attachment = self.env['ir.attachment'].sudo().create({ - 'name': filename or f'{document_label}.pdf', - 'datas': data, - 'res_model': 'sale.order', - 'res_id': self.id, - 'res_field': field_name, - 'type': 'binary', - }) - - return attachment - - def action_open_original_application(self): - """Open the Original ADP Application PDF.""" - self.ensure_one() - return self._action_open_document('x_fc_original_application', 'Original ADP Application') - - def action_open_signed_pages(self): - """Open the Page 11 & 12 PDF.""" - self.ensure_one() - return self._action_open_document('x_fc_signed_pages_11_12', 'Page 11 & 12 (Signed)') - - def action_open_final_application(self): - """Open the Final Submitted Application PDF.""" - self.ensure_one() - return self._action_open_document('x_fc_final_submitted_application', 'Final Submitted Application') - - def action_open_xml_file(self): - """Open the XML File in viewer.""" - self.ensure_one() - return self._action_open_document('x_fc_xml_file', 'XML File', is_xml=True) - - def action_open_proof_of_delivery(self): - """Open the Proof of Delivery PDF.""" - self.ensure_one() - return self._action_open_document('x_fc_proof_of_delivery', 'Proof of Delivery') - - def action_open_approval_letter(self): - """Open the ADP Approval Letter PDF.""" - self.ensure_one() - return self._action_open_document('x_fc_approval_letter', 'ADP Approval Letter') - - def action_open_sa_approval_form(self): - """Open the SA Mobility ODSP Approval Form PDF.""" - self.ensure_one() - return self._action_open_document('x_fc_sa_approval_form', 'ODSP Approval Form') - - def action_open_sa_signed_form(self): - """Open the signed SA Mobility form PDF.""" - self.ensure_one() - return self._action_open_document('x_fc_sa_signed_form', 'SA Signed Form') - - def action_open_sa_physical_copy(self): - """Open the physically signed SA Mobility copy.""" - self.ensure_one() - return self._action_open_document('x_fc_sa_physical_signed_copy', 'Physical Signed Copy') - - def action_open_sa_internal_pod(self): - """Generate and open the internal POD report on-the-fly.""" - self.ensure_one() - report = self.env.ref('fusion_claims.action_report_proof_of_delivery_standard') - return report.report_action(self) - - def action_open_ow_discretionary_form(self): - """Open the Ontario Works Discretionary Benefits form PDF.""" - self.ensure_one() - return self._action_open_document('x_fc_ow_discretionary_form', 'Discretionary Benefits Form') - - def action_open_ow_authorizer_letter(self): - """Open the Ontario Works Authorizer Letter.""" - self.ensure_one() - return self._action_open_document('x_fc_ow_authorizer_letter', 'Authorizer Letter') - - def action_open_ow_internal_pod(self): - """Generate and open the internal POD report on-the-fly (Ontario Works).""" - self.ensure_one() - report = self.env.ref('fusion_claims.action_report_proof_of_delivery_standard') - return report.report_action(self) - - def action_open_odsp_std_approval_document(self): - """Open the Standard ODSP Approval Document.""" - self.ensure_one() - return self._action_open_document('x_fc_odsp_approval_document', 'ODSP Approval Document') - - def action_open_odsp_std_authorizer_letter(self): - """Open the Standard ODSP Authorizer Letter.""" - self.ensure_one() - return self._action_open_document('x_fc_odsp_authorizer_letter', 'Authorizer Letter') - - def action_open_odsp_std_internal_pod(self): - """Generate and open the internal POD report on-the-fly (Standard ODSP).""" - self.ensure_one() - report = self.env.ref('fusion_claims.action_report_proof_of_delivery_standard') - return report.report_action(self) - - def _get_sa_pod_pdf(self): - """Generate the standard POD report PDF and return (pdf_bytes, filename).""" - self.ensure_one() - report = self.env.ref('fusion_claims.action_report_proof_of_delivery_standard') - pdf_content, _ct = report._render_qweb_pdf(report.id, [self.id]) - return pdf_content, f'POD_{self.name}.pdf' - - def action_view_approval_photos(self): - """Open approval photos using Odoo's native attachment viewer.""" - self.ensure_one() - attachments = self.x_fc_approval_photo_ids - if not attachments: - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'No Photos', - 'message': 'No approval screenshots have been uploaded yet.', - 'type': 'warning', - 'sticky': False, - } - } - - # Use Odoo's native attachment viewer (same as chatter) - return { - 'type': 'ir.actions.act_url', - 'url': f'/web/image/{attachments[0].id}', - 'target': 'new', - } - - def _action_open_document(self, field_name, document_label, download=False, is_xml=False): - """Open a document in a preview dialog (PDF or XML viewer).""" - self.ensure_one() - - # Check if the field has data - if not getattr(self, field_name): - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'No Document', - 'message': f'No {document_label} has been uploaded yet.', - 'type': 'warning', - 'sticky': False, - } - } - - # Get or create attachment - attachment = self._get_or_create_attachment(field_name, document_label) - - if attachment: - if download: - # Open in new tab for download - return { - 'type': 'ir.actions.act_url', - 'url': f'/web/content/{attachment.id}?download=true', - 'target': 'new', - } - elif is_xml: - # For XML files, open in XML viewer dialog - return { - 'type': 'ir.actions.client', - 'tag': 'fusion_claims.preview_xml', - 'params': { - 'attachment_id': attachment.id, - 'title': f'{document_label} - {self.name}', - } - } - else: - # For PDF files, open in PDF preview dialog - return { - 'type': 'ir.actions.client', - 'tag': 'fusion_claims.preview_document', - 'params': { - 'attachment_id': attachment.id, - 'title': f'{document_label} - {self.name}', - } - } - else: - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'Error', - 'message': f'Failed to load {document_label}.', - 'type': 'danger', - 'sticky': False, - } - } - - @api.onchange('x_fc_sale_type', 'x_fc_client_type') - def _onchange_sale_type_client_type(self): - """Trigger recalculation when sale type or client type changes.""" - for line in self.order_line: - line._compute_adp_portions() - - # ========================================================================== - # GETTER METHODS - # ========================================================================== - def _get_sale_type(self): - """Get sale type from x_fc_sale_type.""" - self.ensure_one() - return self.x_fc_sale_type or '' - - def _get_client_type(self): - """Get client type from x_fc_client_type.""" - self.ensure_one() - return self.x_fc_client_type or '' - - def _get_authorizer(self): - """Get authorizer from mapped field or built-in field. Returns name as string.""" - self.ensure_one() - ICP = self.env['ir.config_parameter'].sudo() - field_name = ICP.get_param('fusion_claims.field_so_authorizer', 'x_fc_authorizer_id') - value = getattr(self, field_name, None) if hasattr(self, field_name) else None - if not value and field_name != 'x_fc_authorizer_id': - value = self.x_fc_authorizer_id - # Return name if it's a record, otherwise return string value - if hasattr(value, 'name'): - return value.name or '' - return str(value) if value else '' - - def _get_claim_number(self): - """Get claim number.""" - self.ensure_one() - return self.x_fc_claim_number or '' - - def _get_client_ref_1(self): - """Get client reference 1.""" - self.ensure_one() - return self.x_fc_client_ref_1 or '' - - def _get_client_ref_2(self): - """Get client reference 2.""" - self.ensure_one() - return self.x_fc_client_ref_2 or '' - - def _get_adp_delivery_date(self): - """Get ADP delivery date.""" - self.ensure_one() - return self.x_fc_adp_delivery_date - - def _is_adp_sale(self): - """Check if this is an ADP sale type. - - Returns True only for ADP-related sale types. - """ - self.ensure_one() - sale_type = self.x_fc_sale_type or '' - - if not sale_type: - return False - - sale_type_lower = str(sale_type).lower().strip() - adp_keywords = ('adp',) - return any(keyword in sale_type_lower for keyword in adp_keywords) - - def _get_serial_numbers(self): - """Get all serial numbers from order lines.""" - self.ensure_one() - serial_lines = [] - for line in self.order_line: - serial = line._get_serial_number() - if serial: - serial_lines.append({ - 'product': line.product_id.name, - 'serial': serial, - 'adp_code': line._get_adp_device_code(), - }) - return serial_lines - - # ========================================================================== - # ACTION METHODS - # ========================================================================== - def action_recalculate_adp_portions(self): - """Manually recalculate ADP and Client portions for all lines.""" - for order in self: - for line in order.order_line: - line._compute_adp_portions() - order._compute_adp_totals() - - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'ADP Portions Recalculated', - 'message': 'All line portions have been recalculated.', - 'type': 'success', - 'sticky': False, - } - } - - def action_submit_to_adp(self): - """Mark order as submitted to ADP.""" - for order in self: - if order._is_adp_sale(): - order.x_fc_adp_status = 'submitted' - return True - - def action_mark_adp_approved(self): - """Mark order as approved by ADP.""" - for order in self: - if order._is_adp_sale(): - order.x_fc_adp_status = 'approved' - return True - - def action_open_device_approval_wizard(self): - """Open the device approval wizard to verify which devices were approved by ADP.""" - self.ensure_one() - return { - 'name': 'Verify Device Approval', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion_claims.device.approval.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': { - 'active_id': self.id, - 'active_model': 'sale.order', - }, - } - - def action_open_submission_verification_wizard(self): - """Open the submission verification wizard to confirm which device types are being submitted.""" - self.ensure_one() - return { - 'name': 'Verify Submission Device Types', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion_claims.submission.verification.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': { - 'active_id': self.id, - 'active_model': 'sale.order', - }, - } - - # ========================================================================== - # EARLY WORKFLOW STAGE ACTIONS (No wizard required - simple status updates) - # ========================================================================== - - def action_schedule_assessment(self): - """Open wizard to schedule assessment with date/time and calendar event.""" - self.ensure_one() - if self.x_fc_adp_application_status != 'quotation': - raise UserError("Can only schedule assessment from 'Quotation' status.") - - return { - 'name': 'Schedule Assessment', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion_claims.schedule.assessment.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': { - 'active_id': self.id, - 'active_model': 'sale.order', - }, - } - - def action_complete_assessment(self): - """Open wizard to mark assessment as completed with date.""" - self.ensure_one() - if self.x_fc_adp_application_status != 'assessment_scheduled': - raise UserError("Can only complete assessment from 'Assessment Scheduled' status.") - - return { - 'name': 'Assessment Completed', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion_claims.assessment.completed.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': { - 'active_id': self.id, - 'active_model': 'sale.order', - }, - } - - def action_application_received(self): - """Open wizard to upload ADP application and pages 11 & 12.""" - self.ensure_one() - if self.x_fc_adp_application_status not in ('assessment_completed', 'waiting_for_application'): - raise UserError("Can only mark application received from 'Waiting for Application' status.") - - return { - 'name': 'Application Received', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion_claims.application.received.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': { - 'active_id': self.id, - 'active_model': 'sale.order', - }, - } - - def action_ready_for_submission(self): - """Open wizard to collect required fields and mark as ready for submission.""" - self.ensure_one() - if self.x_fc_adp_application_status != 'application_received': - raise UserError("Can only mark ready for submission from 'Application Received' status.") - - return { - 'name': 'Ready for Submission', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion_claims.ready.for.submission.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': { - 'active_id': self.id, - 'active_model': 'sale.order', - }, - } - - # ========================================================================== - # SUBMISSION WORKFLOW ACTIONS - # ========================================================================== - - def action_submit_application(self): - """Open submission verification wizard and submit the application. - - This forces verification of device types before changing status to 'submitted'. - """ - self.ensure_one() - - # Validate we're in a status that can be submitted - if self.x_fc_adp_application_status not in ('ready_submission', 'needs_correction'): - raise UserError( - "Application can only be submitted from 'Ready for Submission' or 'Needs Correction' status." - ) - - return { - 'name': 'Submit Application - Verify Device Types', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion_claims.submission.verification.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': { - 'active_id': self.id, - 'active_model': 'sale.order', - 'submit_application': True, # Flag to set status after verification - }, - } - - def action_close_case(self): - """Open case close verification wizard to verify audit trail before closing. - - This forces verification of: - - Signed Pages 11 & 12 - - Final Application - - Proof of Delivery - - Vendor Bills - """ - self.ensure_one() - - # Validate we're in a status that can be closed - if self.x_fc_adp_application_status != 'billed': - raise UserError( - "Case can only be closed from 'Billed' status." - ) - - return { - 'name': 'Close Case - Audit Trail Verification', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion_claims.case.close.verification.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': { - 'active_id': self.id, - 'active_model': 'sale.order', - }, - } - - def action_mark_accepted(self): - """Mark the application as accepted by ADP. - - This is called when ADP accepts the submission (within 24 hours). - This is a simple status change - no wizard needed. - Submission history is updated in the write() method. - """ - self.ensure_one() - - # Validate we're in a status that can be accepted - if self.x_fc_adp_application_status not in ('submitted', 'resubmitted'): - raise UserError( - "Application can only be marked as accepted from 'Submitted' or 'Resubmitted' status." - ) - - # Update status - this will trigger the write() method which updates submission history - self.with_context(skip_status_validation=True).write({ - 'x_fc_adp_application_status': 'accepted', - }) - - # Post to chatter - self.message_post( - body=Markup( - '' - ), - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - - return True - - def action_mark_approved(self): - """Open device approval wizard and mark as approved. - - This is called when ADP approval letter is received. - The wizard allows verifying which devices were approved. - """ - self.ensure_one() - - # Validate we're in a status that can be approved - if self.x_fc_adp_application_status not in ('submitted', 'resubmitted', 'accepted'): - raise UserError( - "Application can only be marked as approved from 'Submitted', 'Resubmitted', or 'Accepted' status." - ) - - return { - 'name': 'Mark as Approved - Verify Device Approval', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion_claims.device.approval.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': { - 'active_id': self.id, - 'active_model': 'sale.order', - 'mark_as_approved': True, # Flag to set status after verification - }, - } - - def action_resume_from_hold(self): - """Resume the application from on-hold status. - - Returns the application to its previous status before being put on hold. - """ - self.ensure_one() - - if self.x_fc_adp_application_status != 'on_hold': - raise UserError("This action is only available for applications that are On Hold.") - - # Get the previous status - previous_status = self.x_fc_previous_status_before_hold - - # If no previous status recorded, default to 'approved' - if not previous_status: - previous_status = 'approved' - - # Get status labels for message - status_labels = dict(self._fields['x_fc_adp_application_status'].selection) - prev_label = status_labels.get(previous_status, previous_status) - - # Update the status - self.with_context(skip_status_validation=True).write({ - 'x_fc_adp_application_status': previous_status, - 'x_fc_on_hold_date': False, - 'x_fc_previous_status_before_hold': False, - }) - - # Post to chatter - user_name = self.env.user.name - resume_date = fields.Date.today().strftime('%B %d, %Y') - - message_body = f''' - - ''' - - self.message_post( - body=Markup(message_body), - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - - return True - - def action_set_ready_to_bill(self): - """Open the Ready to Bill wizard to collect POD and delivery date. - - The wizard will: - - Collect Proof of Delivery document - - Set the delivery date - - Validate device verification is complete - - Mark the order as Ready to Bill - """ - self.ensure_one() - - # Validate we're in a status that can move to ready_bill - if self.x_fc_adp_application_status not in ('approved', 'approved_deduction'): - raise UserError( - "Order can only be marked as 'Ready to Bill' from 'Approved' status." - ) - - # Check device verification first (this can't be done in wizard) - if not self.x_fc_device_verification_complete: - raise UserError( - "Device approval verification must be completed before marking as Ready to Bill.\n\n" - "Please verify which devices were approved by ADP using the 'Mark as Approved' button first." - ) - - # Open the wizard to collect POD and delivery date - return { - 'name': 'Ready to Bill', - 'type': 'ir.actions.act_window', - 'res_model': 'fusion_claims.ready.to.bill.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': { - 'active_id': self.id, - 'active_model': 'sale.order', - }, - } - - def action_set_ready_to_bill_direct(self): - """Direct method to mark as ready to bill (used when POD already uploaded). - - This is kept for backward compatibility and for cases where POD is already uploaded. - """ - self.ensure_one() - - # Validate we're in a status that can move to ready_bill - if self.x_fc_adp_application_status not in ('approved', 'approved_deduction'): - raise UserError( - "Order can only be marked as 'Ready to Bill' from 'Approved' status." - ) - - # Check POD - if not self.x_fc_proof_of_delivery: - # Redirect to wizard - return self.action_set_ready_to_bill() - - # Check delivery date - if not self.x_fc_adp_delivery_date: - # Redirect to wizard - return self.action_set_ready_to_bill() - - # Check device verification - if not self.x_fc_device_verification_complete: - raise UserError( - "Device approval verification must be completed before marking as Ready to Bill.\n\n" - "Please verify which devices were approved by ADP using the 'Mark as Approved' button first." - ) - - # All validations passed - set status - from markupsafe import Markup - from datetime import date - - self.with_context(skip_status_validation=True).write({ - 'x_fc_adp_application_status': 'ready_bill', - }) - - # Post to chatter with nice card style using Bootstrap classes for dark/light mode - self.message_post( - body=Markup( - '' - ), - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - - return True - - def action_mark_as_billed(self): - """Mark order as billed after validating invoices are posted. - - Validates: - - ADP invoice exists and is posted - - For REG clients: Client invoice exists and is posted - """ - self.ensure_one() - - # Validate we're in ready_bill status - if self.x_fc_adp_application_status != 'ready_bill': - raise UserError( - "Order can only be marked as 'Billed' from 'Ready to Bill' status." - ) - - # Check ADP invoice - AccountMove = self.env['account.move'].sudo() - adp_invoices = AccountMove.search([ - ('x_fc_source_sale_order_id', '=', self.id), - ('x_fc_adp_invoice_portion', '=', 'adp'), - ('state', '=', 'posted'), - ]) - - if not adp_invoices: - raise UserError( - "ADP invoice must be created and posted before marking as Billed.\n\n" - "Please create and post the ADP invoice first." - ) - - # For REG clients, check client invoice - if self.x_fc_client_type == 'REG': - client_invoices = AccountMove.search([ - ('x_fc_source_sale_order_id', '=', self.id), - ('x_fc_adp_invoice_portion', '=', 'client'), - ('state', '=', 'posted'), - ]) - - if not client_invoices: - raise UserError( - "Client invoice must be created and posted before marking as Billed.\n\n" - "For REG clients, both the ADP invoice (75%) and Client invoice (25%) must be posted." - ) - - # All validations passed - set status and billing date - from markupsafe import Markup - from datetime import date - - self.with_context(skip_status_validation=True).write({ - 'x_fc_adp_application_status': 'billed', - 'x_fc_billing_date': date.today(), - }) - - # Update ADP invoice billing status to 'submitted' - for adp_inv in adp_invoices: - if adp_inv.x_fc_adp_billing_status in ('waiting', 'not_applicable'): - adp_inv.write({'x_fc_adp_billing_status': 'submitted'}) - _logger.info(f"Updated ADP invoice {adp_inv.name} billing status to 'submitted'") - - # Build invoice list - invoice_list = ', '.join(adp_invoices.mapped('name')) - if self.x_fc_client_type == 'REG': - invoice_list += ', ' + ', '.join(client_invoices.mapped('name')) - - # Calculate total billed - total_billed = sum(adp_invoices.mapped('amount_total')) - if self.x_fc_client_type == 'REG': - total_billed += sum(client_invoices.mapped('amount_total')) - - # Post to chatter with nice card style using Bootstrap classes for dark/light mode - self.message_post( - body=Markup( - '' - ), - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - - return True - - def _check_unapproved_devices(self): - """Check if there are any unapproved ADP devices in the order. - - Only checks lines with valid ADP device codes in the database. - Non-ADP items are ignored. - """ - self.ensure_one() - ADPDevice = self.env['fusion.adp.device.code'].sudo() - - unapproved = self.env['sale.order.line'] - for line in self.order_line: - if line.display_type: - continue - if not line.product_id or line.product_uom_qty <= 0: - continue - if line.x_fc_adp_approved: - continue - - # Check if this has a valid ADP device code - device_code = line._get_adp_device_code() - if device_code and ADPDevice.search_count([('device_code', '=', device_code), ('active', '=', True)]) > 0: - unapproved |= line - - return unapproved - - def _get_approved_devices_summary(self): - """Get a summary of approved vs unapproved devices.""" - self.ensure_one() - lines_with_codes = self.order_line.filtered( - lambda l: not l.display_type - and l.product_id - and l.product_uom_qty > 0 - and l._get_adp_device_code() - ) - approved = lines_with_codes.filtered(lambda l: l.x_fc_adp_approved) - unapproved = lines_with_codes - approved - return { - 'total': len(lines_with_codes), - 'approved': len(approved), - 'unapproved': len(unapproved), - 'unapproved_lines': unapproved, - } - - def action_mark_client_paid(self): - """Mark order as client paid (25%).""" - for order in self: - if order._is_adp_sale(): - order.x_fc_adp_status = 'client_paid' - return True - - def action_mark_delivered(self): - """Mark order as delivered.""" - for order in self: - if order._is_adp_sale(): - order.x_fc_adp_status = 'delivered' - return True - - def action_mark_billed(self): - """Mark order as billed to ADP (75%).""" - for order in self: - if order._is_adp_sale(): - order.x_fc_adp_status = 'billed' - return True - - def action_mark_closed(self): - """Mark order as closed.""" - for order in self: - if order._is_adp_sale(): - order.x_fc_adp_status = 'closed' - return True - - # ========================================================================== - # VIEW INVOICES BY TYPE (Smart button actions) - # ========================================================================== - def action_view_adp_invoices(self): - """Open list of ADP portion invoices for this order.""" - self.ensure_one() - adp_invoices = self.env['account.move'].sudo().search([ - ('x_fc_source_sale_order_id', '=', self.id), - ('x_fc_adp_invoice_portion', '=', 'adp'), - ('state', '!=', 'cancel'), - ]) - # Include manually mapped ADP invoice - if self.x_fc_adp_invoice_id and self.x_fc_adp_invoice_id.state != 'cancel': - adp_invoices |= self.x_fc_adp_invoice_id - - action = { - 'name': 'ADP Invoices', - 'type': 'ir.actions.act_window', - 'res_model': 'account.move', - 'view_mode': 'list,form', - 'domain': [('id', 'in', adp_invoices.ids)], - 'context': {'default_move_type': 'out_invoice'}, - } - if len(adp_invoices) == 1: - action['view_mode'] = 'form' - action['res_id'] = adp_invoices.id - return action - - def action_view_client_invoices(self): - """Open list of Client portion invoices for this order.""" - self.ensure_one() - client_invoices = self.env['account.move'].sudo().search([ - ('x_fc_source_sale_order_id', '=', self.id), - ('x_fc_adp_invoice_portion', '=', 'client'), - ('state', '!=', 'cancel'), - ]) - # Include manually mapped Client invoice - if self.x_fc_client_invoice_id and self.x_fc_client_invoice_id.state != 'cancel': - client_invoices |= self.x_fc_client_invoice_id - - action = { - 'name': 'Client Invoices', - 'type': 'ir.actions.act_window', - 'res_model': 'account.move', - 'view_mode': 'list,form', - 'domain': [('id', 'in', client_invoices.ids)], - 'context': {'default_move_type': 'out_invoice'}, - } - if len(client_invoices) == 1: - action['view_mode'] = 'form' - action['res_id'] = client_invoices.id - return action - - # ========================================================================== - # SPLIT INVOICE CREATION (Client 25% and ADP 75%) - # ========================================================================== - def action_create_client_invoice(self): - """Create invoice for client portion (25% for REG clients, 0% for others). - - NOTE: Client invoice can be created WITHOUT device verification. - This allows clients to pay their portion and receive products before ADP approval. - Device verification is only required for ADP invoice creation. - - BLOCKING for Modification reasons: - - Modifications to NON-ADP Equipment and Modifications to ADP Equipment - require ADP approval before client invoice can be created. - - WARNING for Replacement reasons: - - If previous funding was less than 5 years ago, show warning about possible deductions. - """ - self.ensure_one() - if not self._is_adp_sale(): - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'Not an ADP Sale', - 'message': 'Client invoices are only for ADP sales.', - 'type': 'warning', - } - } - - client_type = self._get_client_type() - if client_type != 'REG': - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'No Client Portion', - 'message': f'{client_type} clients have 100% ADP funding. No client invoice needed.', - 'type': 'info', - } - } - - # ================================================================= - # BLOCKING: Modification reasons require ADP approval first - # ================================================================= - reason = self.x_fc_reason_for_application - status = self.x_fc_adp_application_status - - if reason in ('mod_non_adp', 'mod_adp'): - if status not in ('approved', 'approved_deduction'): - reason_label = dict(self._fields['x_fc_reason_for_application'].selection or []).get( - reason, reason - ) - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'ADP Approval Required', - 'message': f'Cannot create client invoice for "{reason_label}".\n\n' - f'ADP application must be approved before creating invoices for modification requests.\n\n' - f'Current status: {status or "Not set"}', - 'type': 'danger', - 'sticky': True, - } - } - - # ================================================================= - # WARNING: Replacement reasons with <5 years funding - # ================================================================= - if reason in ('replace_status', 'replace_size', 'replace_worn') and self.x_fc_under_5_years: - years = self.x_fc_years_since_funding - # Show warning but allow proceeding - self.message_post( - body=Markup( - '' - ), - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - - # NO VERIFICATION CHECK - Client invoice can be created before ADP approval - # User will need to complete verification before creating ADP invoice - - # Create client invoice (25% portion) - invoice = self._create_adp_split_invoice(invoice_type='client') - - if invoice: - result = { - 'name': 'Client Invoice (25%)', - 'type': 'ir.actions.act_window', - 'res_model': 'account.move', - 'res_id': invoice.id, - 'view_mode': 'form', - 'target': 'current', - } - return result - return True - - def action_create_adp_invoice(self): - """Create invoice for ADP portion (75% for REG clients, 100% for others). - - NOTE: Device verification MUST be completed before creating ADP invoice. - Verification can be done from the Sales Order or from the Client Invoice (if created first). - - Proof of Delivery is REQUIRED before ADP invoice creation. - """ - self.ensure_one() - if not self._is_adp_sale(): - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'Not an ADP Sale', - 'message': 'ADP invoices are only for ADP sales.', - 'type': 'warning', - } - } - - # ================================================================= - # REQUIREMENT: Proof of Delivery must be uploaded - # ================================================================= - if not self.x_fc_proof_of_delivery: - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'Proof of Delivery Required', - 'message': 'Please upload the Proof of Delivery document in the ADP Documents tab before creating the ADP invoice.', - 'type': 'danger', - 'sticky': True, - } - } - - # ================================================================= - # REQUIREMENT: Device verification MUST be complete for ADP invoice - # ================================================================= - if not self.x_fc_device_verification_complete: - # Check if there's a client invoice - provide appropriate message - client_invoice = self.env['account.move'].sudo().search([ - ('x_fc_source_sale_order_id', '=', self.id), - ('x_fc_adp_invoice_portion', '=', 'client'), - ('state', '!=', 'cancel'), - ], limit=1) - - device_count = self.x_fc_total_device_count - approved_count = self.x_fc_approved_device_count - - if device_count > 0: - device_info = f'{approved_count}/{device_count} devices verified.' - else: - device_info = 'No ADP devices detected on this order.' - - if client_invoice: - message = ( - f'Cannot create ADP invoice: Device verification is not complete.\n\n' - f'{device_info}\n\n' - f'Please complete verification from either:\n' - f'• This Sales Order: Click "Verify Device Approval"\n' - f'• Client Invoice ({client_invoice.name}): Click "Verify Device Approval"' - ) - else: - message = ( - f'Cannot create ADP invoice: Device verification is not complete.\n\n' - f'{device_info}\n\n' - f'Click "Verify Device Approval" to review which devices were approved by ADP.' - ) - - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'Device Verification Required', - 'message': message, - 'type': 'danger', - 'sticky': True, - } - } - - # ================================================================= - # REQUIREMENT: At least one device must be approved for ADP invoice - # ================================================================= - approved_count = self.x_fc_approved_device_count - total_count = self.x_fc_total_device_count - - if approved_count == 0: - if total_count > 0: - message = ( - f'Cannot create ADP invoice: No devices are approved.\n\n' - f'All {total_count} device(s) on this order were marked as NOT approved by ADP.\n\n' - f'If this is incorrect, click "Verify Device Approval" to update the approval status.' - ) - else: - message = ( - 'Cannot create ADP invoice: No ADP-funded devices found.\n\n' - 'This order has no products with ADP device codes. ' - 'ADP invoices can only be created for orders with approved ADP devices.' - ) - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'No Approved Devices', - 'message': message, - 'type': 'danger', - 'sticky': True, - } - } - - # Check for unapproved devices - show info message but allow creation - # Unapproved items will be excluded from the ADP invoice - unapproved = self._check_unapproved_devices() - unapproved_message = None - if unapproved: - device_names = ', '.join(unapproved.mapped('product_id.name')[:3]) - if len(unapproved) > 3: - device_names += f' and {len(unapproved) - 3} more' - unapproved_message = f"Note: {len(unapproved)} unapproved item(s) will be excluded: {device_names}" - - # Create ADP invoice - invoice = self._create_adp_split_invoice(invoice_type='adp') - - if invoice: - return { - 'name': 'ADP Invoice', - 'type': 'ir.actions.act_window', - 'res_model': 'account.move', - 'res_id': invoice.id, - 'view_mode': 'form', - 'target': 'current', - } - return True - - def _create_adp_split_invoice(self, invoice_type='client'): - """ - Create a split invoice for ADP sales. - - Args: - invoice_type: 'client' for client portion invoice, 'adp' for ADP portion invoice - - Returns: - account.move record - """ - self.ensure_one() - - # Re-read fresh data from the database to get current values - self.invalidate_recordset() - - # Get client type to determine percentages - client_type = self._get_client_type() - if client_type == 'REG': - client_pct = 0.25 - adp_pct = 0.75 - else: - # ODS, OWP, ACS, etc. - 100% ADP, 0% client - client_pct = 0.0 - adp_pct = 1.0 - - if invoice_type == 'client' and client_pct == 0: - return False # No client invoice for non-REG clients - - # Determine invoice label - if invoice_type == 'client': - invoice_name_suffix = f' (Client {int(client_pct*100)}%)' - else: - invoice_name_suffix = f' (ADP {int(adp_pct*100)}%)' - - # Prepare base invoice values - invoice_vals = self._prepare_invoice() - invoice_vals['invoice_origin'] = f"{self.name}{invoice_name_suffix}" - - # Add marker for invoice type and link to source sale order - invoice_vals['x_fc_adp_invoice_portion'] = invoice_type - invoice_vals['x_fc_source_sale_order_id'] = self.id - - # Copy Studio fields if they exist on the invoice model - # Use helper function to safely set values - AccountMove = self.env['account.move'] - - def safe_set_field(field_name, value, target_dict): - """Safely set a field value, checking field type and valid options.""" - if field_name not in AccountMove._fields: - return - field = AccountMove._fields[field_name] - try: - if field.type == 'boolean': - # Convert to boolean - target_dict[field_name] = bool(value) - elif field.type == 'selection': - # Check if value is valid - selection = field.selection - if callable(selection): - selection = selection(AccountMove) - valid_values = [s[0] for s in selection] if selection else [] - if value in valid_values: - target_dict[field_name] = value - elif str(value).lower() in [v.lower() for v in valid_values if isinstance(v, str)]: - # Find the matching case - for v in valid_values: - if isinstance(v, str) and v.lower() == str(value).lower(): - target_dict[field_name] = v - break - elif field.type == 'many2one': - # Handle Many2one - pass record id or False - if hasattr(value, 'id'): - target_dict[field_name] = value.id - elif value: - target_dict[field_name] = value - else: - # Char, Text, etc. - just set directly - target_dict[field_name] = value - except Exception: - pass # Skip if any error - - # Invoice type will be set based on invoice_type parameter ('adp' or 'client') - # and the sale type - handled below when setting x_fc_invoice_type - - # Copy primary serial to invoice - primary_serial = self.x_fc_primary_serial - if primary_serial: - invoice_vals['x_fc_primary_serial'] = primary_serial - - # Set invoice type based on invoice_type parameter and sale type - if invoice_type == 'client': - # Client portion invoice - set to 'adp_client' - fc_invoice_type = 'adp_client' - else: - # ADP/Funder portion invoice - use the sale type directly - # This preserves the sale type context (ADP, ADP/ODSP, ODSP, WSIB, etc.) - sale_type = self.x_fc_sale_type or 'adp' - # For ADP-related sale types, use the sale type as invoice type - fc_invoice_type = sale_type - - # For ADP invoices: Change customer to ADP contact, keep original client as delivery address - original_partner = self.partner_id - original_delivery = self.partner_shipping_id or self.partner_id - - # Find the ADP contact (search by name) - adp_partner = self.env['res.partner'].sudo().search([ - '|', '|', '|', - ('name', 'ilike', 'ADP (Assistive Device Program)'), - ('name', 'ilike', 'Assistive Device Program'), - ('name', '=', 'ADP'), - ('name', 'ilike', 'ADP -'), - ], limit=1) - - if adp_partner: - # Set ADP as the invoice customer - invoice_vals['partner_id'] = adp_partner.id - # Keep original client as delivery address - invoice_vals['partner_shipping_id'] = original_partner.id - - invoice_vals.update({ - 'x_fc_invoice_type': fc_invoice_type, - 'x_fc_client_type': self._get_client_type(), - 'x_fc_claim_number': self.x_fc_claim_number, - 'x_fc_client_ref_1': self.x_fc_client_ref_1, - 'x_fc_client_ref_2': self.x_fc_client_ref_2, - 'x_fc_adp_delivery_date': self.x_fc_adp_delivery_date, - 'x_fc_service_start_date': self.x_fc_service_start_date, - 'x_fc_service_end_date': self.x_fc_service_end_date, - 'x_fc_authorizer_id': self.x_fc_authorizer_id.id if self.x_fc_authorizer_id else False, - # Set ADP billing status to 'waiting' by default for ADP invoices - 'x_fc_adp_billing_status': 'waiting' if invoice_type == 'adp' else 'not_applicable', - }) - - # Create invoice - invoice = self.env['account.move'].sudo().create(invoice_vals) - - # Create invoice lines - include sections, notes, AND products - # - # PORTION CALCULATION: - # - Get ADP price from device codes database (priority) or product field - # - Calculate portions based on client type: REG = 75%/25%, Others = 100%/0% - # - Client Invoice: price_unit = client portion per unit - # - ADP Invoice: price_unit = ADP portion per unit - # - Both portions stored on line for reference - # - ADPDevice = self.env['fusion.adp.device.code'].sudo() - invoice_lines = [] - price_mismatches = [] # Track products with price mismatches - - for line in self.order_line: - # For section and note lines, create minimal line - if line.display_type in ('line_section', 'line_note'): - invoice_lines.append({ - 'move_id': invoice.id, - 'display_type': line.display_type, - 'name': line.name, - 'sequence': line.sequence, - }) - continue - - # Skip lines without products or zero quantity - if not line.product_id or line.product_uom_qty <= 0: - continue - - # ================================================================= - # CHECK 1: Is this a NON-ADP funded product? - # ================================================================= - is_non_adp_funded = line.product_id.is_non_adp_funded() - - # ================================================================= - # CHECK 2: Get ADP device info from database - # ================================================================= - device_code = line._get_adp_device_code() - adp_device = None - is_adp_device = False - db_adp_price = 0 - - if device_code and not is_non_adp_funded: - adp_device = ADPDevice.search([ - ('device_code', '=', device_code), - ('active', '=', True) - ], limit=1) - is_adp_device = bool(adp_device) - if adp_device: - db_adp_price = adp_device.adp_price or 0 - - # Determine if item is approved - is_approved = line.x_fc_adp_approved - - # ================================================================= - # GET ADP PRICE - Priority: DB > Product Field > Line Price - # ================================================================= - product_tmpl = line.product_id.product_tmpl_id - product_adp_price = 0 - - # Try product fields - if hasattr(product_tmpl, 'x_fc_adp_price'): - product_adp_price = getattr(product_tmpl, 'x_fc_adp_price', 0) or 0 - # Determine final ADP price to use - if db_adp_price > 0: - adp_max_price = db_adp_price - # Check for price mismatch - if product_adp_price > 0 and abs(db_adp_price - product_adp_price) > 0.01: - price_mismatches.append({ - 'product': line.product_id, - 'device_code': device_code, - 'db_price': db_adp_price, - 'product_price': product_adp_price, - }) - elif product_adp_price > 0: - adp_max_price = product_adp_price - else: - # Fallback to selling price - adp_max_price = line.price_unit - - # ================================================================= - # CALCULATE PORTIONS based on client type - # ================================================================= - qty = line.product_uom_qty - total_adp_base = adp_max_price * qty - - if is_non_adp_funded or not is_adp_device: - # NON-ADP item: Client pays 100% - adp_portion = 0 - client_portion = line.price_subtotal - is_full_client = True - elif is_adp_device and not is_approved: - # ADP device NOT approved: Client pays 100% - adp_portion = 0 - client_portion = line.price_subtotal - is_full_client = True - else: - # ADP device APPROVED: Calculate based on client type - is_full_client = False - if client_type == 'REG': - adp_portion = total_adp_base * 0.75 - client_portion = total_adp_base * 0.25 - else: - # ODS, OWP, ACS, etc. = 100% ADP - adp_portion = total_adp_base - client_portion = 0 - - # Apply deductions if any - if line.x_fc_deduction_type == 'pct' and line.x_fc_deduction_value: - # PCT deduction: ADP pays X% of their normal portion - effective_pct = line.x_fc_deduction_value / 100 - if client_type == 'REG': - adp_portion = total_adp_base * 0.75 * effective_pct - else: - adp_portion = total_adp_base * effective_pct - client_portion = total_adp_base - adp_portion - elif line.x_fc_deduction_type == 'amt' and line.x_fc_deduction_value: - # AMT deduction: Fixed amount deducted from ADP - adp_portion = max(0, adp_portion - line.x_fc_deduction_value) - client_portion = total_adp_base - adp_portion - - # ================================================================= - # DETERMINE INVOICE LINE AMOUNT - # ================================================================= - if invoice_type == 'client': - if is_full_client: - portion_amount = client_portion - line_name = line.name if not (is_adp_device and not is_approved) else f"{line.name} [NOT APPROVED - 100% Client]" - else: - portion_amount = client_portion - line_name = line.name - else: # ADP invoice - if is_non_adp_funded or not is_adp_device or (is_adp_device and not is_approved): - # Skip from ADP invoice - continue - portion_amount = adp_portion - line_name = line.name - - # Calculate adjusted price per unit - adjusted_price = portion_amount / qty if qty else 0 - - # Build invoice line vals - line_vals = { - 'move_id': invoice.id, - 'product_id': line.product_id.id, - 'name': line_name, - 'quantity': qty, - 'product_uom_id': line.product_uom_id.id, - 'price_unit': adjusted_price, - 'discount': line.discount, - 'tax_ids': [(6, 0, line.tax_ids.ids)], - 'sale_line_ids': [(6, 0, [line.id])], - 'sequence': line.sequence, - } - - # Copy serial number and other fields - if 'x_fc_serial_number' in self.env['account.move.line']._fields: - line_vals['x_fc_serial_number'] = line.x_fc_serial_number - if 'x_fc_device_placement' in self.env['account.move.line']._fields: - line_vals['x_fc_device_placement'] = line.x_fc_device_placement - - # Store BOTH portions on invoice line (for display) - if 'x_fc_adp_portion' in self.env['account.move.line']._fields: - line_vals['x_fc_adp_portion'] = adp_portion - if 'x_fc_client_portion' in self.env['account.move.line']._fields: - line_vals['x_fc_client_portion'] = client_portion - if 'x_fc_adp_max_price' in self.env['account.move.line']._fields: - line_vals['x_fc_adp_max_price'] = adp_max_price - if 'x_fc_adp_approved' in self.env['account.move.line']._fields: - line_vals['x_fc_adp_approved'] = is_approved - if 'x_fc_adp_device_type' in self.env['account.move.line']._fields and adp_device: - line_vals['x_fc_adp_device_type'] = adp_device.device_type or '' - - invoice_lines.append(line_vals) - - if invoice_lines: - self.env['account.move.line'].sudo().create(invoice_lines) - - # ================================================================= - # POST PRICE MISMATCH WARNINGS - # ================================================================= - if price_mismatches: - mismatch_msg = '

      ⚠️ ADP Price Mismatches Detected

        ' - for pm in price_mismatches: - mismatch_msg += ( - f'
      • {pm["product"].name} ({pm["device_code"]}): ' - f'Product price ${pm["product_price"]:.2f} vs Database ${pm["db_price"]:.2f}
      • ' - ) - mismatch_msg += '

      Database prices were used. Consider updating product prices.

      ' - self.message_post(body=mismatch_msg, message_type='notification', subtype_xmlid='mail.mt_note') - - # Auto-update product prices from database - for pm in price_mismatches: - product_tmpl = pm['product'].product_tmpl_id - if hasattr(product_tmpl, 'x_fc_adp_price'): - product_tmpl.sudo().write({'x_fc_adp_price': pm['db_price']}) - - # ================================================================= - # POST INVOICE CREATION MESSAGE TO CHATTER - # ================================================================= - if invoice and invoice_lines: - # Calculate totals from the created invoice - invoice.invalidate_recordset() - invoice_total = invoice.amount_total - - # Calculate portion totals from the lines we just created - total_adp_portion = sum( - line_vals.get('x_fc_adp_portion', 0) - for line_vals in invoice_lines - if isinstance(line_vals, dict) and 'x_fc_adp_portion' in line_vals - ) - total_client_portion = sum( - line_vals.get('x_fc_client_portion', 0) - for line_vals in invoice_lines - if isinstance(line_vals, dict) and 'x_fc_client_portion' in line_vals - ) - - user_name = self.env.user.name - create_date = fields.Date.today().strftime('%B %d, %Y') - client_name = self.partner_id.name or 'N/A' - - if invoice_type == 'client': - # Client Invoice - Blue theme using Bootstrap - pct_label = f'{int(client_pct*100)}%' - - invoice_msg = Markup(f'''''') - else: - # ADP Invoice - Green theme using Bootstrap - pct_label = f'{int(adp_pct*100)}%' - - invoice_msg = Markup(f'''''') - - self.message_post( - body=invoice_msg, - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - - return invoice - - # ========================================================================== - # OVERRIDE _get_invoiceable_lines TO INCLUDE ALL SECTIONS AND NOTES - # ========================================================================== - def _get_invoiceable_lines(self, final=False): - """Override to ensure ALL sections and notes are included in invoices. - - Standard Odoo behavior only includes sections/notes if they have invoiceable - product lines AFTER them. This causes warranty, refund policy, and other - important sections at the end of the order to be dropped from invoices. - - This override includes all sections and notes regardless of position. - """ - # Get the standard invoiceable lines first - invoiceable_lines = super()._get_invoiceable_lines(final) - - # Collect all section and note lines from the order - all_display_lines = self.order_line.filtered( - lambda l: l.display_type in ('line_section', 'line_subsection', 'line_note') - ) - - # Add any sections/notes that weren't included by the standard method - missing_display_lines = all_display_lines - invoiceable_lines - - if missing_display_lines: - # Combine and sort by sequence to maintain order - combined = invoiceable_lines | missing_display_lines - return combined.sorted(key=lambda l: l.sequence) - - return invoiceable_lines - - # ========================================================================== - # INVOICE PREPARATION (Copy ADP fields to Invoice) - # ========================================================================== - def _prepare_invoice(self): - """Override to copy ADP fields to the invoice.""" - vals = super()._prepare_invoice() - if self._is_adp_sale(): - # Normalize sale type to match x_fc_invoice_type selection (lowercase) - sale_type_raw = self.x_fc_sale_type or '' - sale_type_normalized = str(sale_type_raw).lower() if sale_type_raw else 'adp' - valid_types = ('adp', 'adp_odsp', 'odsp', 'wsib', 'direct_private', 'insurance', - 'march_of_dimes', 'muscular_dystrophy', 'other', 'rental') - if sale_type_normalized not in valid_types: - if 'adp' in sale_type_normalized: - sale_type_normalized = 'adp' - else: - sale_type_normalized = 'other' - - vals.update({ - 'x_fc_invoice_type': sale_type_normalized, - 'x_fc_client_type': self.x_fc_client_type, - 'x_fc_claim_number': self.x_fc_claim_number, - 'x_fc_client_ref_1': self.x_fc_client_ref_1, - 'x_fc_client_ref_2': self.x_fc_client_ref_2, - 'x_fc_adp_delivery_date': self.x_fc_adp_delivery_date, - 'x_fc_service_start_date': self.x_fc_service_start_date, - 'x_fc_service_end_date': self.x_fc_service_end_date, - 'x_fc_authorizer_id': self.x_fc_authorizer_id.id if self.x_fc_authorizer_id else False, - }) - return vals - - # ========================================================================== - # DOCUMENT CHATTER POSTING - # ========================================================================== - def _post_document_to_chatter(self, field_name, document_label=None): - """Post a document attachment to the chatter with a link. - - Args: - field_name: The binary field name (e.g., 'x_fc_final_submitted_application') - document_label: Optional label for the document (defaults to field string) - """ - self.ensure_one() - - # Map field names to filename fields - filename_mapping = { - 'x_fc_original_application': 'x_fc_original_application_filename', - 'x_fc_signed_pages_11_12': 'x_fc_signed_pages_filename', - 'x_fc_final_submitted_application': 'x_fc_final_application_filename', - 'x_fc_xml_file': 'x_fc_xml_filename', - 'x_fc_proof_of_delivery': 'x_fc_proof_of_delivery_filename', - } - - data_field = field_name - filename_field = filename_mapping.get(field_name, field_name + '_filename') - - data = getattr(self, data_field, None) - original_filename = getattr(self, filename_field, None) or 'document' - - if not data: - return - - # Get document label from field definition if not provided - if not document_label: - field_obj = self._fields.get(data_field) - document_label = field_obj.string if field_obj else data_field - - # Check for existing attachments with same name for revision numbering - existing_count = self.env['ir.attachment'].sudo().search_count([ - ('res_model', '=', 'sale.order'), - ('res_id', '=', self.id), - ('name', '=like', original_filename.rsplit('.', 1)[0] + '%'), - ]) - - # Add revision number if this is a replacement - if existing_count > 0 and '(replaced)' in (document_label or ''): - # This is an old document being replaced - add revision number - base_name, ext = original_filename.rsplit('.', 1) if '.' in original_filename else (original_filename, '') - filename = f"R{existing_count}_{base_name}.{ext}" if ext else f"R{existing_count}_{base_name}" - else: - filename = original_filename - - # Create attachment with the original/revised filename - attachment = self.env['ir.attachment'].sudo().create({ - 'name': filename, - 'datas': data, - 'res_model': 'sale.order', - 'res_id': self.id, - }) - - # Post message with attachment (shows as native Odoo attachment with preview) - user_name = self.env.user.name - now = fields.Datetime.now() - - body = Markup(""" -

      {label} uploaded by {user}

      -

      {timestamp}

      - """).format( - label=document_label, - user=user_name, - timestamp=now.strftime('%Y-%m-%d %H:%M:%S') - ) - - # Use attachment_ids to show as native attachment with preview capability - self.message_post( - body=body, - message_type='notification', - subtype_xmlid='mail.mt_note', - attachment_ids=[attachment.id], - ) - - return attachment - - # ========================================================================== - # AUTOMATIC EMAIL SENDING - # ========================================================================== - - def _is_email_notifications_enabled(self): - """Check if email notifications are enabled in settings.""" - ICP = self.env['ir.config_parameter'].sudo() - return ICP.get_param('fusion_claims.enable_email_notifications', 'True').lower() in ('true', '1', 'yes') - - def _get_office_cc_emails(self): - """Get office notification emails from company settings.""" - company = self.company_id or self.env.company - partners = company.sudo().x_fc_office_notification_ids - return [p.email for p in partners if p.email] - - def _get_email_recipients(self, include_client=False, include_authorizer=True, include_sales_rep=True): - """Get standard email recipients for ADP notifications. - - Returns dict with: - - 'to': List of primary recipient emails - - 'cc': List of CC recipient emails - - 'office_cc': List of office CC emails from settings - """ - self.ensure_one() - to_emails = [] - cc_emails = [] - - # Get authorizer - authorizer = self.x_fc_authorizer_id - - # Get sales rep - sales_rep = self.user_id - - # Get client - client = self.partner_id - - # Build recipient lists - if include_client and client and client.email: - to_emails.append(client.email) - - if include_authorizer and authorizer and authorizer.email: - if to_emails: - cc_emails.append(authorizer.email) - else: - to_emails.append(authorizer.email) - - if include_sales_rep and sales_rep and sales_rep.email: - cc_emails.append(sales_rep.email) - - # Get office CC emails - office_cc = self._get_office_cc_emails() - - return { - 'to': to_emails, - 'cc': cc_emails, - 'office_cc': office_cc, - 'authorizer': authorizer, - 'sales_rep': sales_rep, - 'client': client, - } - - def _check_authorizer_portal_access(self): - """Check if authorizer has logged into portal. - - Returns True if authorizer has a portal user with a password set. - """ - self.ensure_one() - authorizer = self.x_fc_authorizer_id - - if not authorizer: - return False - - # Find portal user for this partner - portal_user = self.env['res.users'].sudo().search([ - ('partner_id', '=', authorizer.id), - ('share', '=', True), # Portal users have share=True - ], limit=1) - - if not portal_user: - return False - - # Check if user has logged in (has password and has login date) - return bool(portal_user.login_date) - - def _build_case_detail_rows(self, include_amounts=False): - """Build standard case detail rows for email templates.""" - self.ensure_one() - - def fmt(d): - return d.strftime('%B %d, %Y') if d else None - - rows = [ - ('Case', self.name), - ('Client', self.partner_id.name or 'N/A'), - ('Claim Number', self.x_fc_claim_number or None), - ('Client Ref 1', self.x_fc_client_ref_1 or None), - ('Client Ref 2', self.x_fc_client_ref_2 or None), - ('Assessment Date', fmt(self.x_fc_assessment_end_date)), - ('Submission Date', fmt(self.x_fc_claim_submission_date)), - ('Approval Date', fmt(self.x_fc_claim_approval_date)), - ('Delivery Date', fmt(self.x_fc_adp_delivery_date)), - ] - if include_amounts: - rows.extend([ - ('ADP Portion', f'${self.x_fc_adp_portion_total or 0:,.2f}'), - ('Client Portion', f'${self.x_fc_client_portion_total or 0:,.2f}'), - ('Total', f'${self.amount_total:,.2f}'), - ]) - # Filter out None values - return [(l, v) for l, v in rows if v is not None] - - def _email_chatter_log(self, label, email_to, email_cc=None, extra_lines=None): - """Post a concise chatter note confirming an email was sent.""" - lines = [f'
    1. To: {email_to}
    2. '] - if email_cc: - lines.append(f'
    3. CC: {email_cc}
    4. ') - if extra_lines: - for line in extra_lines: - lines.append(f'
    5. {line}
    6. ') - body = Markup( - '' - ) - self.message_post(body=body, message_type='notification', subtype_xmlid='mail.mt_note') - - def _send_submission_email(self): - """Send email when application is submitted with PDF and XML attachments.""" - self.ensure_one() - if not self._is_email_notifications_enabled(): - return False - - recipients = self._get_email_recipients(include_client=True, include_authorizer=True, include_sales_rep=True) - to_emails = recipients.get('to', []) - cc_emails = recipients.get('cc', []) + recipients.get('office_cc', []) - if not to_emails and not cc_emails: - return False - - # Reuse existing field attachments (created by Odoo for attachment=True fields) - # instead of creating duplicates - attachments = [] - attachment_names = [] - Attachment = self.env['ir.attachment'].sudo() - if self.x_fc_final_submitted_application: - att = Attachment.search([ - ('res_model', '=', 'sale.order'), - ('res_id', '=', self.id), - ('res_field', '=', 'x_fc_final_submitted_application'), - ], order='id desc', limit=1) - if att: - attachments.append(att.id) - attachment_names.append('Final ADP Application (PDF)') - if self.x_fc_xml_file: - att = Attachment.search([ - ('res_model', '=', 'sale.order'), - ('res_id', '=', self.id), - ('res_field', '=', 'x_fc_xml_file'), - ], order='id desc', limit=1) - if att: - attachments.append(att.id) - attachment_names.append('XML Data File') - - client_name = recipients.get('client', self.partner_id).name or 'Client' - sales_rep_name = (recipients.get('sales_rep') or self.env.user).name - submission_date = self.x_fc_claim_submission_date.strftime('%B %d, %Y') if self.x_fc_claim_submission_date else 'Today' - - body_html = self._email_build( - title='Application Submitted', - summary=f'The ADP application for {client_name} has been submitted on {submission_date}.', - email_type='info', - sections=[('Case Details', self._build_case_detail_rows())], - note='What happens next: The Assistive Devices Program will review the application. ' - 'This typically takes 2-4 weeks. We will notify you as soon as we receive a decision.', - attachments_note=', '.join(attachment_names) if attachment_names else None, - button_url=f'{self.get_base_url()}/web#id={self.id}&model=sale.order&view_type=form', - sender_name=sales_rep_name, - ) - - email_to = ', '.join(to_emails) if to_emails else ', '.join(cc_emails[:1]) - email_cc = ', '.join(cc_emails) if to_emails else ', '.join(cc_emails[1:]) - try: - mail = self.env['mail.mail'].sudo().create({ - 'subject': f'Application Submitted - {client_name} - {self.name}', - 'body_html': body_html, - 'email_to': email_to, 'email_cc': email_cc, - 'model': 'sale.order', 'res_id': self.id, - 'attachment_ids': [(6, 0, attachments)] if attachments else False, - }) - mail.send() - self._email_chatter_log('Application Submitted email sent', email_to, email_cc, - [f'Attachments: {", ".join(attachment_names)}'] if attachment_names else None) - _logger.info(f"Submission email sent for {self.name}") - return True - except Exception as e: - _logger.error(f"Failed to send submission email for {self.name}: {e}") - return False - - @api.model - def _cron_send_application_reminders(self): - """Cron job: Find assessments completed X days ago without application and send reminders.""" - from datetime import timedelta - - if not self._is_email_notifications_enabled(): - _logger.info("Email notifications disabled, skipping application reminders") - return - - # Get reminder days from settings (default 4) - ICP = self.env['ir.config_parameter'].sudo() - reminder_days = int(ICP.get_param('fusion_claims.application_reminder_days', '4')) - - # Calculate target date (X days ago) - target_date = fields.Date.today() - timedelta(days=reminder_days) - - # Find orders where: - # - Assessment completed on target date (x_fc_assessment_end_date = target_date) - # - Status is still 'waiting_for_application' (no application received yet) - # - Not already reminded (we'll track this with x_fc_application_reminder_sent) - orders = self.search([ - ('x_fc_assessment_end_date', '=', target_date), - ('x_fc_adp_application_status', 'in', ['waiting_for_application', 'assessment_completed']), - ('x_fc_application_reminder_sent', '=', False), - ]) - - _logger.info(f"Application reminder cron: Found {len(orders)} orders to remind (assessed on {target_date})") - - for order in orders: - try: - order._send_application_reminder_email() - except Exception as e: - _logger.error(f"Failed to send application reminder for {order.name}: {e}") - - def _send_application_reminder_email(self): - """Send reminder to therapist to submit ADP application.""" - self.ensure_one() - if not self._is_email_notifications_enabled(): - return False - - authorizer = self.x_fc_authorizer_id - if not authorizer or not authorizer.email: - return False - - client_name = self.partner_id.name or 'the client' - assessment_date = self.x_fc_assessment_end_date.strftime('%B %d, %Y') if self.x_fc_assessment_end_date else 'recently' - sales_rep_name = self.user_id.name if self.user_id else 'The Sales Team' - - body_html = self._email_build( - title='Application Reminder', - summary=f'The assessment for {client_name} was completed on {assessment_date}. ' - f'We have not yet received the ADP application documents.', - email_type='attention', - sections=[('Case Details', self._build_case_detail_rows())], - note='Action needed: Please submit the completed ADP application ' - '(including pages 11-12 signed by the client) so we can proceed with the claim submission.', - note_color='#d69e2e', - button_url=f'{self.get_base_url()}/web#id={self.id}&model=sale.order&view_type=form', - sender_name=sales_rep_name, - ) - - recipients = self._get_email_recipients(include_client=False, include_authorizer=True, include_sales_rep=True) - all_cc = recipients.get('cc', []) + recipients.get('office_cc', []) - email_cc = ', '.join(all_cc) if all_cc else '' - - try: - mail = self.env['mail.mail'].sudo().create({ - 'subject': f'Application Reminder - {client_name} - {self.name}', - 'body_html': body_html, - 'email_to': authorizer.email, 'email_cc': email_cc, - 'model': 'sale.order', 'res_id': self.id, - }) - mail.send() - self.with_context(skip_all_validations=True).write({'x_fc_application_reminder_sent': True}) - self._email_chatter_log('Application Reminder sent', authorizer.email, email_cc) - return True - except Exception as e: - _logger.error(f"Failed to send application reminder for {self.name}: {e}") - return False - - @api.model - def _cron_send_application_reminders_2(self): - """Cron job: Send second reminder X days after first reminder was sent.""" - from datetime import timedelta - - if not self._is_email_notifications_enabled(): - _logger.info("Email notifications disabled, skipping second application reminders") - return - - # Get reminder days from settings - ICP = self.env['ir.config_parameter'].sudo() - first_reminder_days = int(ICP.get_param('fusion_claims.application_reminder_days', '4')) - second_reminder_days = int(ICP.get_param('fusion_claims.application_reminder_2_days', '4')) - - # Calculate target date: assessment_end_date + first_reminder_days + second_reminder_days - total_days = first_reminder_days + second_reminder_days - target_date = fields.Date.today() - timedelta(days=total_days) - - # Find orders where: - # - Assessment completed on target date - # - First reminder was sent - # - Second reminder not yet sent - # - Status still waiting for application - orders = self.search([ - ('x_fc_assessment_end_date', '=', target_date), - ('x_fc_adp_application_status', 'in', ['waiting_for_application', 'assessment_completed']), - ('x_fc_application_reminder_sent', '=', True), - ('x_fc_application_reminder_2_sent', '=', False), - ]) - - _logger.info(f"Second application reminder cron: Found {len(orders)} orders to remind (assessed on {target_date})") - - for order in orders: - try: - order._send_application_reminder_2_email() - except Exception as e: - _logger.error(f"Failed to send second application reminder for {order.name}: {e}") - - def _send_application_reminder_2_email(self): - """Send second/follow-up reminder to therapist to submit ADP application.""" - self.ensure_one() - if not self._is_email_notifications_enabled(): - return False - - authorizer = self.x_fc_authorizer_id - if not authorizer or not authorizer.email: - return False - - client_name = self.partner_id.name or 'the client' - assessment_date = self.x_fc_assessment_end_date.strftime('%B %d, %Y') if self.x_fc_assessment_end_date else 'recently' - days_since = (fields.Date.today() - self.x_fc_assessment_end_date).days if self.x_fc_assessment_end_date else 'several' - sales_rep_name = self.user_id.name if self.user_id else 'The Sales Team' - - body_html = self._email_build( - title='Follow-up: Application Needed', - summary=f'It has been {days_since} days since the assessment for ' - f'{client_name} was completed on {assessment_date}. ' - f'We have not yet received the ADP application.', - email_type='attention', - sections=[('Case Details', self._build_case_detail_rows())], - note='Assessment validity: ADP assessments are valid for 90 days. ' - 'To avoid delays or the need for a new assessment, please submit the application ' - 'as soon as possible.', - note_color='#d69e2e', - button_url=f'{self.get_base_url()}/web#id={self.id}&model=sale.order&view_type=form', - sender_name=sales_rep_name, - ) - - all_cc = [] - if self.user_id and self.user_id.email: - all_cc.append(self.user_id.email) - all_cc.extend(self._get_office_cc_emails()) - email_cc = ', '.join(all_cc) if all_cc else '' - - try: - mail = self.env['mail.mail'].sudo().create({ - 'subject': f'Follow-up: Application Needed - {client_name} - {self.name}', - 'body_html': body_html, - 'email_to': authorizer.email, 'email_cc': email_cc, - 'model': 'sale.order', 'res_id': self.id, - }) - mail.send() - self.with_context(skip_all_validations=True).write({'x_fc_application_reminder_2_sent': True}) - self._email_chatter_log('Follow-up Reminder sent', authorizer.email, email_cc, - [f'Days since assessment: {days_since}']) - return True - except Exception as e: - _logger.error(f"Failed to send second reminder for {self.name}: {e}") - return False - - def _send_billed_summary_email(self): - """Send summary email when order is billed to ADP.""" - self.ensure_one() - authorizer = self.x_fc_authorizer_id - sales_rep = self.user_id - email_list = [] - if authorizer and authorizer.email: - email_list.append(authorizer.email) - if sales_rep and sales_rep.email: - email_list.append(sales_rep.email) - if not email_list: - return False - - client_name = self.partner_id.name or 'Client' - body_html = self._email_build( - title='Billing Complete', - summary=f'The ADP claim for {client_name} has been successfully billed.', - email_type='success', - sections=[ - ('Case Details', self._build_case_detail_rows(include_amounts=True)), - ], - note='This case has been billed. Thank you for your collaboration.', - note_color='#38a169', - button_url=f'{self.get_base_url()}/web#id={self.id}&model=sale.order&view_type=form', - sender_name=(sales_rep.name if sales_rep else None), - ) - email_to = ', '.join(email_list) - try: - mail = self.env['mail.mail'].sudo().create({ - 'subject': f'Billing Complete - {client_name} - {self.name}', - 'body_html': body_html, 'email_to': email_to, - 'model': 'sale.order', 'res_id': self.id, - }) - mail.send() - self._email_chatter_log('Billing Complete email sent', email_to) - return True - except Exception as e: - _logger.error(f"Failed to send billed email for {self.name}: {e}") - return False - - def _send_approval_email(self): - """Send notification when ADP application is approved.""" - self.ensure_one() - if not self._is_email_notifications_enabled(): - return False - recipients = self._get_email_recipients(include_client=True, include_authorizer=True, include_sales_rep=True) - to_emails = recipients.get('to', []) - cc_emails = recipients.get('cc', []) + recipients.get('office_cc', []) - if not to_emails: - return False - client_name = (recipients.get('client') or self.partner_id).name or 'Client' - sales_rep_name = (recipients.get('sales_rep') or self.env.user).name - is_deduction = self.x_fc_adp_application_status == 'approved_deduction' - status_label = 'Approved with Deduction' if is_deduction else 'Approved' - note_text = ( - 'Next steps: Our team will be in touch shortly to schedule ' - 'the delivery of your equipment.' - ) - if is_deduction: - note_text = ( - 'Note: This application was approved with a deduction. ' - 'The final amounts may differ from the original request. Our team will ' - 'contact you with the details and next steps for delivery.' - ) - - body_html = self._email_build( - title='Application Approved', - summary=f'The ADP application for {client_name} has been ' - f'{status_label.lower()}.', - email_type='success', - sections=[('Case Details', self._build_case_detail_rows(include_amounts=True))], - note=note_text, - note_color='#38a169', - button_url=f'{self.get_base_url()}/web#id={self.id}&model=sale.order&view_type=form', - sender_name=sales_rep_name, - ) - email_to = ', '.join(to_emails) - email_cc = ', '.join(cc_emails) if cc_emails else '' - try: - self.env['mail.mail'].sudo().create({ - 'subject': f'Application {status_label} - {client_name} - {self.name}', - 'body_html': body_html, - 'email_to': email_to, 'email_cc': email_cc, - 'model': 'sale.order', 'res_id': self.id, - }).send() - self._email_chatter_log(f'Application {status_label} email sent', email_to, email_cc) - return True - except Exception as e: - _logger.error(f"Failed to send approval email for {self.name}: {e}") - return False - - def _send_denial_email(self): - """Send notification when ADP application is denied (funding denied).""" - self.ensure_one() - if not self._is_email_notifications_enabled(): - return False - recipients = self._get_email_recipients(include_client=True, include_authorizer=True, include_sales_rep=True) - to_emails = recipients.get('to', []) - cc_emails = recipients.get('cc', []) + recipients.get('office_cc', []) - if not to_emails: - return False - client_name = (recipients.get('client') or self.partner_id).name or 'Client' - sales_rep_name = (recipients.get('sales_rep') or self.env.user).name - - body_html = self._email_build( - title='Application Update', - summary=f'The ADP application for {client_name} was not approved at this time.', - email_type='urgent', - sections=[('Case Details', self._build_case_detail_rows())], - note='Your options: You may request a detailed explanation, ' - 'submit an appeal if you believe the decision was made in error, or explore ' - 'alternative funding options. Our team is here to help.', - note_color='#c53030', - button_url=f'{self.get_base_url()}/web#id={self.id}&model=sale.order&view_type=form', - sender_name=sales_rep_name, - ) - email_to = ', '.join(to_emails) - email_cc = ', '.join(cc_emails) if cc_emails else '' - try: - self.env['mail.mail'].sudo().create({ - 'subject': f'Application Update - {client_name} - {self.name}', - 'body_html': body_html, - 'email_to': email_to, 'email_cc': email_cc, - 'model': 'sale.order', 'res_id': self.id, - }).send() - self._email_chatter_log('Application Denied email sent', email_to, email_cc) - return True - except Exception as e: - _logger.error(f"Failed to send denial email for {self.name}: {e}") - return False - - def _send_rejection_email(self): - """Send notification when ADP rejects the submission (data errors, not funding denial).""" - self.ensure_one() - if not self._is_email_notifications_enabled(): - return False - recipients = self._get_email_recipients(include_client=False, include_authorizer=True, include_sales_rep=True) - to_emails = recipients.get('to', []) - cc_emails = recipients.get('cc', []) + recipients.get('office_cc', []) - if not to_emails: - return False - - client_name = self.partner_id.name or 'the client' - sales_rep_name = (recipients.get('sales_rep') or self.env.user).name - rejection_reason_labels = { - 'name_correction': 'Name Correction Needed', - 'healthcard_correction': 'Health Card Correction Needed', - 'duplicate_claim': 'Duplicate Claim Exists', - 'xml_format_error': 'XML Format/Validation Error', - 'missing_info': 'Missing Required Information', - 'other': 'Other', - } - rejection_reason = self.x_fc_rejection_reason or 'other' - rejection_label = rejection_reason_labels.get(rejection_reason, rejection_reason) - rejection_details = self.x_fc_rejection_reason_other or '' - note_text = f'Reason: {rejection_label}' - # PLACEHOLDER_REJECTION_START -- marker removed - if rejection_details: - note_text += f'
      {rejection_details}' - - body_html = self._email_build( - title='Action Required: Submission Returned', - summary=f'The ADP submission for {client_name} has been returned and needs correction.', - email_type='urgent', - sections=[('Case Details', self._build_case_detail_rows())], - note=note_text, - note_color='#c53030', - button_url=f'{self.get_base_url()}/web#id={self.id}&model=sale.order&view_type=form', - sender_name=sales_rep_name, - ) - email_to = ', '.join(to_emails) - email_cc = ', '.join(cc_emails) if cc_emails else '' - try: - self.env['mail.mail'].sudo().create({ - 'subject': f'Action Required: Submission Returned - {client_name} - {self.name}', - 'body_html': body_html, - 'email_to': email_to, 'email_cc': email_cc, - 'model': 'sale.order', 'res_id': self.id, - }).send() - self._email_chatter_log('Submission Returned email sent', email_to, email_cc, - [f'Reason: {rejection_label}']) - return True - except Exception as e: - _logger.error(f"Failed to send rejection email for {self.name}: {e}") - return False - - def _send_correction_needed_email(self, reason=None): - """Send notification when ADP application needs correction.""" - self.ensure_one() - if not self._is_email_notifications_enabled(): - return False - recipients = self._get_email_recipients(include_client=True, include_authorizer=True, include_sales_rep=True) - to_emails = recipients.get('to', []) - cc_emails = recipients.get('cc', []) + recipients.get('office_cc', []) - if not to_emails: - return False - client_name = self.partner_id.name or 'the client' - sales_rep_name = (recipients.get('sales_rep') or self.env.user).name - - note_text = 'Action needed: Please review the application, make the necessary corrections, and resubmit.' - if reason: - note_text = f'Reason for correction: {reason}

      {note_text}' - - body_html = self._email_build( - title='Correction Needed', - summary=f'The ADP application for {client_name} requires corrections before resubmission.', - email_type='attention', - sections=[('Case Details', self._build_case_detail_rows())], - note=note_text, - note_color='#d69e2e', - button_url=f'{self.get_base_url()}/web#id={self.id}&model=sale.order&view_type=form', - sender_name=sales_rep_name, - ) - email_to = ', '.join(to_emails) - email_cc = ', '.join(cc_emails) if cc_emails else '' - try: - self.env['mail.mail'].sudo().create({ - 'subject': f'Correction Needed - {client_name} - {self.name}', - 'body_html': body_html, - 'email_to': email_to, 'email_cc': email_cc, - 'model': 'sale.order', 'res_id': self.id, - }).send() - self._email_chatter_log('Correction Needed email sent', email_to, email_cc) - return True - except Exception as e: - _logger.error(f"Failed to send correction email for {self.name}: {e}") - return False - - def _send_case_closed_email(self): - """Send summary email when case is closed.""" - self.ensure_one() - if not self._is_email_notifications_enabled(): - return False - recipients = self._get_email_recipients(include_client=True, include_authorizer=True, include_sales_rep=True) - to_emails = recipients.get('to', []) - cc_emails = recipients.get('cc', []) + recipients.get('office_cc', []) - if not to_emails and not cc_emails: - return False - client_name = (recipients.get('client') or self.partner_id).name or 'Client' - sales_rep_name = (recipients.get('sales_rep') or self.env.user).name - - body_html = self._email_build( - title='Case Closed', - summary=f'The ADP case for {client_name} has been completed and closed.', - email_type='success', - sections=[('Case Summary', self._build_case_detail_rows(include_amounts=True))], - note='This case is now closed. All equipment has been delivered and billing is complete. ' - 'Thank you for your collaboration throughout the process.', - note_color='#38a169', - button_url=f'{self.get_base_url()}/web#id={self.id}&model=sale.order&view_type=form', - sender_name=sales_rep_name, - ) - email_to = ', '.join(to_emails) if to_emails else ', '.join(cc_emails[:1]) - email_cc = ', '.join(cc_emails) if to_emails else ', '.join(cc_emails[1:]) - try: - self.env['mail.mail'].sudo().create({ - 'subject': f'Case Closed - {client_name} - {self.name}', - 'body_html': body_html, - 'email_to': email_to, 'email_cc': email_cc, - 'model': 'sale.order', 'res_id': self.id, - }).send() - self._email_chatter_log('Case Closed email sent', email_to, email_cc) - return True - except Exception as e: - _logger.error(f"Failed to send case closed email for {self.name}: {e}") - return False - - def _send_withdrawal_email(self, reason=None): - """Send notification when application is withdrawn.""" - self.ensure_one() - if not self._is_email_notifications_enabled(): - return False - recipients = self._get_email_recipients(include_client=True, include_authorizer=True, include_sales_rep=True) - to_emails = recipients.get('to', []) - cc_emails = recipients.get('cc', []) + recipients.get('office_cc', []) - if not to_emails and not cc_emails: - return False - client_name = (recipients.get('client') or self.partner_id).name or 'Client' - sales_rep_name = (recipients.get('sales_rep') or self.env.user).name - - note_text = 'This application has been withdrawn from the Assistive Devices Program.' - if reason: - note_text += f'
      Reason: {reason}' - - body_html = self._email_build( - title='Application Withdrawn', - summary=f'The ADP application for {client_name} has been withdrawn.', - email_type='attention', - sections=[('Case Details', self._build_case_detail_rows())], - note=note_text, - note_color='#d69e2e', - button_url=f'{self.get_base_url()}/web#id={self.id}&model=sale.order&view_type=form', - sender_name=sales_rep_name, - ) - email_to = ', '.join(to_emails) if to_emails else ', '.join(cc_emails[:1]) - email_cc = ', '.join(cc_emails) if to_emails else ', '.join(cc_emails[1:]) - try: - self.env['mail.mail'].sudo().create({ - 'subject': f'Application Withdrawn - {client_name} - {self.name}', - 'body_html': body_html, - 'email_to': email_to, 'email_cc': email_cc, - 'model': 'sale.order', 'res_id': self.id, - }).send() - self._email_chatter_log('Application Withdrawn email sent', email_to, email_cc) - return True - except Exception as e: - _logger.error(f"Failed to send withdrawal email for {self.name}: {e}") - return False - - def _send_ready_for_delivery_email(self, technicians=None, scheduled_datetime=None, notes=None): - """Send notification when application is marked Ready for Delivery.""" - self.ensure_one() - if not self._is_email_notifications_enabled(): - return False - recipients = self._get_email_recipients(include_client=True, include_authorizer=True, include_sales_rep=True) - to_emails = recipients.get('to', []) - cc_emails = recipients.get('cc', []) + recipients.get('office_cc', []) - - # Add technician emails to CC - if technicians: - for tech in technicians: - if hasattr(tech, 'email') and tech.email: - cc_emails.append(tech.email) - - if not to_emails and not cc_emails: - return False - - client_name = (recipients.get('client') or self.partner_id).name or 'Client' - sales_rep_name = (recipients.get('sales_rep') or self.env.user).name - - # Build extra rows for delivery details - detail_rows = self._build_case_detail_rows() - if self.partner_shipping_id: - addr = self.partner_shipping_id.contact_address or '' - detail_rows.append(('Delivery Address', addr.replace('\n', ', '))) - if technicians: - tech_names = ', '.join(t.name for t in technicians if hasattr(t, 'name')) - if tech_names: - detail_rows.append(('Technician(s)', tech_names)) - if scheduled_datetime: - detail_rows.append(('Scheduled', str(scheduled_datetime))) - - note_text = 'Next steps: Our delivery team will contact you to confirm the delivery schedule.' - if self.x_fc_early_delivery: - note_text = ('Note: This is an early delivery (before final ADP approval). ' - 'Our team will contact you to schedule.') - if notes: - note_text += f'
      Notes: {notes}' - - body_html = self._email_build( - title='Ready for Delivery', - summary=f'The equipment for {client_name} is ready for delivery.', - email_type='success', - sections=[('Delivery Details', detail_rows)], - note=note_text, - note_color='#38a169', - button_url=f'{self.get_base_url()}/web#id={self.id}&model=sale.order&view_type=form', - sender_name=sales_rep_name, - ) - email_to = ', '.join(to_emails) if to_emails else ', '.join(cc_emails[:1]) - email_cc = ', '.join(cc_emails) if to_emails else ', '.join(cc_emails[1:]) - try: - self.env['mail.mail'].sudo().create({ - 'subject': f'Ready for Delivery - {client_name} - {self.name}', - 'body_html': body_html, - 'email_to': email_to, 'email_cc': email_cc, - 'model': 'sale.order', 'res_id': self.id, - }).send() - _logger.info(f"Ready for delivery email sent for {self.name}") - return True - except Exception as e: - _logger.error(f"Failed to send delivery email for {self.name}: {e}") - return False - - def _send_on_hold_email(self, reason=None): - """Send notification when application is put on hold.""" - self.ensure_one() - if not self._is_email_notifications_enabled(): - return False - recipients = self._get_email_recipients(include_client=True, include_authorizer=True, include_sales_rep=True) - to_emails = recipients.get('to', []) - cc_emails = recipients.get('cc', []) + recipients.get('office_cc', []) - if not to_emails and not cc_emails: - return False - client_name = (recipients.get('client') or self.partner_id).name or 'Client' - sales_rep_name = (recipients.get('sales_rep') or self.env.user).name - - note_text = 'This application has been placed on hold. We will resume processing as soon as possible.' - if reason: - note_text += f'
      Reason: {reason}' - - body_html = self._email_build( - title='Application On Hold', - summary=f'The ADP application for {client_name} has been placed on hold.', - email_type='attention', - sections=[('Case Details', self._build_case_detail_rows())], - note=note_text, - note_color='#d69e2e', - button_url=f'{self.get_base_url()}/web#id={self.id}&model=sale.order&view_type=form', - sender_name=sales_rep_name, - ) - email_to = ', '.join(to_emails) if to_emails else ', '.join(cc_emails[:1]) - email_cc = ', '.join(cc_emails) if to_emails else ', '.join(cc_emails[1:]) - try: - self.env['mail.mail'].sudo().create({ - 'subject': f'Application On Hold - {client_name} - {self.name}', - 'body_html': body_html, - 'email_to': email_to, 'email_cc': email_cc, - 'model': 'sale.order', 'res_id': self.id, - }).send() - self._email_chatter_log('Application On Hold email sent', email_to, email_cc) - return True - except Exception as e: - _logger.error(f"Failed to send on-hold email for {self.name}: {e}") - return False - - # ========================================================================== - # OVERRIDE WRITE - # ========================================================================== - def write(self, vals): - """Override write to handle ADP status changes, date auto-population, and document tracking.""" - from datetime import date as date_class - - # ================================================================= - # VALIDATION BYPASS (for internal operations like crons, email tracking) - # ================================================================= - if self.env.context.get('skip_all_validations'): - return super().write(vals) - - # ================================================================= - # CASE LOCK CHECK - # ================================================================= - # If unlocking (setting x_fc_case_locked to False), allow it - # Otherwise, if any order is locked, block changes to ADP fields - if 'x_fc_case_locked' not in vals or vals.get('x_fc_case_locked') is True: - # Fields that are always allowed to be modified even when locked - always_allowed = { - 'x_fc_case_locked', # Allow toggling the lock itself - 'message_main_attachment_id', - 'message_follower_ids', - 'activity_ids', - } - - # Check if any locked orders would have ADP fields modified - adf_fields_being_changed = [k for k in vals.keys() if k.startswith('x_fc_') and k not in always_allowed] - - if adf_fields_being_changed: - for order in self: - if order.x_fc_case_locked: - raise UserError( - f"Cannot modify order {order.name}.\n\n" - "This case is locked. Please unlock it first by toggling off the " - "'Case Locked' switch in the ADP Order Trail tab." - ) - - # ================================================================= - # SALE TYPE LOCK CHECK - # ================================================================= - # Sale type is locked after application is submitted - # Can be overridden by: context flag, sale type override setting, - # OR the document lock override (setting + group) - if 'x_fc_sale_type' in vals and not self.env.context.get('skip_sale_type_lock'): - locked_statuses = [ - 'submitted', 'accepted', 'rejected', 'resubmitted', - 'approved', 'approved_deduction', 'ready_bill', 'billed', 'case_closed', - ] - - ICP = self.env['ir.config_parameter'].sudo() - allow_sale_type = ICP.get_param('fusion_claims.allow_sale_type_override', 'False').lower() in ('true', '1', 'yes') - allow_doc_lock = ICP.get_param('fusion_claims.allow_document_lock_override', 'False').lower() in ('true', '1', 'yes') - has_override_group = self.env.user.has_group('fusion_claims.group_document_lock_override') - - if not allow_sale_type and not (allow_doc_lock and has_override_group): - for order in self: - if order.x_fc_adp_application_status in locked_statuses: - raise UserError( - f"Cannot modify Sale Type on order {order.name}.\n\n" - f"Sale Type is locked after the application has been submitted to ADP.\n" - f"Current status: {order.x_fc_adp_application_status}\n\n" - f"To modify, enable 'Allow Document Lock Override' in Settings\n" - f"and ensure your user is in the 'Document Lock Override' group." - ) - - # ================================================================= - # DOCUMENT LOCKING BASED ON STATUS PROGRESSION - # ================================================================= - # Documents become locked at specific stages to prevent modification - # Lock rules: - # - Original Application & Signed Pages 11/12 → Lock when submitted or later - # - Final Application & XML File → Lock when approved or later - # - Approval Letter & Screenshots → Lock when billed (but tracked on change) - # - Proof of Delivery → Lock when billed or later - - # Define document lock rules: field -> list of statuses where field is locked - statuses_after_submitted = [ - 'submitted', 'accepted', 'rejected', 'resubmitted', 'needs_correction', - 'approved', 'approved_deduction', 'ready_bill', 'billed', 'case_closed', - ] - statuses_after_approved = [ - 'approved', 'approved_deduction', 'ready_bill', 'billed', 'case_closed', - ] - statuses_after_billed = ['billed', 'case_closed'] - - document_lock_rules = { - # Application documents - lock after submitted - 'x_fc_original_application': statuses_after_submitted, - 'x_fc_original_application_filename': statuses_after_submitted, - 'x_fc_signed_pages_11_12': statuses_after_submitted, - 'x_fc_signed_pages_filename': statuses_after_submitted, - # Submission documents - lock after approved - 'x_fc_final_submitted_application': statuses_after_approved, - 'x_fc_final_application_filename': statuses_after_approved, - 'x_fc_xml_file': statuses_after_approved, - 'x_fc_xml_filename': statuses_after_approved, - # Approval documents - lock after billed - 'x_fc_approval_letter': statuses_after_billed, - 'x_fc_approval_letter_filename': statuses_after_billed, - # POD - lock after billed - 'x_fc_proof_of_delivery': statuses_after_billed, - 'x_fc_proof_of_delivery_filename': statuses_after_billed, - } - - # Check if any locked documents are being modified - # Skip check if: - # - context has skip_document_lock_validation (for programmatic override) - # - BOTH: the "Allow Document Lock Override" setting is ON - # AND the user is in the "Document Lock Override" group - can_override = False - if not self.env.context.get('skip_document_lock_validation'): - ICP_lock = self.env['ir.config_parameter'].sudo() - override_enabled = ICP_lock.get_param( - 'fusion_claims.allow_document_lock_override', 'False' - ).lower() in ('true', '1', 'yes') - if override_enabled: - can_override = self.env.user.has_group('fusion_claims.group_document_lock_override') - else: - can_override = True - - if not can_override: - for order in self: - current_status = order.x_fc_adp_application_status or '' - - for field_name, locked_statuses in document_lock_rules.items(): - if field_name in vals: - if current_status in locked_statuses: - old_value = getattr(order, field_name, None) - new_value = vals.get(field_name) - - if old_value == new_value: - continue - - if current_status in statuses_after_billed: - lock_stage = "billed" - elif current_status in statuses_after_approved: - lock_stage = "approved" - else: - lock_stage = "submitted" - - field_label_map = { - 'x_fc_original_application': 'Original ADP Application', - 'x_fc_signed_pages_11_12': 'Signed Pages 11 & 12', - 'x_fc_final_submitted_application': 'Final Submitted Application', - 'x_fc_xml_file': 'XML File', - 'x_fc_approval_letter': 'Approval Letter', - 'x_fc_proof_of_delivery': 'Proof of Delivery', - } - field_label = field_label_map.get(field_name, field_name) - - raise UserError( - f"Cannot modify '{field_label}' on order {order.name}.\n\n" - f"This document is locked because the application status is '{current_status}'.\n" - f"Documents are locked once the application reaches the '{lock_stage}' stage.\n\n" - f"To modify this document:\n" - f"1. The 'Allow Document Lock Override' setting must be enabled (Fusion Claims > Settings)\n" - f"2. Your user must be in the 'Document Lock Override' group" - ) - - # ================================================================= - # DOCUMENT AUDIT TRAIL - Track all document changes - # ================================================================= - document_fields = [ - 'x_fc_original_application', - 'x_fc_signed_pages_11_12', - 'x_fc_final_submitted_application', - 'x_fc_xml_file', - 'x_fc_proof_of_delivery', - 'x_fc_approval_letter', - ] - doc_changes = {f: vals.get(f) for f in document_fields if f in vals and vals.get(f)} - - # Preserve old documents in chatter BEFORE they get replaced or deleted - # This ensures document history is maintained for audit purposes - document_labels = { - 'x_fc_original_application': 'Original ADP Application', - 'x_fc_signed_pages_11_12': 'Page 11 & 12 (Signed)', - 'x_fc_final_submitted_application': 'Final Application', - 'x_fc_xml_file': 'XML File', - 'x_fc_proof_of_delivery': 'Proof of Delivery', - 'x_fc_approval_letter': 'Approval Letter', - } - - user_name = self.env.user.name - change_timestamp = fields.Datetime.now().strftime('%Y-%m-%d %H:%M:%S') - - # Fields already handled by the needs_correction flow below (avoid duplicate posts) - correction_handled = set() - if vals.get('x_fc_adp_application_status') == 'needs_correction': - correction_handled = {'x_fc_final_submitted_application', 'x_fc_xml_file'} - - for order in self: - for field_name in document_fields: - if field_name in vals and field_name not in correction_handled: - old_data = getattr(order, field_name, None) - new_data = vals.get(field_name) - label = document_labels.get(field_name, field_name) - - if old_data and new_data: - # REPLACEMENT: Old document being replaced with new one - # Preserve old document in chatter as attachment - order._post_document_to_chatter( - field_name, - f"{label} (replaced)" - ) - - elif old_data and not new_data: - # DELETION: Document is being deleted - # Preserve the deleted document in chatter - order._post_document_to_chatter( - field_name, - f"{label} (DELETED)" - ) - - # Post deletion notice - deletion_msg = Markup( - '
      ' - '

      ' - ' Document Deleted

      ' - '' - '' - f'' - '' - f'' - '' - f'' - '
      Document:{label}
      Deleted By:{user_name}
      Time:{change_timestamp}
      ' - '

      ' - 'The deleted document has been preserved in the message above.

      ' - '
      ' - ) - order.message_post( - body=deletion_msg, - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - - # Track status changes for auto-actions - new_app_status = vals.get('x_fc_adp_application_status') - new_mod_status = vals.get('x_fc_mod_status') - - # Handle document correction flow - clear document fields and submission date when needs_correction - if new_app_status == 'needs_correction': - for order in self: - # Post existing final application to chatter before clearing - if order.x_fc_final_submitted_application: - order._post_document_to_chatter('x_fc_final_submitted_application', - 'Final Application (before correction)') - if order.x_fc_xml_file: - order._post_document_to_chatter('x_fc_xml_file', - 'XML File (before correction)') - - # Clear the document fields AND submission date - # Use _correction_cleared to prevent the audit trail from posting duplicates - vals['x_fc_final_submitted_application'] = False - vals['x_fc_final_application_filename'] = False - vals['x_fc_xml_file'] = False - vals['x_fc_xml_filename'] = False - vals['x_fc_claim_submission_date'] = False - - # Post correction notice - for order in self: - order.message_post( - body=Markup( - '' - ), - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - - # Auto-populate date fields based on status changes - today = date_class.today() - if new_app_status == 'assessment_scheduled' and 'x_fc_assessment_start_date' not in vals: - vals['x_fc_assessment_start_date'] = today - elif new_app_status == 'assessment_completed' and 'x_fc_assessment_end_date' not in vals: - vals['x_fc_assessment_end_date'] = today - # Auto-transition to 'waiting_for_application' - vals['x_fc_adp_application_status'] = 'waiting_for_application' - new_app_status = 'waiting_for_application' - elif new_app_status in ('submitted', 'resubmitted') and 'x_fc_claim_submission_date' not in vals: - vals['x_fc_claim_submission_date'] = today - elif new_app_status == 'accepted' and 'x_fc_claim_acceptance_date' not in vals: - vals['x_fc_claim_acceptance_date'] = today - elif new_app_status in ('approved', 'approved_deduction') and 'x_fc_claim_approval_date' not in vals: - vals['x_fc_claim_approval_date'] = today - elif new_app_status == 'billed' and 'x_fc_billing_date' not in vals: - vals['x_fc_billing_date'] = today - - # ================================================================= - # REQUIRED FIELD VALIDATION based on status - # ================================================================= - # Note: UserError is imported at top of file - - # Helper to get field value (check vals first, then existing record) - def get_val(order, field): - if field in vals: - return vals[field] - return getattr(order, field, None) - - # Authorizer validation based on sale type and authorizer_required field - # Always required for: adp, adp_odsp, wsib, march_of_dimes, muscular_dystrophy - # Optional for: odsp, direct_private, insurance, other, rental (depends on x_fc_authorizer_required) - # - # IMPORTANT: Only validate when changing relevant fields, not on every write. - # This prevents blocking unrelated saves when authorizer is missing. - authorizer_related_fields = { - 'x_fc_sale_type', 'x_fc_authorizer_id', 'x_fc_authorizer_required', - 'x_fc_adp_application_status', # Also validate when changing ADP status - } - should_validate_authorizer = bool(authorizer_related_fields & set(vals.keys())) - - if should_validate_authorizer: - always_auth_types = ('adp', 'adp_odsp', 'wsib', 'march_of_dimes', 'muscular_dystrophy') - optional_auth_types = ('odsp', 'direct_private', 'insurance', 'other', 'rental') - - for order in self: - sale_type = get_val(order, 'x_fc_sale_type') - auth_id = get_val(order, 'x_fc_authorizer_id') - auth_required = get_val(order, 'x_fc_authorizer_required') - - if sale_type in always_auth_types: - # Always required for these types - if not auth_id: - raise UserError("Authorizer is required for this sale type.") - elif sale_type in optional_auth_types and auth_required == 'yes': - # Required only if user selected "Yes" - if not auth_id: - raise UserError("Authorizer is required. You selected 'Yes' for Authorizer Required.") - - # Helper to check if previous funding date is required based on reason - def requires_previous_funding(reason_val): - """Return True if the reason requires previous funding date.""" - exempt_reasons = ['first_access', 'mod_non_adp'] - return reason_val and reason_val not in exempt_reasons - - # ================================================================= - # STATUS TRANSITION VALIDATIONS - # ================================================================= - # All status changes to "controlled" statuses must go through dedicated - # buttons/wizards. Direct dropdown/statusbar changes are blocked. - # Use context flag 'skip_status_validation' to bypass when calling from wizards. - - if not self.env.context.get('skip_status_validation') and new_app_status: - # Statuses that can ONLY be set via buttons/wizards - # This ensures proper workflow tracking and validation - controlled_statuses = { - # Early workflow stages - 'assessment_scheduled': 'Schedule Assessment', - 'assessment_completed': 'Complete Assessment', - 'waiting_for_application': 'Complete Assessment', - 'application_received': 'Application Received', - 'ready_submission': 'Ready for Submission', - # Submission and approval stages - 'submitted': 'Submit Application', - 'accepted': 'Mark as Accepted', # New: ADP accepted submission - 'rejected': 'Mark as Rejected', # New: ADP rejected submission - 'resubmitted': 'Submit Application', - 'approved': 'Mark as Approved', - 'approved_deduction': 'Mark as Approved', - # Delivery stage - 'ready_delivery': 'Ready for Delivery', - # Billing stages - 'ready_bill': 'Ready to Bill', - 'billed': 'Mark as Billed', - 'case_closed': 'Close Case', - # Special statuses (require reason wizard) - 'on_hold': 'Put On Hold', - 'withdrawn': 'Withdraw', - 'denied': 'Denied', - 'cancelled': 'Cancel', - 'needs_correction': 'Needs Correction', - } - - if new_app_status in controlled_statuses: - button_name = controlled_statuses[new_app_status] - raise UserError( - f"To change status to this value, please use the '{button_name}' button.\n\n" - f"Direct status changes are not allowed for workflow integrity." - ) - - # ================================================================= - # RESUMING FROM ON_HOLD: Check assessment validity (3 months) - # ================================================================= - for order in self: - if order.x_fc_adp_application_status == 'on_hold' and new_app_status and new_app_status != 'on_hold': - # Check if assessment is expired (more than 3 months old) - if order.x_fc_assessment_expired: - days_expired = (today - order.x_fc_assessment_end_date).days - 90 if order.x_fc_assessment_end_date else 0 - order.message_post( - body=Markup( - '' - ), - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - raise UserError( - f"Cannot resume from 'On Hold' - Assessment has expired!\n\n" - f"The assessment was completed on {order.x_fc_assessment_end_date} and is now " - f"{days_expired} days past the 3-month validity period.\n\n" - f"A new assessment must be completed before proceeding." - ) - - # assessment_scheduled: No special requirements (Assessment Start Date auto-populated) - - if new_app_status == 'assessment_completed': - for order in self: - missing = [] - if not get_val(order, 'x_fc_assessment_start_date'): - missing.append('Assessment Start Date') - if not get_val(order, 'x_fc_assessment_end_date'): - missing.append('Assessment End Date') - if missing: - raise UserError( - f"Cannot change status to 'Assessment Completed'.\n\n" - f"Required fields missing:\n• " + "\n• ".join(missing) - ) - - elif new_app_status == 'application_received': - for order in self: - missing = [] - # Only Assessment Start Date required at this stage - if not get_val(order, 'x_fc_assessment_start_date'): - missing.append('Assessment Start Date') - if missing: - raise UserError( - f"Cannot change status to 'Application Received'.\n\n" - f"Required fields missing:\n• " + "\n• ".join(missing) - ) - - elif new_app_status == 'ready_submission': - for order in self: - missing = [] - # Assessment dates - if not get_val(order, 'x_fc_assessment_start_date'): - missing.append('Assessment Start Date') - if not get_val(order, 'x_fc_assessment_end_date'): - missing.append('Assessment End Date') - # Reason for application - if not get_val(order, 'x_fc_reason_for_application'): - missing.append('Reason for Application') - # Client references and authorization date - if not get_val(order, 'x_fc_client_ref_1'): - missing.append('Client Reference 1') - if not get_val(order, 'x_fc_client_ref_2'): - missing.append('Client Reference 2') - if not get_val(order, 'x_fc_claim_authorization_date'): - missing.append('Claim Authorization Date') - # Previous funding date if required by reason - reason_val = get_val(order, 'x_fc_reason_for_application') - if requires_previous_funding(reason_val): - if not get_val(order, 'x_fc_previous_funding_date'): - missing.append('Previous Funding Date') - # Documents - if not order.x_fc_original_application and not vals.get('x_fc_original_application'): - missing.append('Original ADP Application') - if not order.x_fc_signed_pages_11_12 and not vals.get('x_fc_signed_pages_11_12'): - missing.append('Page 11 & 12 (Signed)') - if missing: - raise UserError( - f"Cannot change status to 'Ready for Submission'.\n\n" - f"Required fields/documents missing:\n• " + "\n• ".join(missing) - ) - - elif new_app_status in ('submitted', 'resubmitted'): - for order in self: - missing = [] - # Documents - if not order.x_fc_final_submitted_application and not vals.get('x_fc_final_submitted_application'): - missing.append('Final Submitted Application') - if not order.x_fc_xml_file and not vals.get('x_fc_xml_file'): - missing.append('XML File') - # Fields - if not get_val(order, 'x_fc_claim_submission_date'): - missing.append('Claim Submission Date') - if missing: - raise UserError( - f"Cannot change status to 'Application Submitted'.\n\n" - f"Required fields/documents missing:\n• " + "\n• ".join(missing) - ) - - elif new_app_status in ('approved', 'approved_deduction'): - for order in self: - missing = [] - if not get_val(order, 'x_fc_claim_number'): - missing.append('Claim Number') - if not get_val(order, 'x_fc_claim_approval_date'): - missing.append('Claim Approval Date') - if missing: - raise UserError( - f"Cannot change status to 'Application Approved'.\n\n" - f"Required fields missing:\n• " + "\n• ".join(missing) - ) - - elif new_app_status == 'ready_bill': - for order in self: - missing = [] - if not get_val(order, 'x_fc_adp_delivery_date'): - missing.append('ADP Delivery Date') - if not order.x_fc_proof_of_delivery and not vals.get('x_fc_proof_of_delivery'): - missing.append('Proof of Delivery') - if missing: - raise UserError( - f"Cannot change status to 'Ready to Bill'.\n\n" - f"Required fields/documents missing:\n• " + "\n• ".join(missing) - ) - - elif new_app_status == 'billed': - for order in self: - missing = [] - if not get_val(order, 'x_fc_billing_date'): - missing.append('Billing Date') - if missing: - raise UserError( - f"Cannot change status to 'Billed to ADP'.\n\n" - f"Required fields missing:\n• " + "\n• ".join(missing) - ) - - elif new_app_status == 'case_closed': - for order in self: - missing = [] - if not get_val(order, 'x_fc_billing_date'): - missing.append('Billing Date') - if missing: - raise UserError( - f"Cannot change status to 'Case Closed'.\n\n" - f"Required fields missing:\n• " + "\n• ".join(missing) - ) - - # ================================================================== - # MARCH OF DIMES STATUS TRANSITION VALIDATIONS - # ================================================================== - if new_mod_status: - for order in self: - if not order._is_mod_sale() and order.x_fc_sale_type != 'march_of_dimes': - continue - - if new_mod_status == 'contract_received': - missing = [] - if not get_val(order, 'x_fc_case_reference') and not vals.get('x_fc_case_reference'): - missing.append('HVMP Reference Number') - if missing: - raise UserError( - "Cannot change status to 'PCA Received'.\n\n" - "Required:\n" + "\n".join(f"- {m}" for m in missing) - ) - - elif new_mod_status == 'pod_submitted': - if not order.x_fc_mod_proof_of_delivery and not vals.get('x_fc_mod_proof_of_delivery'): - raise UserError( - "Cannot change status to 'POD Sent'.\n\n" - "Please upload the Proof of Delivery document first." - ) - - result = super().write(vals) - - # Skip additional processing if we're in a sync operation (prevent infinite loops) - if self.env.context.get('skip_sync'): - return result - - # Post document uploads to chatter - if doc_changes: - for order in self: - for field_name, data in doc_changes.items(): - if data: - order._post_document_to_chatter(field_name) - - # Auto-overlay POD signature onto SA Mobility approval form - if 'x_fc_pod_signature' in vals and vals['x_fc_pod_signature'] and not self.env.context.get('skip_pod_signature_hook'): - for order in self: - try: - order._apply_pod_signature_to_approval_form() - except Exception as e: - _logger.error("Failed to overlay POD signature for %s: %s", order.name, e) - # Auto-advance SA Mobility from ready_delivery to delivered when POD is signed - if (order.x_fc_odsp_division == 'sa_mobility' - and order.x_fc_sa_status == 'ready_delivery'): - order._odsp_advance_status( - 'delivered', - "Delivery completed. POD signature collected and SA form auto-signed.", - ) - - # Handle status-based actions (emails and reminders) - # skip_status_emails: suppress all status-triggered emails - # (used when reverting status e.g. cancelled delivery task) - if self.env.context.get('skip_status_emails'): - new_app_status = None # Disable all email triggers below - - if new_app_status in ('submitted', 'resubmitted'): - for order in self: - order._send_submission_email() - # Create submission history record - submission_type = 'resubmission' if new_app_status == 'resubmitted' else 'initial' - self.env['fusion.submission.history'].create_from_submission(order, submission_type=submission_type) - elif new_app_status in ('approved', 'approved_deduction'): - for order in self: - order._send_approval_email() - order._schedule_delivery_reminder() - elif new_app_status == 'accepted': - # 'Accepted' is internal tracking - no external email notification - # But we record it in submission history - for order in self: - # Update the most recent pending submission to 'accepted' - pending_submission = self.env['fusion.submission.history'].search([ - ('sale_order_id', '=', order.id), - ('result', '=', 'pending'), - ], order='submission_date desc', limit=1) - if pending_submission: - pending_submission.update_result('accepted') - elif new_app_status == 'rejected': - # 'Rejected' - ADP rejected the submission, needs correction - for order in self: - order._send_rejection_email() - # Update the most recent pending submission to 'rejected' - pending_submission = self.env['fusion.submission.history'].search([ - ('sale_order_id', '=', order.id), - ('result', '=', 'pending'), - ], order='submission_date desc', limit=1) - if pending_submission: - pending_submission.update_result( - 'rejected', - rejection_reason=order.x_fc_rejection_reason, - rejection_details=order.x_fc_rejection_reason_other, - ) - elif new_app_status == 'denied': - for order in self: - order._send_denial_email() - elif new_app_status == 'needs_correction': - # Email sent from the wizard with the reason text, not here. - # If called programmatically without the wizard, send without reason. - if not self.env.context.get('skip_correction_email'): - for order in self: - order._send_correction_needed_email() - elif new_app_status == 'case_closed': - for order in self: - order._send_case_closed_email() - - # ================================================================== - # MARCH OF DIMES STATUS-TRIGGERED EMAILS & SMS - # ================================================================== - if new_mod_status and not self.env.context.get('skip_status_emails'): - for order in self: - if not order._is_mod_sale(): - continue - try: - if new_mod_status == 'assessment_scheduled': - order._send_mod_assessment_scheduled_email() - order._send_mod_sms('assessment_scheduled') - elif new_mod_status == 'assessment_completed': - order._send_mod_assessment_completed_email() - elif new_mod_status == 'quote_submitted': - order._send_mod_quote_submitted_email() - if not order.x_fc_case_submitted: - order.with_context(skip_all_validations=True).write({ - 'x_fc_case_submitted': fields.Date.today()}) - elif new_mod_status == 'funding_approved': - order._send_mod_funding_approved_email() - order._send_mod_sms('funding_approved') - if not order.x_fc_case_approved: - order.with_context(skip_all_validations=True).write({ - 'x_fc_case_approved': fields.Date.today()}) - elif new_mod_status == 'funding_denied': - order._send_mod_funding_denied_email() - elif new_mod_status == 'contract_received': - order._send_mod_contract_received_email() - elif new_mod_status == 'in_production': - order._send_mod_sms('initial_payment_received') - elif new_mod_status == 'project_complete': - order._send_mod_project_complete_email() - order._send_mod_sms('project_complete') - elif new_mod_status == 'pod_submitted': - order._send_mod_pod_submitted_email() - elif new_mod_status == 'case_closed': - order._send_mod_case_closed_email() - except Exception as e: - _logger.error(f"MOD status email/sms failed for {order.name} ({new_mod_status}): {e}") - - # Check if we need to recalculate - ICP = self.env['ir.config_parameter'].sudo() - sale_type_field = ICP.get_param('fusion_claims.field_sale_type', 'x_fc_sale_type') - client_type_field = ICP.get_param('fusion_claims.field_so_client_type', 'x_fc_client_type') - - trigger_fields = { - 'x_fc_sale_type', 'x_fc_client_type', - sale_type_field, client_type_field, - } - - if trigger_fields & set(vals.keys()): - for order in self: - # Trigger recomputation of x_fc_is_adp_sale - order._compute_is_adp_sale() - # Trigger recalculation of ADP portions - for line in order.order_line: - line._compute_adp_portions() - - # Sync FC fields to invoices when relevant fields change - sync_fields = { - 'x_fc_claim_number', 'x_fc_client_ref_1', 'x_fc_client_ref_2', - 'x_fc_adp_delivery_date', 'x_fc_authorizer_id', 'x_fc_client_type', 'x_fc_primary_serial', - 'x_fc_service_start_date', 'x_fc_service_end_date', - } - if sync_fields & set(vals.keys()): - for order in self: - order._sync_fields_to_invoices() - - return result - - # ========================================================================== - # FIELD SYNCHRONIZATION (SO -> Invoice) - # ========================================================================== - def _get_field_mappings(self): - """Get field mappings from system parameters. - - Returns dict with SO and Invoice field mappings configured in Settings. - """ - ICP = self.env['ir.config_parameter'].sudo() - return { - # Sale Order field mappings - 'so_claim_number': ICP.get_param('fusion_claims.field_so_claim_number', 'x_fc_claim_number'), - 'so_client_ref_1': ICP.get_param('fusion_claims.field_so_client_ref_1', 'x_fc_client_ref_1'), - 'so_client_ref_2': ICP.get_param('fusion_claims.field_so_client_ref_2', 'x_fc_client_ref_2'), - 'so_delivery_date': ICP.get_param('fusion_claims.field_so_delivery_date', 'x_fc_adp_delivery_date'), - 'so_authorizer': ICP.get_param('fusion_claims.field_so_authorizer', 'x_fc_authorizer_id'), - 'so_client_type': ICP.get_param('fusion_claims.field_so_client_type', 'x_fc_client_type'), - 'so_service_start': ICP.get_param('fusion_claims.field_so_service_start', 'x_fc_service_start_date'), - 'so_service_end': ICP.get_param('fusion_claims.field_so_service_end', 'x_fc_service_end_date'), - 'sol_serial': ICP.get_param('fusion_claims.field_sol_serial', 'x_fc_serial_number'), - # Invoice field mappings - 'inv_claim_number': ICP.get_param('fusion_claims.field_inv_claim_number', 'x_fc_claim_number'), - 'inv_client_ref_1': ICP.get_param('fusion_claims.field_inv_client_ref_1', 'x_fc_client_ref_1'), - 'inv_client_ref_2': ICP.get_param('fusion_claims.field_inv_client_ref_2', 'x_fc_client_ref_2'), - 'inv_delivery_date': ICP.get_param('fusion_claims.field_inv_delivery_date', 'x_fc_adp_delivery_date'), - 'inv_authorizer': ICP.get_param('fusion_claims.field_inv_authorizer', 'x_fc_authorizer_id'), - 'inv_client_type': ICP.get_param('fusion_claims.field_inv_client_type', 'x_fc_client_type'), - 'inv_service_start': ICP.get_param('fusion_claims.field_inv_service_start', 'x_fc_service_start_date'), - 'inv_service_end': ICP.get_param('fusion_claims.field_inv_service_end', 'x_fc_service_end_date'), - 'aml_serial': ICP.get_param('fusion_claims.field_aml_serial', 'x_fc_serial_number'), - } - - def _get_field_value(self, record, field_name): - """Safely get a field value from a record.""" - if not field_name or field_name not in record._fields: - return None - value = getattr(record, field_name, None) - # Handle Many2one fields - return id for writing - if hasattr(value, 'id'): - return value.id if value else False - return value - - def _sync_fields_to_invoices(self): - """Sync ADP fields from Sale Order to linked Invoices. - - Uses dynamic field mappings from Settings. - """ - mappings = self._get_field_mappings() - - for order in self: - invoices = order.invoice_ids.filtered(lambda inv: inv.state != 'cancel') - if not invoices: - _logger.debug(f"No invoices found for order {order.name}") - continue - - for invoice in invoices: - vals = {} - - # Get source values from SO - claim_number = order.x_fc_claim_number - client_ref_1 = order.x_fc_client_ref_1 - client_ref_2 = order.x_fc_client_ref_2 - delivery_date = order.x_fc_adp_delivery_date - - authorizer_id = False - if order.x_fc_authorizer_id: - authorizer_id = order.x_fc_authorizer_id.id - - client_type = order.x_fc_client_type - service_start = order.x_fc_service_start_date - service_end = order.x_fc_service_end_date - - # Write to Invoice FC fields only (no Studio field writes) - if claim_number: - if 'x_fc_claim_number' in invoice._fields: - vals['x_fc_claim_number'] = claim_number - - if client_ref_1: - if 'x_fc_client_ref_1' in invoice._fields: - vals['x_fc_client_ref_1'] = client_ref_1 - - if client_ref_2: - if 'x_fc_client_ref_2' in invoice._fields: - vals['x_fc_client_ref_2'] = client_ref_2 - - if delivery_date: - if 'x_fc_adp_delivery_date' in invoice._fields: - vals['x_fc_adp_delivery_date'] = delivery_date - - if authorizer_id: - if 'x_fc_authorizer_id' in invoice._fields: - vals['x_fc_authorizer_id'] = authorizer_id - - if client_type: - if 'x_fc_client_type' in invoice._fields: - vals['x_fc_client_type'] = client_type - - if service_start: - if 'x_fc_service_start_date' in invoice._fields: - vals['x_fc_service_start_date'] = service_start - - if service_end: - if 'x_fc_service_end_date' in invoice._fields: - vals['x_fc_service_end_date'] = service_end - - # Serial Number - sync from SO header to invoice header - primary_serial = order.x_fc_primary_serial - if primary_serial: - vals['x_fc_primary_serial'] = primary_serial - - if vals: - try: - invoice.sudo().with_context(skip_sync=True).write(vals) - _logger.debug(f"Synced fields to invoice {invoice.name}: {list(vals.keys())}") - except Exception as e: - _logger.warning(f"Failed to sync to invoice {invoice.name}: {e}") - else: - _logger.debug(f"No fields to sync to invoice {invoice.name}") - - # Sync serial numbers from SO lines to corresponding invoice lines - order._sync_serial_numbers_to_invoices() - - def _sync_serial_numbers_to_invoices(self): - """Sync serial numbers from SO lines to linked invoice lines. - - Uses dynamic field mappings from Settings. - """ - if self.env.context.get('skip_sync'): - _logger.info("_sync_serial_numbers_to_invoices: skipped (skip_sync context)") - return - - mappings = self._get_field_mappings() - sol_serial_field = mappings.get('sol_serial', 'x_fc_serial_number') - aml_serial_field = mappings.get('aml_serial', 'x_fc_serial_number') - - _logger.debug(f"_sync_serial_numbers_to_invoices: Starting. sol_field={sol_serial_field}, aml_field={aml_serial_field}") - - for order in self: - _logger.debug(f" Processing SO {order.name}") - for so_line in order.order_line: - if so_line.display_type in ('line_section', 'line_note'): - continue - - # Get serial from THIS SO line ONLY - no fallback to header - # Each line syncs its OWN serial to corresponding invoice lines - serial_value = None - if sol_serial_field in so_line._fields: - serial_value = getattr(so_line, sol_serial_field, None) - - # Skip if this line has no serial - don't use header fallback - if not serial_value: - continue - - _logger.debug(f" SO line {so_line.id}: serial={serial_value}") - - # Find linked invoice lines - invoice_lines = self.env['account.move.line'].sudo().search([ - ('sale_line_ids', 'in', so_line.id), - ('move_id.state', '!=', 'cancel') - ]) - - for inv_line in invoice_lines: - vals = {} - # Write to x_fc_serial_number on invoice line - if 'x_fc_serial_number' in inv_line._fields: - vals['x_fc_serial_number'] = serial_value - - if vals: - try: - inv_line.sudo().with_context(skip_sync=True).write(vals) - _logger.debug(f" Synced serial '{serial_value}' to invoice line {inv_line.id} (inv {inv_line.move_id.name})") - except Exception as e: - _logger.error(f" Failed to sync serial to invoice line {inv_line.id}: {e}") - - def action_sync_adp_fields(self): - """Manual action to sync all ADP fields to invoices.""" - synced_invoices = 0 - for order in self: - # First sync Studio fields to FC fields on the SO itself - order._sync_studio_to_fc_fields() - - # Then sync to invoices - invoices = order.invoice_ids.filtered(lambda inv: inv.state != 'cancel') - if invoices: - order._sync_fields_to_invoices() - synced_invoices += len(invoices) - - # Force refresh of the view - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'Fields Synchronized', - 'message': f'Synced ADP fields from {len(self)} sale order(s) to {synced_invoices} invoice(s). Please refresh the page to see updated values.', - 'type': 'success', - 'sticky': False, - } - } - - @api.model - def _cron_sync_adp_fields(self): - """Cron job to sync ADP fields from Sale Orders to Invoices. - - Processes all ADP sales created/modified in the last 7 days. - Uses dynamic field mappings from Settings. - """ - from datetime import timedelta - cutoff_date = fields.Datetime.now() - timedelta(days=7) - - # Get field mappings - mappings = self._get_field_mappings() - sale_type_field = self.env['ir.config_parameter'].sudo().get_param( - 'fusion_claims.field_sale_type', 'x_fc_sale_type' - ) - - # Build domain - check FC sale type fields - domain = [('write_date', '>=', cutoff_date)] - or_conditions = [] - - # Check FC sale type field - if sale_type_field in self._fields: - or_conditions.append((sale_type_field, 'in', ['adp', 'adp_odsp', 'ADP', 'ADP/ODSP'])) - - # Check claim number fields - claim_field = mappings.get('so_claim_number', 'x_fc_claim_number') - if claim_field in self._fields: - or_conditions.append((claim_field, '!=', False)) - - # Combine with OR - each '|' must be a separate element in the domain list - if or_conditions: - # Add (n-1) OR operators for n conditions - for _ in range(len(or_conditions) - 1): - domain.append('|') - # Add all conditions - for cond in or_conditions: - domain.append(cond) - - try: - orders = self.search(domain) - except Exception as e: - _logger.error(f"Error searching for ADP orders: {e}") - # Fallback to simpler search - orders = self.search([ - ('write_date', '>=', cutoff_date), - ('invoice_ids', '!=', False), - ]) - - synced_count = 0 - error_count = 0 - - for order in orders: - try: - # Only sync if it's an ADP sale - if order._is_adp_sale() or order.x_fc_claim_number: - order._sync_studio_to_fc_fields() - order._sync_fields_to_invoices() - synced_count += 1 - except Exception as e: - error_count += 1 - _logger.warning(f"Failed to sync order {order.name}: {e}") - - _logger.info(f"Fusion Claims sync complete: {synced_count} orders synced, {error_count} errors") - return synced_count - - # ========================================================================== - # EMAIL SEND OVERRIDE (Use ADP templates for ADP sales) - # ========================================================================== - def action_quotation_send(self): - """Override to use ADP email template for ADP sales. - - When sending a quotation for an ADP sale, automatically selects the - ADP landscape template instead of the default template. - """ - self.ensure_one() - - # Check if this is an ADP sale - if self._is_adp_sale(): - # Get the ADP template - template_xmlid = 'fusion_claims.email_template_adp_quotation' - if self.state in ('sale', 'done'): - # Use sales order confirmation template for confirmed orders - template_xmlid = 'fusion_claims.email_template_adp_sales_order' - - try: - template = self.env.ref(template_xmlid, raise_if_not_found=False) - if template: - # Open the mail compose wizard with the ADP template pre-selected - ctx = { - 'default_model': 'sale.order', - 'default_res_ids': self.ids, - 'default_template_id': template.id, - 'default_email_layout_xmlid': 'mail.mail_notification_layout', - 'default_composition_mode': 'comment', - 'mark_so_as_sent': True, - 'force_email': True, - 'model_description': self.with_context(lang=self.partner_id.lang).type_name, - } - - return { - 'type': 'ir.actions.act_window', - 'res_model': 'mail.compose.message', - 'view_mode': 'form', - 'views': [(False, 'form')], - 'target': 'new', - 'context': ctx, - } - except Exception as e: - _logger.warning(f"Could not load ADP email template: {e}") - - # Fall back to standard behavior for non-ADP sales - return super().action_quotation_send() - - # ========================================================================== - # ADP ACTIVITY REMINDER METHODS - # ========================================================================== - def _schedule_or_renew_adp_activity(self, activity_type_xmlid, user_id, date_deadline, summary, note=False): - """Schedule or renew an ADP-related activity. - - If an activity of the same type for the same user already exists, - update its deadline instead of creating a duplicate. - - Args: - activity_type_xmlid: XML ID of the activity type - user_id: ID of the user to assign the activity to - date_deadline: Deadline date for the activity - summary: Activity summary text - note: Optional note text - """ - self.ensure_one() - - try: - activity_type = self.env.ref(activity_type_xmlid) - except ValueError: - _logger.warning(f"Activity type not found: {activity_type_xmlid}") - return - - # Search for existing activity of this type for this user - existing = self.activity_ids.filtered( - lambda a: a.activity_type_id.id == activity_type.id - and a.user_id.id == user_id - ) - - if existing: - # Update existing activity - existing[0].write({ - 'date_deadline': date_deadline, - 'summary': summary, - 'note': note or existing[0].note, - }) - _logger.info(f"Renewed ADP activity for {self.name}: {summary} -> {date_deadline}") - else: - # Create new activity - self.activity_schedule( - activity_type_xmlid, - date_deadline=date_deadline, - summary=summary, - note=note, - user_id=user_id - ) - _logger.info(f"Scheduled new ADP activity for {self.name}: {summary} -> {date_deadline}") - - def _complete_adp_activities(self, activity_type_xmlid): - """Complete all activities of a specific type for this record. - - Args: - activity_type_xmlid: XML ID of the activity type to complete - """ - self.ensure_one() - - try: - activity_type = self.env.ref(activity_type_xmlid) - except ValueError: - return - - activities = self.activity_ids.filtered( - lambda a: a.activity_type_id.id == activity_type.id - ) - - for activity in activities: - activity.action_feedback(feedback='Completed automatically') - _logger.info(f"Completed ADP activity for {self.name}: {activity.summary}") - - def _schedule_delivery_reminder(self): - """Schedule a delivery reminder for the salesperson. - - Triggered when ADP application status changes to 'approved' or 'approved_deduction'. - Reminds the salesperson to deliver the order by Tuesday of the next posting week. - """ - self.ensure_one() - - if not self._is_adp_sale(): - return - - # Get the salesperson - salesperson = self.user_id - if not salesperson: - _logger.warning(f"No salesperson assigned to {self.name}, cannot schedule delivery reminder") - return - - # Calculate the next posting date and the Tuesday of that week - next_posting = self._get_next_posting_date() - reminder_date = self._get_posting_week_tuesday(next_posting) - - # Don't schedule if reminder date is in the past - from datetime import date - if reminder_date < date.today(): - # Schedule for the next posting cycle - next_posting = self._get_next_posting_date(next_posting) - reminder_date = self._get_posting_week_tuesday(next_posting) - - summary = f"Deliver ADP order {self.name} for {next_posting.strftime('%b %d')} billing" - note = f"Complete delivery by Tuesday to meet the Wednesday 6 PM submission deadline for the {next_posting.strftime('%B %d, %Y')} ADP posting." - - self._schedule_or_renew_adp_activity( - 'fusion_claims.mail_activity_type_adp_delivery', - salesperson.id, - reminder_date, - summary, - note - ) - - def _cron_renew_delivery_reminders(self): - """Cron job to renew overdue delivery reminders. - - For sale orders with approved status that have overdue delivery activities, - reschedule them to the next posting week's Tuesday. - """ - from datetime import date - today = date.today() - - # Find approved orders with overdue delivery activities - try: - activity_type = self.env.ref('fusion_claims.mail_activity_type_adp_delivery') - except ValueError: - _logger.warning("ADP Delivery activity type not found") - return - - # Find orders that are approved but not yet billed (delivery still pending) - approved_orders = self.search([ - ('x_fc_is_adp_sale', '=', True), - ('x_fc_adp_application_status', 'in', ['approved', 'approved_deduction']), - ]) - - for order in approved_orders: - # Check if there's an overdue delivery activity - overdue_activities = order.activity_ids.filtered( - lambda a: a.activity_type_id.id == activity_type.id - and a.date_deadline < today - ) - - if overdue_activities: - # Reschedule to next posting week - order._schedule_delivery_reminder() - _logger.info(f"Renewed overdue delivery reminder for {order.name}") - - def _cron_auto_close_billed_cases(self): - """Cron job to automatically close cases 1 month after being billed. - - Finds all sale orders with 'billed' status where the billing date - was more than 30 days ago, and automatically changes them to 'case_closed'. - """ - from datetime import date, timedelta - today = date.today() - cutoff_date = today - timedelta(days=30) - - # Find orders that are billed and have billing date > 30 days ago - orders_to_close = self.search([ - ('x_fc_is_adp_sale', '=', True), - ('x_fc_adp_application_status', '=', 'billed'), - ('x_fc_billing_date', '<=', cutoff_date), - ]) - - for order in orders_to_close: - try: - # Use context to skip status validation for automated process - order.with_context(skip_status_validation=True).write({ - 'x_fc_adp_application_status': 'case_closed', - }) - - # Post to chatter - days_since_billed = (today - order.x_fc_billing_date).days - order.message_post( - body=f'

      Case Automatically Closed

      ' - f'

      This case has been automatically closed after {days_since_billed} days since billing.

      ' - f'

      Billing Date: {order.x_fc_billing_date}

      ', - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - - _logger.info(f"Auto-closed case {order.name} after {days_since_billed} days since billing") - except Exception as e: - _logger.error(f"Failed to auto-close case {order.name}: {e}") - - @api.model - def _cron_auto_close_odsp_paid_cases(self): - """Auto-close ODSP/SA/OW cases 7 days after their final workflow step. - - SA Mobility & Standard ODSP: close 7 days after payment_received. - Ontario Works: close 7 days after delivered (payment comes before delivery). - """ - from datetime import timedelta - cutoff = fields.Datetime.now() - timedelta(days=7) - orders = self.search([ - ('x_fc_is_odsp_sale', '=', True), - ('write_date', '<=', cutoff), - '|', '|', '|', - ('x_fc_sa_status', '=', 'payment_received'), - ('x_fc_odsp_std_status', '=', 'payment_received'), - ('x_fc_ow_status', '=', 'payment_received'), - ('x_fc_ow_status', '=', 'delivered'), - ]) - closeable = {'payment_received', 'delivered'} - for order in orders: - status = order._get_odsp_status() - if status not in closeable: - continue - if order.x_fc_odsp_division == 'ontario_works' and status != 'delivered': - continue - if order.x_fc_odsp_division != 'ontario_works' and status != 'payment_received': - continue - try: - order._odsp_advance_status( - 'case_closed', - "Case automatically closed 7 days after %s." % status.replace('_', ' '), - ) - _logger.info(f"Auto-closed ODSP case {order.name}") - except Exception as e: - _logger.error(f"Failed to auto-close ODSP case {order.name}: {e}") - - @api.model - def _cron_send_acceptance_reminders(self): - """Cron job: Send reminders for orders still in 'submitted' status next business day. - - Per business rule: If 'Accepted by ADP' not marked within 1 business day after submission: - - First email to Office Notification Recipients - - Second email to Office + Sales Rep - """ - from datetime import timedelta - - if not self._is_email_notifications_enabled(): - _logger.info("Email notifications disabled, skipping acceptance reminders") - return - - today = fields.Date.today() - - # Find orders where: - # - Status is still 'submitted' (not accepted, rejected, or later) - # - Submission date was at least 1 business day ago - # - # For simplicity, we check if submission was 2+ days ago (covers weekends) - cutoff_date = today - timedelta(days=2) - - orders = self.search([ - ('x_fc_is_adp_sale', '=', True), - ('x_fc_adp_application_status', '=', 'submitted'), - ('x_fc_claim_submission_date', '<=', cutoff_date), - ('x_fc_acceptance_reminder_sent', '=', False), - ]) - - if not orders: - _logger.info("Acceptance reminder cron: No orders require reminders") - return - - _logger.info(f"Acceptance reminder cron: Found {len(orders)} orders to remind") - - # Get office notification emails from company - company = self.env.company - office_partners = company.sudo().x_fc_office_notification_ids - office_emails = [p.email for p in office_partners if p.email] - - if not office_emails: - _logger.warning("Acceptance reminder cron: No office notification recipients configured") - return - - for order in orders: - try: - days_since_submission = (today - order.x_fc_claim_submission_date).days - - client_name = order.partner_id.name or 'Client' - claim_number = order.x_fc_claim_number or 'N/A' - order_name = order.name - submission_date = order.x_fc_claim_submission_date.strftime('%B %d, %Y') - sales_rep = order.user_id - - # Determine recipients - if days_since_submission > 3: - to_emails = office_emails.copy() - if sales_rep and sales_rep.email: - to_emails.append(sales_rep.email) - reminder_type = "SECOND" - else: - to_emails = office_emails.copy() - reminder_type = "FIRST" - - # Build email using the mixin builder - level = 'Follow-up' if reminder_type == 'SECOND' else 'Pending' - subject = f'{level} Review: Acceptance Status - {order_name}' - body_html = order._email_build( - title='Acceptance Status Pending', - summary=f'The application for {client_name} was submitted on ' - f'{submission_date} but has not been marked as accepted or rejected ' - f'({days_since_submission} days pending).', - email_type='attention', - sections=[('Details', [ - ('Case', order_name), - ('Client', client_name), - ('Claim Number', claim_number), - ('Submitted', submission_date), - ('Days Pending', f'{days_since_submission} days'), - ])], - note='Action needed: Please update the acceptance status in the system.', - note_color='#d69e2e', - button_url=f'{order.get_base_url()}/web#id={order.id}&model=sale.order&view_type=form', - button_text='Open Case', - ) - - self.env['mail.mail'].sudo().create({ - 'subject': subject, - 'body_html': body_html, - 'email_to': ', '.join(to_emails), - 'model': 'sale.order', 'res_id': order.id, - }).send() - - # Mark as sent so it won't resend on next cron run / restart - order.with_context(skip_all_validations=True).write({ - 'x_fc_acceptance_reminder_sent': True, - }) - - _logger.info(f"Sent {reminder_type.lower()} acceptance reminder for {order.name}") - - except Exception as e: - _logger.error(f"Failed to send acceptance reminder for {order.name}: {e}") - - # ====================================================================== - # MARCH OF DIMES - WORKFLOW ACTION METHODS - # ====================================================================== - - def action_mod_schedule_assessment(self): - self.ensure_one() - self.write({ - 'x_fc_mod_status': 'assessment_scheduled', - 'x_fc_mod_assessment_scheduled_date': fields.Date.today(), - }) - - def action_mod_complete_assessment(self): - self.ensure_one() - self.write({ - 'x_fc_mod_status': 'assessment_completed', - 'x_fc_mod_assessment_completed_date': fields.Date.today(), - }) - - def action_mod_processing_drawing(self): - """Open wizard to attach drawing + photos and send quotation to MOD. - If drawing/photos already exist, they are pre-loaded in the wizard. - On confirm: saves to order, sets status to quote_submitted, sends email.""" - self.ensure_one() - # First set to processing_drawings - self.with_context(skip_status_emails=True).write({'x_fc_mod_status': 'processing_drawings'}) - # Open the wizard in drawing mode - return { - 'type': 'ir.actions.act_window', - 'name': 'Attach Drawing and Send Quotation', - 'res_model': 'fusion_claims.send.to.mod.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': { - 'active_id': self.id, - 'active_model': 'sale.order', - 'mod_wizard_mode': 'drawing', - }, - } - - def action_mod_awaiting_funding(self): - """Open wizard to record Application Submission Date before moving to awaiting funding.""" - self.ensure_one() - return { - 'type': 'ir.actions.act_window', - 'name': 'Application Submitted to March of Dimes', - 'res_model': 'fusion_claims.mod.awaiting.funding.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': {'active_id': self.id}, - } - - def action_mod_funding_approved(self): - """Open wizard to record case worker and HVMP reference on approval.""" - self.ensure_one() - return { - 'type': 'ir.actions.act_window', - 'name': 'Funding Approved', - 'res_model': 'fusion_claims.mod.funding.approved.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': {'active_id': self.id}, - } - - def action_mod_funding_denied(self): - self.ensure_one() - self.write({'x_fc_mod_status': 'funding_denied'}) - - def action_mod_contract_received(self): - """Open wizard to upload PCA document and record receipt.""" - self.ensure_one() - return { - 'type': 'ir.actions.act_window', - 'name': 'PCA Received', - 'res_model': 'fusion_claims.mod.pca.received.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': {'active_id': self.id}, - } - - def action_mod_in_production(self): - self.ensure_one() - self.write({ - 'x_fc_mod_status': 'in_production', - 'x_fc_mod_production_started_date': fields.Date.today(), - }) - - def action_mod_project_complete(self): - self.ensure_one() - self.write({ - 'x_fc_mod_status': 'project_complete', - 'x_fc_mod_project_completed_date': fields.Date.today(), - }) - - def action_mod_pod_submitted(self): - """Open wizard to attach completion photos + POD and send to case worker.""" - self.ensure_one() - return { - 'type': 'ir.actions.act_window', - 'name': 'Submit Completion Photos and POD', - 'res_model': 'fusion_claims.send.to.mod.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': { - 'active_id': self.id, - 'active_model': 'sale.order', - 'mod_wizard_mode': 'completion', - }, - } - - def action_mod_close_case(self): - self.ensure_one() - self.write({ - 'x_fc_mod_status': 'case_closed', - 'x_fc_mod_case_closed_date': fields.Date.today(), - }) - - def action_mod_on_hold(self): - self.ensure_one() - self.write({'x_fc_mod_status': 'on_hold'}) - - def action_mod_resume(self): - """Resume from on_hold - go back to in_production.""" - self.ensure_one() - self.write({'x_fc_mod_status': 'in_production'}) - - def action_cancel(self): - """Override: also set MOD status to cancelled when order is cancelled.""" - res = super().action_cancel() - for order in self: - if order._is_mod_sale() and order.x_fc_mod_status not in ('cancelled', False): - order.with_context(skip_all_validations=True, skip_status_emails=True).write({ - 'x_fc_mod_status': 'cancelled', - }) - return res - - def _get_mod_partner(self): - """Find or create the March of Dimes partner for invoicing.""" - ICP = self.env['ir.config_parameter'].sudo() - mod_email = ICP.get_param('fusion_claims.mod_default_email', 'hvmp@marchofdimes.ca') - partner = self.env['res.partner'].sudo().search([('email', '=', mod_email)], limit=1) - if not partner: - partner = self.env['res.partner'].sudo().create({ - 'name': 'March of Dimes Canada (HVMP)', - 'email': mod_email, - 'is_company': True, - }) - return partner - - def _create_mod_invoice(self, partner_id, invoice_lines, portion_type='full', label=''): - """Create a MOD invoice with given lines. Reusable for full/split.""" - self.ensure_one() - from odoo.fields import Command - ICP = self.env['ir.config_parameter'].sudo() - vendor_code = ICP.get_param('fusion_claims.mod_vendor_code', '') - authorizer = self.x_fc_authorizer_id - case_worker = self.x_fc_case_worker - - invoice = self.env['account.move'].sudo().create({ - 'move_type': 'out_invoice', - 'partner_id': partner_id, - 'partner_shipping_id': self.partner_id.id, - 'x_fc_source_sale_order_id': self.id, - 'x_fc_invoice_type': 'march_of_dimes', - 'x_fc_adp_invoice_portion': portion_type, - 'x_fc_authorizer_id': authorizer.id if authorizer else False, - 'x_fc_claim_number': self.x_fc_case_reference or '', - 'ref': self.x_fc_case_reference or self.name, - 'invoice_origin': f'{self.name}{label}', - 'invoice_line_ids': invoice_lines, - 'narration': Markup( - f'HVMP Reference: {self.x_fc_case_reference or "N/A"}
      ' - f'Client: {self.partner_id.name}
      ' - f'Case Worker: {case_worker.name if case_worker else "N/A"}
      ' - f'Sale Order: {self.name}
      ' - f'Vendor Code: {vendor_code}' - ), - }) - return invoice - - def action_send_to_mod(self): - """Open the Send to March of Dimes wizard.""" - self.ensure_one() - return { - 'type': 'ir.actions.act_window', - 'name': 'Send to March of Dimes', - 'res_model': 'fusion_claims.send.to.mod.wizard', - 'view_mode': 'form', - 'target': 'new', - 'context': { - 'active_id': self.id, - 'active_model': 'sale.order', - }, - } - - # --- MOD Document Preview Actions --- - - def action_open_mod_drawing(self): - self.ensure_one() - return self._action_open_document('x_fc_mod_drawing', 'Drawing') - - def action_open_mod_initial_photos(self): - self.ensure_one() - return self._action_open_image('x_fc_mod_initial_photos', 'Initial Photos') - - def action_open_mod_pca(self): - self.ensure_one() - return self._action_open_document('x_fc_mod_pca_document', 'PCA Document') - - def action_open_mod_pod(self): - self.ensure_one() - return self._action_open_document('x_fc_mod_proof_of_delivery', 'Proof of Delivery') - - def action_open_mod_completion_photos(self): - self.ensure_one() - return self._action_open_image('x_fc_mod_completion_photos', 'Completion Photos') - - def _action_open_image(self, field_name, label): - """Open an image attachment in a new browser tab.""" - self.ensure_one() - if not getattr(self, field_name): - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'No File', - 'message': f'No {label} uploaded yet.', - 'type': 'warning', 'sticky': False, - }, - } - attachment = self._get_or_create_attachment(field_name, label) - if attachment: - return { - 'type': 'ir.actions.act_url', - 'url': f'/web/content/{attachment.id}', - 'target': 'new', - } - return {'type': 'ir.actions.act_window_close'} - - # ====================================================================== - # MARCH OF DIMES - EMAIL METHODS - # ====================================================================== - - def _build_mod_case_detail_rows(self, include_amounts=False): - """Build case detail rows for MOD email templates.""" - self.ensure_one() - - def fmt(d): - return d.strftime('%B %d, %Y') if d else None - - status_label = dict(self._fields['x_fc_mod_status'].selection).get( - self.x_fc_mod_status, self.x_fc_mod_status or '') - rows = [ - ('Case', self.name), - ('Client', self.partner_id.name or 'N/A'), - ('HVMP Reference', self.x_fc_case_reference or None), - ('Status', status_label or None), - ('Funding Approved', fmt(self.x_fc_case_approved)), - ('Est. Completion', fmt(self.x_fc_estimated_completion_date)), - ] - if include_amounts: - approved = self.x_fc_mod_approved_amount or 0 - rows.extend([ - ('Order Total', f'${self.amount_total:,.2f}'), - ]) - if approved: - rows.append(('MOD Approved', f'${approved:,.2f}')) - if approved < self.amount_total: - rows.append(('Client Portion', f'${self.amount_total - approved:,.2f}')) - return [(l, v) for l, v in rows if v is not None] - - def _mod_email_build(self, **kwargs): - """Wrapper around _email_build that overrides the footer for MOD emails.""" - # Build the email normally - html = self._email_build(**kwargs) - # Replace the footer text - html = html.replace( - 'This is an automated notification from the ADP Claims Management System.', - 'This is an automated notification from the Accessibility Case Management System.', - ) - return html - - def _get_mod_email_recipients(self, include_client=True, include_authorizer=True, - include_mod_contact=False, include_sales_rep=True): - """Get email recipients for MOD notifications.""" - self.ensure_one() - to_emails = [] - cc_emails = [] - - client = self.partner_id - authorizer = self.x_fc_authorizer_id - sales_rep = self.user_id - - if include_client and client and client.email: - to_emails.append(client.email) - - if include_authorizer and authorizer and authorizer.email: - if to_emails: - cc_emails.append(authorizer.email) - else: - to_emails.append(authorizer.email) - - if include_mod_contact and self.x_fc_mod_contact_email: - cc_emails.append(self.x_fc_mod_contact_email) - - if include_sales_rep and sales_rep and sales_rep.email: - cc_emails.append(sales_rep.email) - - office_cc = self._get_office_cc_emails() - - return { - 'to': to_emails, - 'cc': cc_emails, - 'office_cc': office_cc, - 'authorizer': authorizer, - 'sales_rep': sales_rep, - 'client': client, - } - - def _send_mod_email(self, subject_prefix, title, summary, email_type='info', - include_client=True, include_authorizer=True, - include_mod_contact=False, include_sales_rep=True, - sections=None, note=None, note_color=None, - attachments=None, attachment_names=None): - """Generic MOD email sender to avoid repeating boilerplate.""" - self.ensure_one() - if not self._is_email_notifications_enabled(): - return False - - recipients = self._get_mod_email_recipients( - include_client=include_client, include_authorizer=include_authorizer, - include_mod_contact=include_mod_contact, include_sales_rep=include_sales_rep) - to_emails = recipients.get('to', []) - cc_emails = recipients.get('cc', []) + recipients.get('office_cc', []) - if not to_emails and not cc_emails: - return False - - client_name = (recipients.get('client') or self.partner_id).name or 'Client' - sender_name = (recipients.get('sales_rep') or self.env.user).name - - body_html = self._mod_email_build( - title=title, - summary=summary, - email_type=email_type, - sections=sections or [('Case Details', self._build_mod_case_detail_rows())], - note=note, - note_color=note_color, - button_url=f'{self.get_base_url()}/web#id={self.id}&model=sale.order&view_type=form', - sender_name=sender_name, - attachments_note=', '.join(attachment_names) if attachment_names else None, - ) - - email_to = ', '.join(to_emails) if to_emails else ', '.join(cc_emails[:1]) - email_cc_str = ', '.join(cc_emails) if to_emails else ', '.join(cc_emails[1:]) - - subject = f'{subject_prefix} - {client_name} - {self.name}' - try: - mail_vals = { - 'subject': subject, - 'body_html': body_html, - 'email_to': email_to, - 'email_cc': email_cc_str, - 'model': 'sale.order', - 'res_id': self.id, - } - if attachments: - mail_vals['attachment_ids'] = [(6, 0, attachments)] - self.env['mail.mail'].sudo().create(mail_vals).send() - self._email_chatter_log(f'{title} email sent', email_to, email_cc_str, - [f'Attachments: {", ".join(attachment_names)}'] if attachment_names else None) - _logger.info(f"MOD email '{title}' sent for {self.name}") - return True - except Exception as e: - _logger.error(f"Failed to send MOD email '{title}' for {self.name}: {e}") - return False - - # --- Individual MOD status email methods --- - - def _send_mod_assessment_scheduled_email(self): - """Email: Assessment has been scheduled. To: Client, CC: Authorizer.""" - self.ensure_one() - client_name = self.partner_id.name or 'Client' - assess_date = self.x_fc_assessment_start_date.strftime('%B %d, %Y') if hasattr(self, 'x_fc_assessment_start_date') and self.x_fc_assessment_start_date else 'a date to be confirmed' - return self._send_mod_email( - subject_prefix='Assessment Scheduled', - title='Assessment Scheduled', - summary=f'An accessibility assessment for {client_name} has been scheduled for {assess_date}.', - email_type='info', - include_client=True, include_authorizer=True, - note='What to expect: Our assessor will visit your home to evaluate ' - 'the accessibility modifications needed. Please ensure someone is available at the ' - 'scheduled time. If you need to reschedule, please contact us as soon as possible.', - ) - - def _send_mod_assessment_completed_email(self): - """Email: Assessment completed. To: Client.""" - self.ensure_one() - client_name = self.partner_id.name or 'Client' - return self._send_mod_email( - subject_prefix='Assessment Completed', - title='Assessment Completed', - summary=f'The accessibility assessment for {client_name} has been completed.', - email_type='success', - include_client=True, include_authorizer=False, - note='Next steps: Our team is now preparing the drawings and quotation ' - 'based on the assessment. We will send you the proposal once it is ready for review.', - note_color='#38a169', - ) - - def _send_mod_quote_submitted_email(self): - """Email: Quote/drawings submitted. To: Client, CC: Authorizer, MOD contact.""" - self.ensure_one() - client_name = self.partner_id.name or 'Client' - return self._send_mod_email( - subject_prefix='Quotation & Drawings Submitted', - title='Quotation & Drawings Submitted', - summary=f'The quotation and drawings for {client_name} have been submitted for review.', - email_type='info', - include_client=True, include_authorizer=True, include_mod_contact=True, - note='Next steps: The proposal will be reviewed by March of Dimes. ' - 'The funding review process typically takes several weeks. We will follow up ' - 'regularly and keep you updated on the status.', - ) - - def _send_mod_funding_approved_email(self): - """Email: Funding approved by MOD. To: Client, CC: Authorizer, Sales Rep.""" - self.ensure_one() - client_name = self.partner_id.name or 'Client' - commitment = f'${self.x_fc_mod_approved_amount:,.2f}' if self.x_fc_mod_approved_amount else 'TBD' - return self._send_mod_email( - subject_prefix='Funding Approved', - title='Great News - Funding Approved', - summary=f'The March of Dimes funding for {client_name} has been approved.', - email_type='success', - include_client=True, include_authorizer=True, - sections=[('Case Details', self._build_mod_case_detail_rows(include_amounts=True))], - note=f'Approved Amount: {commitment}

      ' - 'Next steps: We will receive the Payment Commitment Agreement (PCA) ' - 'from March of Dimes shortly. Once received, we will proceed with the project. ' - 'Our team will be in touch to discuss timelines.', - note_color='#38a169', - ) - - def _send_mod_funding_denied_email(self): - """Email: Funding denied. To: Client, CC: Authorizer, Sales Rep.""" - self.ensure_one() - client_name = self.partner_id.name or 'Client' - return self._send_mod_email( - subject_prefix='Funding Update', - title='Funding Update', - summary=f'Unfortunately, the March of Dimes funding request for {client_name} ' - f'was not approved at this time.', - email_type='urgent', - include_client=True, include_authorizer=True, - note='Your options: You may contact March of Dimes directly for more ' - 'information about the decision. Alternative funding options or private payment ' - 'arrangements may be available. Our team is here to help explore your options.', - note_color='#c53030', - ) - - def _send_mod_contract_received_email(self): - """Email: PCA/Contract received. To: Client, CC: Sales Rep.""" - self.ensure_one() - client_name = self.partner_id.name or 'Client' - completion_date = self.x_fc_estimated_completion_date.strftime('%B %d, %Y') if self.x_fc_estimated_completion_date else 'TBD' - return self._send_mod_email( - subject_prefix='Contract Received - Project Starting', - title='Contract Received', - summary=f'The Payment Commitment Agreement for {client_name} has been received from March of Dimes.', - email_type='success', - include_client=True, include_authorizer=False, - note=f'Project Completion Deadline: {completion_date}

      ' - 'Next steps: We will now begin processing your project. ' - 'Our team will be in contact to schedule the next steps and keep you updated on progress.', - note_color='#38a169', - ) - - def _send_mod_invoice_submitted_email(self): - """Email: Invoice submitted to MOD. To: MOD contact.""" - self.ensure_one() - client_name = self.partner_id.name or 'Client' - if not self.x_fc_mod_contact_email: - _logger.warning(f"No MOD contact email for {self.name}, skipping invoice email") - return False - return self._send_mod_email( - subject_prefix='Invoice Submitted', - title='Invoice Submitted', - summary=f'Please find attached the invoice for the accessibility modification project for {client_name}.', - email_type='info', - include_client=False, include_authorizer=False, include_mod_contact=True, - sections=[('Invoice Details', self._build_mod_case_detail_rows(include_amounts=True))], - note='Please process the initial payment (90%) as per the Payment Commitment Agreement terms.', - ) - - def _send_mod_initial_payment_email(self): - """Email: 90% payment received, project progressing. To: Client.""" - self.ensure_one() - client_name = self.partner_id.name or 'Client' - amount = f'${self.x_fc_mod_initial_payment_amount:,.2f}' if self.x_fc_mod_initial_payment_amount else 'the initial payment' - return self._send_mod_email( - subject_prefix='Project Update - Payment Received', - title='Project Update', - summary=f'We have received {amount} for the accessibility project for {client_name}. ' - f'Your project is now in active production.', - email_type='success', - include_client=True, include_authorizer=False, - note='What is happening: Your project is being processed and we are ' - 'working towards completion. We will keep you updated on key milestones.', - note_color='#38a169', - ) - - def _send_mod_project_complete_email(self): - """Email: Project/installation complete. To: Client, CC: Authorizer.""" - self.ensure_one() - client_name = self.partner_id.name or 'Client' - return self._send_mod_email( - subject_prefix='Project Complete', - title='Project Installation Complete', - summary=f'The accessibility modification project for {client_name} has been completed.', - email_type='success', - include_client=True, include_authorizer=True, - note='Next steps: We will be submitting the photos and proof of delivery ' - 'to March of Dimes for final payment processing. If you have any questions or ' - 'concerns about the installation, please contact us.', - note_color='#38a169', - ) - - def _send_mod_pod_submitted_email(self): - """Email: Photos/POD submitted to MOD. To: MOD contact, CC: Authorizer.""" - self.ensure_one() - client_name = self.partner_id.name or 'Client' - return self._send_mod_email( - subject_prefix='Proof of Delivery Submitted', - title='Proof of Delivery Submitted', - summary=f'Photos and proof of delivery for {client_name} have been submitted.', - email_type='info', - include_client=False, include_authorizer=True, include_mod_contact=True, - note='Please process the final payment (10%) as per the Payment Commitment Agreement terms.', - ) - - def _send_mod_final_payment_email(self): - """Email: Final payment received. To: Client.""" - self.ensure_one() - client_name = self.partner_id.name or 'Client' - return self._send_mod_email( - subject_prefix='Final Payment Received', - title='Final Payment Received', - summary=f'The final payment for the accessibility project for {client_name} has been received.', - email_type='success', - include_client=True, include_authorizer=False, - note='Thank you! All payments have been received and your project is ' - 'now fully complete. If you need any support or have warranty questions, ' - 'please do not hesitate to contact us.', - note_color='#38a169', - ) - - def _send_mod_case_closed_email(self): - """Email: Case closed. To: Client, CC: Authorizer.""" - self.ensure_one() - client_name = self.partner_id.name or 'Client' - return self._send_mod_email( - subject_prefix='Case Closed', - title='Case Closed', - summary=f'The accessibility modification case for {client_name} has been closed.', - email_type='info', - include_client=True, include_authorizer=True, - note='Important: Your equipment comes with a one-year warranty on ' - 'materials, equipment, and workmanship from the date of installation. ' - 'If you experience any issues, please contact us immediately.', - ) - - def _send_mod_followup_email(self): - """Auto-email to client when follow-up activity is not completed on time.""" - self.ensure_one() - if not self._is_email_notifications_enabled(): - return False - - client = self.partner_id - if not client or not client.email: - return False - - client_name = client.name or 'Client' - sender_name = (self.user_id or self.env.user).name - followup_count = self.x_fc_mod_followup_count or 0 - - body_html = self._mod_email_build( - title='Project Status Check-In', - summary=f'We wanted to check in on the accessibility modification project for ' - f'{client_name}.', - email_type='info', - sections=[('Case Details', self._build_mod_case_detail_rows())], - note='We are here to help: If you have received any updates from March of Dimes ' - 'regarding your funding application, please let us know so we can proceed accordingly. ' - 'If you have any questions about your project, feel free to reach out to us anytime.', - button_url=False, - sender_name=sender_name, - ) - - try: - self.env['mail.mail'].sudo().create({ - 'subject': f'Project Update Check-In - {client_name} - {self.name}', - 'body_html': body_html, - 'email_to': client.email, - 'model': 'sale.order', 'res_id': self.id, - }).send() - self.with_context(skip_all_validations=True).write({ - 'x_fc_mod_last_followup_date': fields.Date.today(), - 'x_fc_mod_followup_count': followup_count + 1, - 'x_fc_mod_followup_escalated': True, - }) - self._email_chatter_log('MOD Follow-up auto-email sent (activity overdue)', client.email) - return True - except Exception as e: - _logger.error(f"Failed to send MOD follow-up email for {self.name}: {e}") - return False - - # ====================================================================== - # MARCH OF DIMES - TWILIO SMS - # ====================================================================== - - def _send_mod_sms(self, trigger): - """Send Twilio SMS for key MOD status changes.""" - self.ensure_one() - ICP = self.env['ir.config_parameter'].sudo() - if ICP.get_param('fusion_claims.twilio_enabled', 'False').lower() not in ('true', '1', 'yes'): - return False - - client = self.partner_id - phone = client.mobile or client.phone if client else None - if not phone: - _logger.info(f"No phone number for {self.name}, skipping SMS") - return False - - client_name = client.name or 'Client' - company_phone = self.company_id.phone or '' - - messages = { - 'assessment_scheduled': ( - f"Hi {client_name}, your accessibility assessment with Westin Healthcare " - f"has been scheduled. We will confirm the exact date and time shortly. " - f"For questions, call {company_phone}." - ), - 'funding_approved': ( - f"Hi {client_name}, great news! Your March of Dimes funding has been approved. " - f"Our team will be in touch with next steps. Questions? Call {company_phone}." - ), - 'initial_payment_received': ( - f"Hi {client_name}, we have received the initial payment for your project. " - f"Work is in progress. We will keep you updated. Call {company_phone} for info." - ), - 'project_complete': ( - f"Hi {client_name}, your accessibility modification project is now complete! " - f"If you have any questions or concerns, call us at {company_phone}." - ), - } - - message = messages.get(trigger) - if not message: - return False - - return self._twilio_send_sms(phone, message) - - def _twilio_send_sms(self, to_number, message): - """Send SMS via Twilio REST API.""" - import requests as req - self.ensure_one() - ICP = self.env['ir.config_parameter'].sudo() - account_sid = ICP.get_param('fusion_claims.twilio_account_sid', '') - auth_token = ICP.get_param('fusion_claims.twilio_auth_token', '') - from_number = ICP.get_param('fusion_claims.twilio_phone_number', '') - - if not all([account_sid, auth_token, from_number]): - _logger.warning("Twilio not configured, skipping SMS") - return False - - url = f'https://api.twilio.com/2010-04-01/Accounts/{account_sid}/Messages.json' - try: - resp = req.post(url, data={ - 'To': to_number, - 'From': from_number, - 'Body': message, - }, auth=(account_sid, auth_token), timeout=10) - if resp.status_code in (200, 201): - self._email_chatter_log(f'SMS sent to {to_number}', to_number) - _logger.info(f"Twilio SMS sent to {to_number} for {self.name}") - return True - else: - _logger.error(f"Twilio SMS failed ({resp.status_code}): {resp.text}") - return False - except Exception as e: - _logger.error(f"Twilio SMS error for {self.name}: {e}") - return False - - # ====================================================================== - # MARCH OF DIMES - FOLLOW-UP CRON - # ====================================================================== - - @api.model - def _cron_mod_schedule_followups(self): - """Cron: Schedule bi-weekly follow-up activities for MOD cases awaiting funding.""" - from datetime import timedelta - - ICP = self.env['ir.config_parameter'].sudo() - interval_days = int(ICP.get_param('fusion_claims.mod_followup_interval_days', '14')) - - # Statuses that need follow-up (waiting for funding decision) - followup_statuses = ['quote_submitted', 'awaiting_funding'] - - orders = self.search([ - ('x_fc_sale_type', '=', 'march_of_dimes'), - ('x_fc_mod_status', 'in', followup_statuses), - ]) - - today = fields.Date.today() - - for order in orders: - try: - next_date = order.x_fc_mod_next_followup_date - # If no next followup date set, or it's in the past, schedule one - if not next_date or next_date <= today: - # Calculate from last followup or quote submission date - base_date = order.x_fc_mod_last_followup_date or order.x_fc_case_submitted or today - new_followup = base_date + timedelta(days=interval_days) - if new_followup <= today: - new_followup = today + timedelta(days=1) # Schedule for tomorrow at minimum - - # Create scheduled activity - activity_type = self.env.ref( - 'fusion_claims.mail_activity_type_mod_followup', raise_if_not_found=False) - if activity_type: - # Check if there's already an open activity of this type - existing = self.env['mail.activity'].search([ - ('res_model', '=', 'sale.order'), - ('res_id', '=', order.id), - ('activity_type_id', '=', activity_type.id), - ], limit=1) - if not existing: - order.activity_schedule( - 'fusion_claims.mail_activity_type_mod_followup', - date_deadline=new_followup, - user_id=(order.user_id or self.env.user).id, - summary=f'MOD Follow-up: Call {order.partner_id.name or "client"} for funding update', - ) - - order.with_context(skip_all_validations=True).write({ - 'x_fc_mod_next_followup_date': new_followup, - }) - _logger.info(f"Scheduled MOD follow-up for {order.name} on {new_followup}") - except Exception as e: - _logger.error(f"Failed to schedule MOD follow-up for {order.name}: {e}") - - @api.model - def _cron_mod_escalate_followups(self): - """Cron: Send auto-email if follow-up activity is overdue (not completed within 3 days).""" - from datetime import timedelta - - ICP = self.env['ir.config_parameter'].sudo() - escalation_days = int(ICP.get_param('fusion_claims.mod_followup_escalation_days', '3')) - - activity_type = self.env.ref( - 'fusion_claims.mail_activity_type_mod_followup', raise_if_not_found=False) - if not activity_type: - return - - # Find overdue follow-up activities - cutoff_date = fields.Date.today() - timedelta(days=escalation_days) - overdue_activities = self.env['mail.activity'].search([ - ('res_model', '=', 'sale.order'), - ('activity_type_id', '=', activity_type.id), - ('date_deadline', '<=', cutoff_date), - ]) - - for activity in overdue_activities: - try: - order = self.browse(activity.res_id) - if not order.exists() or not order._is_mod_sale(): - continue - if order.x_fc_mod_status not in ('quote_submitted', 'awaiting_funding'): - # Status moved past follow-up phase, clean up the activity - activity.unlink() - continue - # Only escalate once per activity - if not order.x_fc_mod_followup_escalated: - order._send_mod_followup_email() - # Clean up the overdue activity and let the scheduler create a new one - activity.unlink() - except Exception as e: - _logger.error(f"Failed to escalate MOD follow-up for activity {activity.id}: {e}") - - # ====================================================================== - # ODSP EMAIL AUTOMATION - # ====================================================================== - - def _odsp_email_build(self, **kwargs): - """Wrapper around _email_build that overrides the footer for ODSP emails.""" - html = self._email_build(**kwargs) - html = html.replace( - 'This is an automated notification from the ADP Claims Management System.', - 'This is an automated notification from the ODSP Case Management System.', - ) - return html - - def _get_sa_mobility_email(self): - """Get the configured SA Mobility email address.""" - return self.env['ir.config_parameter'].sudo().get_param( - 'fusion_claims.sa_mobility_email', 'samobility@ontario.ca') - - def _send_sa_mobility_email(self, request_type='repair', device_description='', - attachment_ids=None, email_body_notes=None): - """Send SA Mobility submission email. - - Args: - request_type: 'batteries' or 'repair' - device_description: human-readable device label - attachment_ids: list of ir.attachment IDs to attach - email_body_notes: optional urgency/priority notes for the email body - """ - self.ensure_one() - client_name = self.partner_id.name or 'Client' - member_id = self.x_fc_odsp_member_id or self.partner_id.x_fc_odsp_member_id or '' - client_address = self.partner_id.contact_address or '' - - sa_email = self._get_sa_mobility_email() - subject = f'{client_name} - ODSP - {member_id}' if member_id else client_name - - summary_parts = [] - if email_body_notes: - summary_parts.append( - f'{email_body_notes}' - ) - - if request_type == 'batteries': - summary_parts.append( - f'Client is getting {device_description or "Electric Wheelchair / Mobility Scooter"} from ADP. ' - f'ADP is covering the equipment. We have submitted request for approval to ADP ' - f'and client is seeking approval from ODSP for Batteries.' - ) - else: - summary_parts.append( - f'Client has {device_description or "mobility equipment"} ' - f'and is looking for replacement parts and repairs. ' - f'Please find the attached SA Mobility Form and Quotation.' - ) - summary = '
      '.join(summary_parts) - - sections = [('Client Details', [ - ('Client Name', client_name), - ('ODSP Member ID', member_id), - ('Address', client_address), - ('Order #', self.name), - ])] - - body_html = self._odsp_email_build( - title='SA Mobility Request', - summary=summary, - email_type='info', - sections=sections, - sender_name=(self.user_id or self.env.user).name, - ) - - cc_emails = [] - if self.user_id and self.user_id.email: - cc_emails.append(self.user_id.email) - - mail_vals = { - 'subject': subject, - 'body_html': body_html, - 'email_to': sa_email, - 'email_cc': ', '.join(cc_emails) if cc_emails else '', - 'model': 'sale.order', - 'res_id': self.id, - } - if attachment_ids: - mail_vals['attachment_ids'] = [(6, 0, attachment_ids)] - - try: - self.env['mail.mail'].sudo().create(mail_vals).send() - self._email_chatter_log( - 'SA Mobility request sent', sa_email, - ', '.join(cc_emails) if cc_emails else None) - _logger.info(f"SA Mobility email sent for {self.name} to {sa_email}") - except Exception as e: - _logger.error(f"Failed to send SA Mobility email for {self.name}: {e}") - from odoo.exceptions import UserError - raise UserError(f"Failed to send email: {e}") - - def _send_sa_mobility_completion_email(self, attachment_ids=None): - """Send SA Mobility completion email with signed form, POD, and invoice.""" - self.ensure_one() - client_name = self.partner_id.name or 'Client' - member_id = self.x_fc_odsp_member_id or '' - sa_email = self._get_sa_mobility_email() - - subject = f'{client_name} - {member_id} - Completed' - summary = ( - f'Delivery/repair for {client_name} has been completed. ' - f'Please find the attached signed SA Mobility approval form, ' - f'Proof of Delivery, and Invoice.' - ) - - body_html = self._odsp_email_build( - title='SA Mobility - Completed', - summary=summary, - email_type='success', - sections=[('Case Details', [ - ('Client Name', client_name), - ('ODSP Member ID', member_id), - ('Order #', self.name), - ])], - sender_name=(self.user_id or self.env.user).name, - ) - - cc_emails = [] - if self.user_id and self.user_id.email: - cc_emails.append(self.user_id.email) - - mail_vals = { - 'subject': subject, - 'body_html': body_html, - 'email_to': sa_email, - 'email_cc': ', '.join(cc_emails) if cc_emails else '', - 'model': 'sale.order', - 'res_id': self.id, - } - if attachment_ids: - mail_vals['attachment_ids'] = [(6, 0, attachment_ids)] - - try: - self.env['mail.mail'].sudo().create(mail_vals).send() - self._email_chatter_log( - 'SA Mobility completion sent', sa_email, - ', '.join(cc_emails) if cc_emails else None) - _logger.info(f"SA Mobility completion email sent for {self.name}") - except Exception as e: - _logger.error(f"Failed to send SA Mobility completion email for {self.name}: {e}") - - def _send_odsp_submission_email(self, attachment_ids=None, email_body_notes=None): - """Send ODSP submission email to the selected ODSP office.""" - self.ensure_one() - if not self.x_fc_odsp_office_id or not self.x_fc_odsp_office_id.email: - from odoo.exceptions import UserError - raise UserError("ODSP Office email is required. Please select an ODSP Office with an email.") - - client_name = self.partner_id.name or 'Client' - member_id = self.x_fc_odsp_member_id or '' - office_email = self.x_fc_odsp_office_id.email - - subject = f'ODSP Application - {client_name} - {member_id}' - - summary_parts = [] - if email_body_notes: - summary_parts.append( - f'{email_body_notes}' - ) - summary_parts.append( - f'Please find enclosed the ODSP application documents for ' - f'{client_name} (Member ID: {member_id}).' - ) - summary = '
      '.join(summary_parts) - - body_html = self._odsp_email_build( - title='ODSP Application Submission', - summary=summary, - email_type='info', - sections=[('Application Details', [ - ('Client Name', client_name), - ('ODSP Member ID', member_id), - ('Order #', self.name), - ])], - sender_name=(self.user_id or self.env.user).name, - ) - - cc_emails = [] - if self.user_id and self.user_id.email: - cc_emails.append(self.user_id.email) - - mail_vals = { - 'subject': subject, - 'body_html': body_html, - 'email_to': office_email, - 'email_cc': ', '.join(cc_emails) if cc_emails else '', - 'model': 'sale.order', - 'res_id': self.id, - } - if attachment_ids: - mail_vals['attachment_ids'] = [(6, 0, attachment_ids)] - - try: - self.env['mail.mail'].sudo().create(mail_vals).send() - self._email_chatter_log('ODSP submission sent', office_email, - ', '.join(cc_emails) if cc_emails else None) - if self._get_odsp_status() in ('quotation', 'documents_ready'): - self._odsp_advance_status('submitted_to_odsp', - "Status auto-advanced after ODSP submission email.") - _logger.info(f"ODSP submission email sent for {self.name} to {office_email}") - except Exception as e: - _logger.error(f"Failed to send ODSP submission email for {self.name}: {e}") diff --git a/fusion_claims/fusion_claims/models/sale_order_line.py b/fusion_claims/fusion_claims/models/sale_order_line.py deleted file mode 100644 index c7118ef..0000000 --- a/fusion_claims/fusion_claims/models/sale_order_line.py +++ /dev/null @@ -1,362 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2025 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) -# Part of the Fusion Claim Assistant product family. - -from odoo import models, fields, api - - -class SaleOrderLine(models.Model): - _inherit = 'sale.order.line' - - # ========================================================================== - # PARENT FIELD FOR VISIBILITY (used by Studio conditions) - # ========================================================================== - x_fc_is_adp_sale = fields.Boolean( - compute='_compute_is_adp_sale_line', - string='Is ADP Sale', - store=False, - help='True if parent order is an ADP sale - used for column visibility', - ) - - def _compute_is_adp_sale_line(self): - """Check if parent order is an ADP sale.""" - for line in self: - is_adp = False - if line.order_id and line.order_id.x_fc_sale_type: - is_adp = 'adp' in str(line.order_id.x_fc_sale_type).lower() - line.x_fc_is_adp_sale = is_adp - - @api.depends('product_id', 'product_id.default_code') - def _compute_adp_device_type(self): - """Compute ADP device type from the product's device code.""" - ADPDevice = self.env['fusion.adp.device.code'].sudo() - for line in self: - device_type = '' - if line.product_id: - # Get the device code from product (default_code or custom field) - device_code = line._get_adp_device_code() - if device_code: - # Look up device type in ADP database - adp_device = ADPDevice.search([ - ('device_code', '=', device_code), - ('active', '=', True) - ], limit=1) - if adp_device: - device_type = adp_device.device_type or '' - line.x_fc_adp_device_type = device_type - - # ========================================================================== - # SERIAL NUMBER AND DEVICE PLACEMENT - # ========================================================================== - x_fc_serial_number = fields.Char( - string='Serial Number', - help='Serial number for this product', - ) - x_fc_device_placement = fields.Selection( - selection=[ - ('L', 'Left'), - ('R', 'Right'), - ('NA', 'N/A'), - ], - string='Device Placement', - default='NA', - help='Device placement position (Left/Right/N/A)', - ) - - # ========================================================================== - # DEDUCTION FIELDS - # ========================================================================== - x_fc_deduction_type = fields.Selection( - selection=[ - ('none', 'No Deduction'), - ('pct', 'Percentage'), - ('amt', 'Amount'), - ], - string='Deduction Type', - default='none', - help='Type of ADP deduction applied to this line', - ) - x_fc_deduction_value = fields.Float( - string='Deduction Value', - digits='Product Price', - help='Deduction value (percentage if PCT, dollar amount if AMT)', - ) - - # ========================================================================== - # ADP REFERENCE FIELDS - # ========================================================================== - x_fc_adp_max_price = fields.Float( - string='ADP Max Price', - digits='Product Price', - help='Maximum price ADP will cover for this device (from mobility manual)', - ) - x_fc_sn_required = fields.Boolean( - string='S/N Required', - help='Is serial number required for this device?', - ) - - # ========================================================================== - # ADP DEVICE APPROVAL TRACKING - # ========================================================================== - x_fc_adp_approved = fields.Boolean( - string='ADP Approved', - default=False, - help='Was this device approved by ADP in the application approval?', - ) - x_fc_adp_device_type = fields.Char( - string='ADP Device Type', - compute='_compute_adp_device_type', - store=True, - help='Device type from ADP mobility manual (for approval matching)', - ) - - # ========================================================================== - # COMPUTED ADP PORTIONS - # ========================================================================== - x_fc_adp_portion = fields.Monetary( - string='ADP Portion', - compute='_compute_adp_portions', - store=True, - currency_field='currency_id', - help='ADP portion for this line', - ) - x_fc_client_portion = fields.Monetary( - string='Client Portion', - compute='_compute_adp_portions', - store=True, - currency_field='currency_id', - help='Client portion for this line', - ) - - # ========================================================================== - # COMPUTE ADP PORTIONS WITH DEDUCTIONS AND APPROVAL STATUS - # ========================================================================== - @api.depends('price_subtotal', 'product_uom_qty', 'price_unit', 'product_id', - 'order_id.x_fc_sale_type', 'order_id.x_fc_client_type', - 'order_id.x_fc_device_verification_complete', - 'x_fc_deduction_type', 'x_fc_deduction_value', 'x_fc_adp_max_price', - 'x_fc_adp_approved') - def _compute_adp_portions(self): - """Compute ADP and client portions based on product's ADP price, client type, and approval status. - - IMPORTANT: - 1. If a product has NON-ADP code (NON-ADP, NON-FUNDED, etc.): Client pays 100% - 2. If a product is NOT in the ADP device database: Client pays 100% - 3. If a device is NOT approved by ADP: Client pays 100% - 4. Only products with valid ADP codes that are approved get the 75%/25% (or 100%/0%) split - """ - ADPDevice = self.env['fusion.adp.device.code'].sudo() - - for line in self: - # Get sale type and client type from parent order - order = line.order_id - if not order: - line.x_fc_adp_portion = 0 - line.x_fc_client_portion = 0 - continue - - # Check if this is an ADP sale - if not order._is_adp_sale(): - line.x_fc_adp_portion = 0 - line.x_fc_client_portion = 0 - continue - - # Skip non-product lines - if not line.product_id or line.product_uom_qty <= 0: - line.x_fc_adp_portion = 0 - line.x_fc_client_portion = 0 - continue - - # ================================================================= - # CHECK 1: Is this a NON-ADP funded product? - # Products with NON-ADP, NON-FUNDED, UNFUNDED codes = 100% client - # ================================================================= - if line.product_id.is_non_adp_funded(): - line.x_fc_adp_portion = 0 - line.x_fc_client_portion = line.price_subtotal - continue - - # ================================================================= - # CHECK 2: Does this product have a valid ADP device code? - # Products without valid ADP codes in the database = 100% client - # ================================================================= - device_code = line._get_adp_device_code() - is_adp_device = False - if device_code: - # Check if this code exists in the ADP mobility manual database - is_adp_device = ADPDevice.search_count([ - ('device_code', '=', device_code), - ('active', '=', True) - ]) > 0 - - # If product has NO valid ADP code in database: client pays 100% - if not is_adp_device: - line.x_fc_adp_portion = 0 - line.x_fc_client_portion = line.price_subtotal - continue - - # ================================================================= - # CHECK 3: If this is an ADP device but NOT approved: 100% client - # ================================================================= - if order.x_fc_device_verification_complete and not line.x_fc_adp_approved: - line.x_fc_adp_portion = 0 - line.x_fc_client_portion = line.price_subtotal - continue - - # ================================================================= - # STANDARD CALCULATION: Product is a valid, approved ADP device - # ================================================================= - - # Get client type and determine base percentages - client_type = order._get_client_type() - if client_type == 'REG': - # REG: 75% ADP, 25% Client - base_adp_pct = 0.75 - base_client_pct = 0.25 - else: - # ODS, OWP, ACS, LTC, SEN, CCA: 100% ADP, 0% Client - base_adp_pct = 1.0 - base_client_pct = 0.0 - - # Get the ADP price from the product - adp_price = 0 - if line.product_id and line.product_id.product_tmpl_id: - product_tmpl = line.product_id.product_tmpl_id - if hasattr(product_tmpl, 'x_fc_adp_price'): - adp_price = product_tmpl.x_fc_adp_price or 0 - if not adp_price and line.x_fc_adp_max_price: - adp_price = line.x_fc_adp_max_price - if not adp_price: - adp_price = line.price_unit - - qty = line.product_uom_qty - adp_base_total = adp_price * qty - - # Apply deductions - if line.x_fc_deduction_type == 'pct' and line.x_fc_deduction_value: - # PCT: ADP only covers deduction_value% of their portion - effective_adp_pct = base_adp_pct * (line.x_fc_deduction_value / 100) - effective_client_pct = 1 - effective_adp_pct - adp_portion = adp_base_total * effective_adp_pct - client_portion = adp_base_total * effective_client_pct - elif line.x_fc_deduction_type == 'amt' and line.x_fc_deduction_value: - # AMT: Subtract fixed amount from ADP portion - base_adp_amount = adp_base_total * base_adp_pct - adp_portion = max(0, base_adp_amount - line.x_fc_deduction_value) - client_portion = adp_base_total - adp_portion - else: - # No deduction - standard calculation based on ADP price - adp_portion = adp_base_total * base_adp_pct - client_portion = adp_base_total * base_client_pct - - line.x_fc_adp_portion = adp_portion - line.x_fc_client_portion = client_portion - - # ========================================================================== - # GETTER METHODS - # ========================================================================== - def _get_adp_device_code(self): - """Get ADP device code from product. - - Checks multiple sources in order: - 1. x_fc_adp_device_code (module field) - 2. x_adp_code (Studio/custom field) - 3. default_code - 4. Code in parentheses in product name (e.g., "Product Name (SE0001109)") - """ - import re - - self.ensure_one() - if not self.product_id: - return '' - - product_tmpl = self.product_id.product_tmpl_id - ADPDevice = self.env['fusion.adp.device.code'].sudo() - - # 1. Check x_fc_adp_device_code (module field) - code = '' - if hasattr(product_tmpl, 'x_fc_adp_device_code'): - code = getattr(product_tmpl, 'x_fc_adp_device_code', '') or '' - - # Verify code exists in ADP database - if code and ADPDevice.search_count([('device_code', '=', code), ('active', '=', True)]) > 0: - return code - - # 2. Check x_adp_code (Studio/custom field) - if hasattr(product_tmpl, 'x_adp_code'): - code = getattr(product_tmpl, 'x_adp_code', '') or '' - if code and ADPDevice.search_count([('device_code', '=', code), ('active', '=', True)]) > 0: - return code - - # 3. Check default_code - code = self.product_id.default_code or '' - if code and ADPDevice.search_count([('device_code', '=', code), ('active', '=', True)]) > 0: - return code - - # 4. Try to extract code from product name in parentheses - # E.g., "[MXA-1618] GEOMATRIX SILVERBACK MAX BACKREST - ACTIVE (SE0001109)" - product_name = self.product_id.name or '' - # Find all codes in parentheses - matches = re.findall(r'\(([A-Z0-9]+)\)', product_name) - for potential_code in matches: - if ADPDevice.search_count([('device_code', '=', potential_code), ('active', '=', True)]) > 0: - return potential_code - - # 5. Final fallback - return default_code even if not in ADP database - return self.product_id.default_code or '' - - def _get_serial_number(self): - """Get serial number from mapped field or native field.""" - self.ensure_one() - ICP = self.env['ir.config_parameter'].sudo() - field_name = ICP.get_param('fusion_claims.field_sol_serial', 'x_fc_serial_number') - - # Try mapped field first - if hasattr(self, field_name): - value = getattr(self, field_name, None) - if value: - return value - - # Fallback to native field - return self.x_fc_serial_number or '' - - def _get_device_placement(self): - """Get device placement.""" - self.ensure_one() - return self.x_fc_device_placement or 'NA' - - # ========================================================================== - # INVOICE LINE PREPARATION - # ========================================================================== - def _prepare_invoice_line(self, **optional_values): - """Override to copy ADP line fields to the invoice line.""" - vals = super()._prepare_invoice_line(**optional_values) - vals.update({ - 'x_fc_serial_number': self.x_fc_serial_number, - 'x_fc_device_placement': self.x_fc_device_placement, - 'x_fc_deduction_type': self.x_fc_deduction_type, - 'x_fc_deduction_value': self.x_fc_deduction_value, - 'x_fc_adp_max_price': self.x_fc_adp_max_price, - 'x_fc_sn_required': self.x_fc_sn_required, - 'x_fc_adp_approved': self.x_fc_adp_approved, - 'x_fc_adp_device_type': self.x_fc_adp_device_type, - }) - return vals - - # ========================================================================== - # ONCHANGE FOR ADP MAX PRICE LOOKUP - # ========================================================================== - @api.onchange('product_id') - def _onchange_product_adp_info(self): - """Lookup ADP info from device codes when product changes.""" - if self.product_id: - # Try to find device code in the reference table - device_code = self._get_adp_device_code() - if device_code: - adp_device = self.env['fusion.adp.device.code'].sudo().search([ - ('device_code', '=', device_code) - ], limit=1) - if adp_device: - self.x_fc_adp_max_price = adp_device.adp_price - self.x_fc_sn_required = adp_device.sn_required diff --git a/fusion_claims/fusion_claims/models/submission_history.py b/fusion_claims/fusion_claims/models/submission_history.py deleted file mode 100644 index 17f7218..0000000 --- a/fusion_claims/fusion_claims/models/submission_history.py +++ /dev/null @@ -1,237 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) -# Part of the Fusion Claim Assistant product family. - -from odoo import api, fields, models -from markupsafe import Markup -import logging - -_logger = logging.getLogger(__name__) - - -class FusionSubmissionHistory(models.Model): - """Track submission history for ADP applications. - - Each record represents one submission or resubmission to ADP, - including the documents submitted, the result, and any rejection reasons. - """ - _name = 'fusion.submission.history' - _description = 'ADP Submission History' - _order = 'submission_date desc, id desc' - _rec_name = 'display_name' - - # ========================================================================== - # RELATIONSHIPS - # ========================================================================== - sale_order_id = fields.Many2one( - 'sale.order', - string='Sale Order', - required=True, - ondelete='cascade', - index=True, - ) - - # ========================================================================== - # SUBMISSION DETAILS - # ========================================================================== - display_name = fields.Char( - string='Display Name', - compute='_compute_display_name', - store=True, - ) - - submission_number = fields.Integer( - string='Submission #', - default=1, - help='Sequence number for this submission (1 = first submission, 2+ = resubmissions)', - ) - - submission_type = fields.Selection( - selection=[ - ('initial', 'Initial Submission'), - ('resubmission', 'Resubmission'), - ('correction', 'Correction'), - ], - string='Type', - default='initial', - ) - - submission_date = fields.Date( - string='Submission Date', - default=fields.Date.today, - required=True, - ) - - submitted_by_id = fields.Many2one( - 'res.users', - string='Submitted By', - default=lambda self: self.env.user, - ) - - # ========================================================================== - # DOCUMENTS SUBMITTED (copies at time of submission) - # ========================================================================== - final_application = fields.Binary( - string='Final Application (PDF)', - attachment=True, - help='Copy of the final application PDF at time of submission', - ) - final_application_filename = fields.Char( - string='Final Application Filename', - ) - - xml_file = fields.Binary( - string='XML File', - attachment=True, - help='Copy of the XML file at time of submission', - ) - xml_filename = fields.Char( - string='XML Filename', - ) - - # ========================================================================== - # RESULT TRACKING - # ========================================================================== - result = fields.Selection( - selection=[ - ('pending', 'Pending'), - ('accepted', 'Accepted'), - ('rejected', 'Rejected'), - ('approved', 'Approved'), - ('denied', 'Denied'), - ], - string='Result', - default='pending', - ) - - result_date = fields.Date( - string='Result Date', - help='Date when the result was received from ADP', - ) - - # ========================================================================== - # REJECTION DETAILS (if rejected) - # ========================================================================== - rejection_reason = fields.Selection( - selection=[ - ('name_correction', 'Name Correction Needed'), - ('healthcard_correction', 'Health Card Correction Needed'), - ('duplicate_claim', 'Duplicate Claim Exists'), - ('xml_format_error', 'XML Format/Validation Error'), - ('missing_info', 'Missing Required Information'), - ('other', 'Other'), - ], - string='Rejection Reason', - ) - - rejection_details = fields.Text( - string='Rejection Details', - help='Additional details about the rejection', - ) - - # ========================================================================== - # CORRECTION NOTES (for resubmissions) - # ========================================================================== - correction_notes = fields.Text( - string='Correction Notes', - help='Notes about what was corrected for this resubmission', - ) - - # ========================================================================== - # COMPUTED FIELDS - # ========================================================================== - @api.depends('sale_order_id', 'submission_number', 'submission_type') - def _compute_display_name(self): - for record in self: - order_name = record.sale_order_id.name or 'New' - type_label = dict(record._fields['submission_type'].selection).get( - record.submission_type, record.submission_type - ) - record.display_name = f"{order_name} - Submission #{record.submission_number} ({type_label})" - - # ========================================================================== - # HELPER METHODS - # ========================================================================== - @api.model - def create_from_submission(self, sale_order, submission_type='initial', correction_notes=None): - """Create a submission history record from a sale order submission. - - Args: - sale_order: The sale.order record being submitted - submission_type: 'initial', 'resubmission', or 'correction' - correction_notes: Optional notes about corrections made - - Returns: - The created fusion.submission.history record - """ - # Get next submission number - existing_count = self.search_count([('sale_order_id', '=', sale_order.id)]) - submission_number = existing_count + 1 - - # If submission_number > 1, it's a resubmission - if submission_number > 1 and submission_type == 'initial': - submission_type = 'resubmission' - - vals = { - 'sale_order_id': sale_order.id, - 'submission_number': submission_number, - 'submission_type': submission_type, - 'submission_date': fields.Date.today(), - 'submitted_by_id': self.env.user.id, - 'correction_notes': correction_notes, - } - - # Copy current documents - if sale_order.x_fc_final_submitted_application: - vals['final_application'] = sale_order.x_fc_final_submitted_application - vals['final_application_filename'] = sale_order.x_fc_final_application_filename - - if sale_order.x_fc_xml_file: - vals['xml_file'] = sale_order.x_fc_xml_file - vals['xml_filename'] = sale_order.x_fc_xml_filename - - record = self.create(vals) - - # Post to chatter - sale_order.message_post( - body=Markup( - '
      ' - '

      ' - f' Submission #{submission_number} Recorded

      ' - '' - f'' - f'' - f'' - '
      Type:{dict(self._fields["submission_type"].selection).get(submission_type)}
      Date:{fields.Date.today().strftime("%B %d, %Y")}
      By:{self.env.user.name}
      ' - + (f'

      Corrections: {correction_notes}

      ' if correction_notes else '') + - '
      ' - ), - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - - return record - - def update_result(self, result, rejection_reason=None, rejection_details=None): - """Update the result of a submission. - - Args: - result: 'accepted', 'rejected', 'approved', or 'denied' - rejection_reason: Selection value for rejection reason - rejection_details: Text details for rejection - """ - self.ensure_one() - - vals = { - 'result': result, - 'result_date': fields.Date.today(), - } - - if result == 'rejected': - vals['rejection_reason'] = rejection_reason - vals['rejection_details'] = rejection_details - - self.write(vals) - - return self diff --git a/fusion_claims/fusion_claims/models/technician_location.py b/fusion_claims/fusion_claims/models/technician_location.py deleted file mode 100644 index c680fb2..0000000 --- a/fusion_claims/fusion_claims/models/technician_location.py +++ /dev/null @@ -1,116 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) - -""" -Fusion Technician Location -GPS location logging for field technicians. -""" - -from odoo import models, fields, api, _ -import logging - -_logger = logging.getLogger(__name__) - - -class FusionTechnicianLocation(models.Model): - _name = 'fusion.technician.location' - _description = 'Technician Location Log' - _order = 'logged_at desc' - - user_id = fields.Many2one( - 'res.users', - string='Technician', - required=True, - index=True, - ondelete='cascade', - ) - latitude = fields.Float( - string='Latitude', - digits=(10, 7), - required=True, - ) - longitude = fields.Float( - string='Longitude', - digits=(10, 7), - required=True, - ) - accuracy = fields.Float( - string='Accuracy (m)', - help='GPS accuracy in meters', - ) - logged_at = fields.Datetime( - string='Logged At', - default=fields.Datetime.now, - required=True, - index=True, - ) - source = fields.Selection([ - ('portal', 'Portal'), - ('app', 'Mobile App'), - ], string='Source', default='portal') - - @api.model - def log_location(self, latitude, longitude, accuracy=None): - """Log the current user's location. Called from portal JS.""" - return self.sudo().create({ - 'user_id': self.env.user.id, - 'latitude': latitude, - 'longitude': longitude, - 'accuracy': accuracy or 0, - 'source': 'portal', - }) - - @api.model - def get_latest_locations(self): - """Get the most recent location for each technician (for map view).""" - self.env.cr.execute(""" - SELECT DISTINCT ON (user_id) - user_id, latitude, longitude, accuracy, logged_at - FROM fusion_technician_location - WHERE logged_at > NOW() - INTERVAL '24 hours' - ORDER BY user_id, logged_at DESC - """) - rows = self.env.cr.dictfetchall() - result = [] - for row in rows: - user = self.env['res.users'].sudo().browse(row['user_id']) - result.append({ - 'user_id': row['user_id'], - 'name': user.name, - 'latitude': row['latitude'], - 'longitude': row['longitude'], - 'accuracy': row['accuracy'], - 'logged_at': str(row['logged_at']), - }) - return result - - @api.model - def _cron_cleanup_old_locations(self): - """Remove location logs based on configurable retention setting. - - Setting (fusion_claims.location_retention_days): - - Empty / not set => keep 30 days (default) - - "0" => delete at end of day (keep today only) - - "1" .. "N" => keep for N days - """ - ICP = self.env['ir.config_parameter'].sudo() - raw = (ICP.get_param('fusion_claims.location_retention_days') or '').strip() - - if raw == '': - retention_days = 30 # default: 1 month - else: - try: - retention_days = max(int(raw), 0) - except (ValueError, TypeError): - retention_days = 30 - - cutoff = fields.Datetime.subtract(fields.Datetime.now(), days=retention_days) - old_records = self.search([('logged_at', '<', cutoff)]) - count = len(old_records) - if count: - old_records.unlink() - _logger.info( - "Cleaned up %d technician location records (retention=%d days)", - count, retention_days, - ) diff --git a/fusion_claims/fusion_claims/models/technician_task.py b/fusion_claims/fusion_claims/models/technician_task.py deleted file mode 100644 index 442a42d..0000000 --- a/fusion_claims/fusion_claims/models/technician_task.py +++ /dev/null @@ -1,2307 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) - -""" -Fusion Technician Task -Scheduling and task management for field technicians. -Replaces Monday.com for technician schedule tracking. -""" - -from odoo import models, fields, api, _ -from odoo.exceptions import UserError, ValidationError -from odoo.osv import expression -from markupsafe import Markup -import logging -import json -import uuid -import requests -from datetime import datetime as dt_datetime, timedelta -import urllib.parse - -_logger = logging.getLogger(__name__) - - -class FusionTechnicianTask(models.Model): - _name = 'fusion.technician.task' - _description = 'Technician Task' - _order = 'scheduled_date, sequence, time_start, id' - _inherit = ['mail.thread', 'mail.activity.mixin'] - _rec_name = 'name' - - def _compute_display_name(self): - """Richer display name: Client - Type | 9:00 AM - 10:00 AM.""" - type_labels = dict(self._fields['task_type'].selection) - for task in self: - client = task.x_fc_sync_client_name if task.x_fc_sync_source else (task.partner_id.name or '') - ttype = type_labels.get(task.task_type, task.task_type or '') - start = self._float_to_time_str(task.time_start) - end = self._float_to_time_str(task.time_end) - parts = [client, ttype] - label = ' - '.join(p for p in parts if p) - if start and end: - label += f' | {start} - {end}' - task.display_name = label or task.name - - # ------------------------------------------------------------------ - # STORE HOURS HELPER - # ------------------------------------------------------------------ - def _get_store_hours(self): - """Return (open_hour, close_hour) from settings. Defaults 9.0 / 18.0.""" - ICP = self.env['ir.config_parameter'].sudo() - try: - open_h = float(ICP.get_param('fusion_claims.store_open_hour', '9.0') or '9.0') - except (ValueError, TypeError): - open_h = 9.0 - try: - close_h = float(ICP.get_param('fusion_claims.store_close_hour', '18.0') or '18.0') - except (ValueError, TypeError): - close_h = 18.0 - return (open_h, close_h) - - # ------------------------------------------------------------------ - # CORE FIELDS - # ------------------------------------------------------------------ - name = fields.Char( - string='Task Reference', - required=True, - copy=False, - readonly=True, - default=lambda self: _('New'), - ) - active = fields.Boolean(default=True) - - # Cross-instance sync fields - x_fc_sync_source = fields.Char( - 'Source Instance', readonly=True, index=True, - help='Origin instance ID if this is a synced shadow task (e.g. westin, mobility)', - ) - x_fc_sync_remote_id = fields.Integer( - 'Remote Task ID', readonly=True, - help='ID of the task on the remote instance', - ) - x_fc_sync_uuid = fields.Char( - 'Sync UUID', readonly=True, index=True, copy=False, - help='Unique ID for cross-instance deduplication', - ) - x_fc_is_shadow = fields.Boolean( - 'Shadow Task', compute='_compute_is_shadow', store=True, - help='True if this task was synced from another instance', - ) - x_fc_sync_client_name = fields.Char( - 'Synced Client Name', readonly=True, - help='Client name from the remote instance (shadow tasks only)', - ) - - x_fc_source_label = fields.Char( - 'Source', compute='_compute_is_shadow', store=True, - ) - - @api.depends('x_fc_sync_source') - def _compute_is_shadow(self): - local_id = self.env['ir.config_parameter'].sudo().get_param( - 'fusion_claims.sync_instance_id', '') - for task in self: - task.x_fc_is_shadow = bool(task.x_fc_sync_source) - task.x_fc_source_label = task.x_fc_sync_source or local_id - - technician_id = fields.Many2one( - 'res.users', - string='Technician', - required=True, - tracking=True, - domain="[('x_fc_is_field_staff', '=', True)]", - help='Shows: users marked as Field Staff (technicians and sales reps)', - ) - technician_name = fields.Char( - related='technician_id.name', - string='Technician Name', - store=True, - ) - - sale_order_id = fields.Many2one( - 'sale.order', - string='Related Case', - tracking=True, - ondelete='restrict', - help='Sale order / case linked to this task (required)', - ) - sale_order_name = fields.Char( - related='sale_order_id.name', - string='Case Reference', - store=True, - ) - - task_type = fields.Selection([ - ('delivery', 'Delivery'), - ('repair', 'Repair'), - ('pickup', 'Pickup'), - ('troubleshoot', 'Troubleshooting'), - ('assessment', 'Assessment'), - ('installation', 'Installation'), - ('maintenance', 'Maintenance'), - ('other', 'Other'), - ], string='Task Type', required=True, default='delivery', tracking=True) - - # ------------------------------------------------------------------ - # SCHEDULING - # ------------------------------------------------------------------ - scheduled_date = fields.Date( - string='Scheduled Date', - required=True, - tracking=True, - default=fields.Date.context_today, - index=True, - ) - time_start = fields.Float( - string='Start Time', - help='Start time in hours (e.g. 9.5 = 9:30 AM)', - default=9.0, - ) - time_end = fields.Float( - string='End Time', - help='End time in hours (e.g. 10.5 = 10:30 AM)', - default=10.0, - ) - time_start_display = fields.Char( - string='Start', - compute='_compute_time_displays', - ) - time_end_display = fields.Char( - string='End', - compute='_compute_time_displays', - ) - # Legacy 12h selection fields -- kept for DB compatibility, hidden on form - time_start_12h = fields.Selection( - selection='_get_time_selection', - string='Start Time (12h)', - compute='_compute_time_12h', - inverse='_inverse_time_start_12h', - store=True, - ) - time_end_12h = fields.Selection( - selection='_get_time_selection', - string='End Time (12h)', - compute='_compute_time_12h', - inverse='_inverse_time_end_12h', - store=True, - ) - sequence = fields.Integer( - string='Sequence', - default=10, - help='Order of task within the day', - ) - duration_hours = fields.Float( - string='Duration', - default=1.0, - help='Task duration in hours. Auto-calculates end time.', - ) - - # Task type -> default duration mapping - TASK_TYPE_DURATIONS = { - 'delivery': 1.0, - 'repair': 2.0, - 'pickup': 0.5, - 'troubleshoot': 1.5, - 'assessment': 1.5, - 'installation': 2.0, - 'maintenance': 1.5, - 'other': 1.0, - } - - # Previous task travel warning banner - prev_task_summary_html = fields.Html( - string='Previous Task', - compute='_compute_prev_task_summary', - sanitize=False, - ) - - # Datetime fields for calendar view (computed from date + float time) - datetime_start = fields.Datetime( - string='Start', - compute='_compute_datetimes', - inverse='_inverse_datetime_start', - store=True, - help='Combined start datetime for calendar display', - ) - datetime_end = fields.Datetime( - string='End', - compute='_compute_datetimes', - inverse='_inverse_datetime_end', - store=True, - help='Combined end datetime for calendar display', - ) - - # Schedule info helper for the form - schedule_info_html = fields.Html( - string='Schedule Info', - compute='_compute_schedule_info', - sanitize=False, - ) - - # ------------------------------------------------------------------ - # STATUS - # ------------------------------------------------------------------ - status = fields.Selection([ - ('scheduled', 'Scheduled'), - ('en_route', 'En Route'), - ('in_progress', 'In Progress'), - ('completed', 'Completed'), - ('cancelled', 'Cancelled'), - ('rescheduled', 'Rescheduled'), - ], string='Status', default='scheduled', required=True, tracking=True, index=True) - - priority = fields.Selection([ - ('0', 'Normal'), - ('1', 'Urgent'), - ('2', 'Emergency'), - ], string='Priority', default='0') - - color = fields.Integer( - string='Color Index', - compute='_compute_color', - ) - - # ------------------------------------------------------------------ - # CLIENT / ADDRESS - # ------------------------------------------------------------------ - partner_id = fields.Many2one( - 'res.partner', - string='Client', - tracking=True, - help='Client for this task', - ) - partner_phone = fields.Char( - related='partner_id.phone', - string='Client Phone', - ) - - # Address fields - computed from shipping address or manually set - address_partner_id = fields.Many2one( - 'res.partner', - string='Task Address', - help='Partner record containing the task address (usually shipping address)', - ) - address_street = fields.Char(string='Street') - address_street2 = fields.Char(string='Unit/Suite #') - address_city = fields.Char(string='City') - address_state_id = fields.Many2one('res.country.state', string='Province') - address_zip = fields.Char(string='Postal Code') - address_buzz_code = fields.Char(string='Buzz Code', help='Building buzzer code for entry') - address_display = fields.Text( - string='Full Address', - compute='_compute_address_display', - ) - - # Geocoding - address_lat = fields.Float(string='Latitude', digits=(10, 7)) - address_lng = fields.Float(string='Longitude', digits=(10, 7)) - - # ------------------------------------------------------------------ - # TASK DETAILS - # ------------------------------------------------------------------ - description = fields.Text( - string='Task Description', - help='What needs to be done', - ) - equipment_needed = fields.Text( - string='Equipment / Materials Needed', - help='Tools and materials the technician should bring', - ) - pod_required = fields.Boolean( - string='POD Required', - default=False, - help='Proof of Delivery signature required', - ) - - # ------------------------------------------------------------------ - # COMPLETION - # ------------------------------------------------------------------ - completion_notes = fields.Html( - string='Completion Notes', - help='Notes from the technician about what was done', - ) - completion_datetime = fields.Datetime( - string='Completed At', - tracking=True, - ) - voice_note_audio = fields.Binary( - string='Voice Recording', - attachment=True, - ) - voice_note_transcription = fields.Text( - string='Voice Transcription', - ) - - # ------------------------------------------------------------------ - # TRAVEL - # ------------------------------------------------------------------ - travel_time_minutes = fields.Integer( - string='Travel Time (min)', - help='Estimated travel time from previous task in minutes', - ) - travel_distance_km = fields.Float( - string='Travel Distance (km)', - digits=(8, 1), - ) - travel_origin = fields.Char( - string='Travel From', - help='Origin address for travel calculation', - ) - previous_task_id = fields.Many2one( - 'fusion.technician.task', - string='Previous Task', - help='The task before this one in the schedule (for travel calculation)', - ) - - # ------------------------------------------------------------------ - # PUSH NOTIFICATION TRACKING - # ------------------------------------------------------------------ - push_notified = fields.Boolean( - string='Push Notified', - default=False, - help='Whether a push notification was sent for this task', - ) - push_notified_datetime = fields.Datetime( - string='Notified At', - ) - - # ------------------------------------------------------------------ - # COMPUTED FIELDS - # ------------------------------------------------------------------ - - # ------------------------------------------------------------------ - # SLOT AVAILABILITY HELPERS - # ------------------------------------------------------------------ - - def _find_next_available_slot(self, tech_id, date, preferred_start=9.0, - duration=1.0, exclude_task_id=False, - dest_lat=0, dest_lng=0): - """Find the next available time slot for a technician on a given date. - - Scans all non-cancelled tasks for that tech+date, sorts them, and - walks through the day (9 AM - 6 PM) looking for a gap that fits - the requested duration PLUS travel time from the previous task. - - :param tech_id: res.users id of the technician - :param date: date object for the day to check - :param preferred_start: float hour to start looking from (default 9.0) - :param duration: required slot length in hours (default 1.0) - :param exclude_task_id: task id to exclude (when editing an existing task) - :param dest_lat: latitude of the destination (new task location) - :param dest_lng: longitude of the destination (new task location) - :returns: (start_float, end_float) or (False, False) if fully booked - """ - STORE_OPEN, STORE_CLOSE = self._get_store_hours() - - if not tech_id or not date: - return (preferred_start, preferred_start + duration) - - domain = [ - ('technician_id', '=', tech_id), - ('scheduled_date', '=', date), - ('status', 'not in', ['cancelled']), - ] - if exclude_task_id: - domain.append(('id', '!=', exclude_task_id)) - - booked = self.sudo().search(domain, order='time_start') - - # Build sorted list of (start, end, lat, lng) intervals - intervals = [] - for b in booked: - intervals.append(( - max(b.time_start, STORE_OPEN), - min(b.time_end, STORE_CLOSE), - b.address_lat or 0, - b.address_lng or 0, - )) - - def _travel_hours(from_lat, from_lng, to_lat, to_lng): - """Calculate travel time in hours between two locations. - Returns 0 if coordinates are missing. Rounds up to 15-min.""" - if not from_lat or not from_lng or not to_lat or not to_lng: - return 0 - travel_min = self._quick_travel_time( - from_lat, from_lng, to_lat, to_lng) - if travel_min > 0: - import math - return math.ceil(travel_min / 15.0) * 0.25 - return 0 - - def _travel_from_prev(iv_lat, iv_lng): - """Travel from a previous booked task TO the new task.""" - return _travel_hours(iv_lat, iv_lng, dest_lat, dest_lng) - - def _travel_to_next(next_lat, next_lng): - """Travel FROM the new task TO the next booked task.""" - return _travel_hours(dest_lat, dest_lng, next_lat, next_lng) - - def _check_gap_fits(cursor, dur, idx): - """Check if a slot at 'cursor' for 'dur' hours fits before - the interval at index 'idx' (accounting for travel TO that task).""" - if idx >= len(intervals): - return cursor + dur <= STORE_CLOSE - next_start, _ne, next_lat, next_lng = intervals[idx] - travel_fwd = _travel_to_next(next_lat, next_lng) - return cursor + dur + travel_fwd <= next_start - - # Walk through gaps, starting from preferred_start - cursor = max(preferred_start, STORE_OPEN) - - for i, (iv_start, iv_end, iv_lat, iv_lng) in enumerate(intervals): - if cursor + duration <= iv_start: - # Check travel time from new task end TO next booked task - if _check_gap_fits(cursor, duration, i): - return (cursor, cursor + duration) - # Not enough travel time -- try pushing start earlier or skip - # If we can't fit here, fall through to jump past this interval - # Jump past this booked interval + travel buffer from prev to new - new_cursor = max(cursor, iv_end) - travel = _travel_from_prev(iv_lat, iv_lng) - new_cursor += travel - # Snap to nearest 15 min - new_cursor = round(new_cursor * 4) / 4 - cursor = new_cursor - - # Check gap after last interval (no next task, so no forward travel needed) - if cursor + duration <= STORE_CLOSE: - return (cursor, cursor + duration) - - # No gap found from preferred_start onward -- wrap and try from start - if preferred_start > STORE_OPEN: - cursor = STORE_OPEN - for i, (iv_start, iv_end, iv_lat, iv_lng) in enumerate(intervals): - if cursor + duration <= iv_start: - if _check_gap_fits(cursor, duration, i): - return (cursor, cursor + duration) - new_cursor = max(cursor, iv_end) - travel = _travel_from_prev(iv_lat, iv_lng) - new_cursor += travel - new_cursor = round(new_cursor * 4) / 4 - cursor = new_cursor - if cursor + duration <= STORE_CLOSE: - return (cursor, cursor + duration) - - return (False, False) - - def _get_available_gaps(self, tech_id, date, exclude_task_id=False): - """Return a list of available (start, end) gaps for a technician on a date. - - Used by schedule_info_html to show green "available" badges. - """ - STORE_OPEN, STORE_CLOSE = self._get_store_hours() - - if not tech_id or not date: - return [(STORE_OPEN, STORE_CLOSE)] - - domain = [ - ('technician_id', '=', tech_id), - ('scheduled_date', '=', date), - ('status', 'not in', ['cancelled']), - ] - if exclude_task_id: - domain.append(('id', '!=', exclude_task_id)) - - booked = self.sudo().search(domain, order='time_start') - intervals = [(max(b.time_start, STORE_OPEN), min(b.time_end, STORE_CLOSE)) - for b in booked] - - gaps = [] - cursor = STORE_OPEN - for iv_start, iv_end in intervals: - if cursor < iv_start: - gaps.append((cursor, iv_start)) - cursor = max(cursor, iv_end) - if cursor < STORE_CLOSE: - gaps.append((cursor, STORE_CLOSE)) - return gaps - - @api.model - def _get_time_selection(self): - """Generate 12-hour time slots every 15 minutes, store hours only (9 AM - 6 PM).""" - times = [] - for hour in range(9, 18): # 9 AM to 5:45 PM - for minute in (0, 15, 30, 45): - float_val = hour + minute / 60.0 - key = f'{float_val:.2f}' - period = 'AM' if hour < 12 else 'PM' - display_hour = hour % 12 or 12 - label = f'{display_hour}:{minute:02d} {period}' - times.append((key, label)) - # Add 6:00 PM as end-time option - times.append(('18.00', '6:00 PM')) - return times - - @api.depends('time_start', 'time_end') - def _compute_time_12h(self): - """Sync the 12h selection fields from the raw float values.""" - for task in self: - task.time_start_12h = f'{(task.time_start or 9.0):.2f}' - task.time_end_12h = f'{(task.time_end or 10.0):.2f}' - - def _inverse_time_start_12h(self): - for task in self: - if task.time_start_12h: - task.time_start = float(task.time_start_12h) - - def _inverse_time_end_12h(self): - for task in self: - if task.time_end_12h: - task.time_end = float(task.time_end_12h) - - @api.depends('time_start', 'time_end') - def _compute_time_displays(self): - """Convert float hours to readable time strings.""" - for task in self: - task.time_start_display = self._float_to_time_str(task.time_start) - task.time_end_display = self._float_to_time_str(task.time_end) - - @api.onchange('task_type') - def _onchange_task_type_duration(self): - """Set default duration based on task type.""" - if self.task_type: - self.duration_hours = self.TASK_TYPE_DURATIONS.get(self.task_type, 1.0) - # Also recalculate end time - if self.time_start: - _open, close = self._get_store_hours() - self.time_end = min(self.time_start + self.duration_hours, close) - - @api.onchange('time_start', 'duration_hours') - def _onchange_compute_end_time(self): - """Auto-compute end time from start + duration. Also run overlap check.""" - if self.time_start and self.duration_hours: - _open, close = self._get_store_hours() - new_end = min(self.time_start + self.duration_hours, close) - self.time_end = new_end - # Run overlap snap if we have enough data - if self.technician_id and self.scheduled_date and self.time_start and self.time_end: - result = self._snap_if_overlap() - if result: - return result - - @api.depends('scheduled_date', 'time_start', 'time_end') - def _compute_datetimes(self): - """Combine date + float time into proper Datetime fields for calendar. - time_start/time_end are LOCAL hours; datetime_start/end must be UTC for Odoo.""" - import pytz - user_tz = pytz.timezone(self.env.user.tz or 'UTC') - for task in self: - if task.scheduled_date: - # Build local datetime, then convert to UTC - base = dt_datetime.combine(task.scheduled_date, dt_datetime.min.time()) - store_open, _close = task._get_store_hours() - local_start = user_tz.localize(base + timedelta(hours=task.time_start or store_open)) - local_end = user_tz.localize(base + timedelta(hours=task.time_end or (store_open + 1.0))) - task.datetime_start = local_start.astimezone(pytz.utc).replace(tzinfo=None) - task.datetime_end = local_end.astimezone(pytz.utc).replace(tzinfo=None) - else: - task.datetime_start = False - task.datetime_end = False - - def _inverse_datetime_start(self): - """When datetime_start is changed (e.g. from calendar drag), update date + time.""" - import pytz - user_tz = pytz.timezone(self.env.user.tz or 'UTC') - for task in self: - if task.datetime_start: - local_dt = pytz.utc.localize(task.datetime_start).astimezone(user_tz) - task.scheduled_date = local_dt.date() - task.time_start = local_dt.hour + local_dt.minute / 60.0 - - def _inverse_datetime_end(self): - """When datetime_end is changed (e.g. from calendar resize), update time_end.""" - import pytz - user_tz = pytz.timezone(self.env.user.tz or 'UTC') - for task in self: - if task.datetime_end: - local_dt = pytz.utc.localize(task.datetime_end).astimezone(user_tz) - task.time_end = local_dt.hour + local_dt.minute / 60.0 - - @api.depends('technician_id', 'scheduled_date') - def _compute_schedule_info(self): - """Show booked + available time slots for the technician on the selected date.""" - for task in self: - if not task.technician_id or not task.scheduled_date: - task.schedule_info_html = '' - continue - - exclude_id = task.id if task.id else 0 - # Find other tasks for the same technician+date - others = self.sudo().search([ - ('technician_id', '=', task.technician_id.id), - ('scheduled_date', '=', task.scheduled_date), - ('status', 'not in', ['cancelled']), - ('id', '!=', exclude_id), - ], order='time_start') - - if not others: - s_open, s_close = self._get_store_hours() - open_str = self._float_to_time_str(s_open) - close_str = self._float_to_time_str(s_close) - task.schedule_info_html = Markup( - f'
      ' - f' All slots available ({open_str} - {close_str})
      ' - ) - continue - - # Booked badges - booked_lines = [] - for o in others: - start_str = self._float_to_time_str(o.time_start) - end_str = self._float_to_time_str(o.time_end) - type_label = dict(self._fields['task_type'].selection).get(o.task_type, o.task_type) - client_name = o.partner_id.name or '' - booked_lines.append( - f'' - f'{start_str} - {end_str} ({type_label}{" - " + client_name if client_name else ""})' - f'' - ) - - # Available gaps badges - gaps = self._get_available_gaps( - task.technician_id.id, task.scheduled_date, - exclude_task_id=exclude_id, - ) - avail_lines = [] - for g_start, g_end in gaps: - # Only show gaps >= 15 min - if g_end - g_start >= 0.25: - avail_lines.append( - f'' - f'{self._float_to_time_str(g_start)} - {self._float_to_time_str(g_end)}' - f'' - ) - - html_parts = [ - '
      ', - ' Booked: ', - ' '.join(booked_lines), - ] - if avail_lines: - html_parts.append( - '
      ' - 'Available: ' - + ' '.join(avail_lines) - ) - elif not avail_lines: - html_parts.append( - '
      ' - 'Fully booked' - ) - html_parts.append('
      ') - - task.schedule_info_html = Markup(''.join(html_parts)) - - @api.depends('technician_id', 'scheduled_date', 'time_start', - 'address_lat', 'address_lng', 'address_street') - def _compute_prev_task_summary(self): - """Show previous task info + travel time warning with color coding.""" - for task in self: - if not task.technician_id or not task.scheduled_date: - task.prev_task_summary_html = '' - continue - - exclude_id = task.id if task.id else 0 - # Find the task that ends just before this one starts - prev_tasks = self.sudo().search([ - ('technician_id', '=', task.technician_id.id), - ('scheduled_date', '=', task.scheduled_date), - ('status', 'not in', ['cancelled']), - ('id', '!=', exclude_id), - ('time_end', '<=', task.time_start or 99.0), - ], order='time_end desc', limit=1) - - if not prev_tasks: - # Check if this is the first task of the day -- show start location info - task.prev_task_summary_html = Markup( - '
      ' - ' First task of the day -- ' - 'travel calculated from start location.
      ' - ) - continue - - prev = prev_tasks[0] - prev_start = self._float_to_time_str(prev.time_start) - prev_end = self._float_to_time_str(prev.time_end) - type_label = dict(self._fields['task_type'].selection).get( - prev.task_type, prev.task_type or '') - client_name = prev.partner_id.name or '' - prev_addr = prev.address_display or 'No address' - - # Calculate gap between prev task end and this task start - s_open, _s_close = self._get_store_hours() - gap_hours = (task.time_start or s_open) - (prev.time_end or s_open) - gap_minutes = int(gap_hours * 60) - - # Try to get travel time if both have coordinates - travel_minutes = 0 - travel_text = '' - if (prev.address_lat and prev.address_lng and - task.address_lat and task.address_lng): - travel_minutes = self._quick_travel_time( - prev.address_lat, prev.address_lng, - task.address_lat, task.address_lng, - ) - if travel_minutes > 0: - travel_text = f'{travel_minutes} min drive' - else: - travel_text = 'Could not calculate travel time' - elif prev.address_street and task.address_street: - travel_text = 'Save to calculate travel time' - else: - travel_text = 'Address missing -- cannot calculate travel' - - # Determine color coding - if travel_minutes > 0 and gap_minutes >= travel_minutes: - bg_class = 'alert-success' # Green -- enough time - icon = 'fa-check-circle' - status_text = ( - f'{gap_minutes} min gap -- enough travel time ' - f'(~{travel_minutes} min drive)' - ) - elif travel_minutes > 0 and gap_minutes > 0: - bg_class = 'alert-warning' # Yellow -- tight - icon = 'fa-exclamation-triangle' - status_text = ( - f'{gap_minutes} min gap -- tight! ' - f'Travel is ~{travel_minutes} min drive' - ) - elif travel_minutes > 0 and gap_minutes <= 0: - bg_class = 'alert-danger' # Red -- impossible - icon = 'fa-times-circle' - status_text = ( - f'No gap! Previous task ends at {prev_end}. ' - f'Travel is ~{travel_minutes} min drive' - ) - else: - bg_class = 'alert-info' # Blue -- no travel data yet - icon = 'fa-info-circle' - status_text = travel_text - - html = ( - f'
      ' - f' ' - f'Previous: {prev.name} ' - f'({type_label}) {prev_start} - {prev_end}' - f'{" -- " + client_name if client_name else ""}' - f'
      ' - f' {prev_addr}' - f'
      ' - f' {status_text}' - f'
      ' - ) - task.prev_task_summary_html = Markup(html) - - def _quick_travel_time(self, from_lat, from_lng, to_lat, to_lng): - """Quick inline travel time calculation using Google Distance Matrix API. - Returns travel time in minutes, or 0 if unavailable.""" - try: - api_key = self.env['ir.config_parameter'].sudo().get_param( - 'fusion_claims.google_maps_api_key', '') - if not api_key: - return 0 - - url = 'https://maps.googleapis.com/maps/api/distancematrix/json' - params = { - 'origins': f'{from_lat},{from_lng}', - 'destinations': f'{to_lat},{to_lng}', - 'mode': 'driving', - 'avoid': 'tolls', - 'departure_time': 'now', - 'key': api_key, - } - resp = requests.get(url, params=params, timeout=5) - data = resp.json() - if data.get('status') == 'OK': - elements = data['rows'][0]['elements'][0] - if elements.get('status') == 'OK': - # Use duration_in_traffic if available, else duration - duration = elements.get( - 'duration_in_traffic', elements.get('duration', {})) - seconds = duration.get('value', 0) - return max(1, int(seconds / 60)) - except Exception: - _logger.warning('Failed to calculate travel time', exc_info=True) - return 0 - - @api.depends('status') - def _compute_color(self): - color_map = { - 'scheduled': 0, # grey - 'en_route': 4, # blue - 'in_progress': 2, # orange - 'completed': 10, # green - 'cancelled': 1, # red - 'rescheduled': 3, # yellow - } - for task in self: - task.color = color_map.get(task.status, 0) - - @api.depends('address_street', 'address_street2', 'address_city', - 'address_state_id', 'address_zip') - def _compute_address_display(self): - for task in self: - street = task.address_street or '' - # If the street field already contains a full address (has a comma), - # use it directly -- Google Places stores the formatted address here. - if ',' in street and ( - (task.address_city and task.address_city in street) or - (task.address_zip and task.address_zip in street) - ): - # Street already has full address; just append unit if separate - if task.address_street2 and task.address_street2 not in street: - task.address_display = f"{street}, {task.address_street2}" - else: - task.address_display = street - else: - # Build from components (manual entry or legacy data) - parts = [ - street, - task.address_street2, - task.address_city, - task.address_state_id.name if task.address_state_id else '', - task.address_zip, - ] - task.address_display = ', '.join([p for p in parts if p]) - - # ------------------------------------------------------------------ - # ONCHANGE - Auto-fill address from client - # ------------------------------------------------------------------ - - @api.onchange('partner_id') - def _onchange_partner_id(self): - """Auto-fill address fields from the selected client's address.""" - if self.partner_id: - addr = self.partner_id - self.address_partner_id = addr.id - self.address_street = addr.street or '' - self.address_street2 = addr.street2 or '' - self.address_city = addr.city or '' - self.address_state_id = addr.state_id.id if addr.state_id else False - self.address_zip = addr.zip or '' - self.address_lat = addr.x_fc_latitude if hasattr(addr, 'x_fc_latitude') and addr.x_fc_latitude else 0 - self.address_lng = addr.x_fc_longitude if hasattr(addr, 'x_fc_longitude') and addr.x_fc_longitude else 0 - - @api.onchange('sale_order_id') - def _onchange_sale_order_id(self): - """Auto-fill client and address from the sale order's shipping address.""" - if self.sale_order_id: - order = self.sale_order_id - if not self.partner_id: - self.partner_id = order.partner_id - # Use shipping address if different - addr = order.partner_shipping_id or order.partner_id - self.address_partner_id = addr.id - self.address_street = addr.street or '' - self.address_street2 = addr.street2 or '' - self.address_city = addr.city or '' - self.address_state_id = addr.state_id.id if addr.state_id else False - self.address_zip = addr.zip or '' - self.address_lat = addr.x_fc_latitude if hasattr(addr, 'x_fc_latitude') and addr.x_fc_latitude else 0 - self.address_lng = addr.x_fc_longitude if hasattr(addr, 'x_fc_longitude') and addr.x_fc_longitude else 0 - - # ------------------------------------------------------------------ - # CONSTRAINTS + VALIDATION - # ------------------------------------------------------------------ - - @api.constrains('technician_id', 'scheduled_date', 'time_start', 'time_end') - def _check_no_overlap(self): - """Prevent overlapping bookings for the same technician on the same date.""" - for task in self: - if task.status == 'cancelled': - continue - if task.x_fc_sync_source: - continue - # Validate time range - if task.time_start >= task.time_end: - raise ValidationError(_("Start time must be before end time.")) - # Validate store hours - s_open, s_close = self._get_store_hours() - if task.time_start < s_open or task.time_end > s_close: - open_str = self._float_to_time_str(s_open) - close_str = self._float_to_time_str(s_close) - raise ValidationError(_( - "Tasks must be scheduled within store hours (%s - %s)." - ) % (open_str, close_str)) - # Validate not in the past (only for new/scheduled local tasks) - if task.status == 'scheduled' and task.scheduled_date and not task.x_fc_sync_source: - today = fields.Date.context_today(self) - if task.scheduled_date < today: - raise ValidationError(_("Cannot schedule tasks in the past.")) - if task.scheduled_date == today: - now = fields.Datetime.now() - current_hour = now.hour + now.minute / 60.0 - if task.time_start < current_hour: - pass # Allow editing existing tasks that started earlier today - # Check overlap with other tasks - overlapping = self.sudo().search([ - ('technician_id', '=', task.technician_id.id), - ('scheduled_date', '=', task.scheduled_date), - ('status', 'not in', ['cancelled']), - ('id', '!=', task.id), - ('time_start', '<', task.time_end), - ('time_end', '>', task.time_start), - ], limit=1) - if overlapping: - start_str = self._float_to_time_str(overlapping.time_start) - end_str = self._float_to_time_str(overlapping.time_end) - raise ValidationError(_( - "Time slot overlaps with %(task)s (%(start)s - %(end)s). " - "Please choose a different time.", - task=overlapping.name, - start=start_str, - end=end_str, - )) - - # Check travel time gap to the NEXT task on the same day - next_task = self.sudo().search([ - ('technician_id', '=', task.technician_id.id), - ('scheduled_date', '=', task.scheduled_date), - ('status', 'not in', ['cancelled']), - ('id', '!=', task.id), - ('time_start', '>=', task.time_end), - ], order='time_start', limit=1) - if next_task and task.address_lat and task.address_lng and \ - next_task.address_lat and next_task.address_lng: - travel_min = self._quick_travel_time( - task.address_lat, task.address_lng, - next_task.address_lat, next_task.address_lng, - ) - if travel_min > 0: - gap_min = int((next_task.time_start - task.time_end) * 60) - if gap_min < travel_min: - raise ValidationError(_( - "Not enough travel time to the next task!\n\n" - "This task ends at %(end)s, and %(next)s starts " - "at %(next_start)s (%(gap)d min gap).\n" - "Travel time is ~%(travel)d minutes.\n\n" - "Please allow at least %(travel)d minutes between tasks.", - end=self._float_to_time_str(task.time_end), - next=next_task.name, - next_start=self._float_to_time_str(next_task.time_start), - gap=gap_min, - travel=travel_min, - )) - - # Check travel time gap FROM the PREVIOUS task on the same day - prev_task = self.sudo().search([ - ('technician_id', '=', task.technician_id.id), - ('scheduled_date', '=', task.scheduled_date), - ('status', 'not in', ['cancelled']), - ('id', '!=', task.id), - ('time_end', '<=', task.time_start), - ], order='time_end desc', limit=1) - if prev_task and task.address_lat and task.address_lng and \ - prev_task.address_lat and prev_task.address_lng: - travel_min = self._quick_travel_time( - prev_task.address_lat, prev_task.address_lng, - task.address_lat, task.address_lng, - ) - if travel_min > 0: - gap_min = int((task.time_start - prev_task.time_end) * 60) - if gap_min < travel_min: - raise ValidationError(_( - "Not enough travel time from the previous task!\n\n" - "%(prev)s ends at %(prev_end)s, and this task starts " - "at %(start)s (%(gap)d min gap).\n" - "Travel time is ~%(travel)d minutes.\n\n" - "Please allow at least %(travel)d minutes between tasks.", - prev=prev_task.name, - prev_end=self._float_to_time_str(prev_task.time_end), - start=self._float_to_time_str(task.time_start), - gap=gap_min, - travel=travel_min, - )) - - @api.onchange('technician_id', 'scheduled_date') - def _onchange_technician_date_autoset(self): - """Auto-set start/end time to the first available slot when tech+date change.""" - if not self.technician_id or not self.scheduled_date: - return - exclude_id = self._origin.id if self._origin else False - duration = self.duration_hours or 1.0 - s_open, _s_close = self._get_store_hours() - preferred = self.time_start or s_open - start, end = self._find_next_available_slot( - self.technician_id.id, - self.scheduled_date, - preferred_start=preferred, - duration=duration, - exclude_task_id=exclude_id, - dest_lat=self.address_lat or 0, - dest_lng=self.address_lng or 0, - ) - if start is not False: - self.time_start = start - self.time_end = end - self.duration_hours = end - start - else: - return {'warning': { - 'title': _('Fully Booked'), - 'message': _( - '%s is fully booked on %s. No available slots.' - ) % (self.technician_id.name, - self.scheduled_date.strftime('%B %d, %Y')), - }} - - def _snap_if_overlap(self): - """Check if current time_start/time_end overlaps with another task. - If so, auto-snap to the next available slot and return a warning dict.""" - if not self.technician_id or not self.scheduled_date or not self.time_start: - return None - exclude_id = self._origin.id if self._origin else 0 - duration = max(self.duration_hours or 1.0, 0.25) - - overlapping = self.sudo().search([ - ('technician_id', '=', self.technician_id.id), - ('scheduled_date', '=', self.scheduled_date), - ('status', 'not in', ['cancelled']), - ('id', '!=', exclude_id), - ('time_start', '<', self.time_end), - ('time_end', '>', self.time_start), - ], limit=1) - if overlapping: - conflict_name = overlapping.name - conflict_start = self._float_to_time_str(overlapping.time_start) - conflict_end = self._float_to_time_str(overlapping.time_end) - start, end = self._find_next_available_slot( - self.technician_id.id, - self.scheduled_date, - preferred_start=self.time_start, - duration=duration, - exclude_task_id=exclude_id, - dest_lat=self.address_lat or 0, - dest_lng=self.address_lng or 0, - ) - if start is not False: - new_start_str = self._float_to_time_str(start) - new_end_str = self._float_to_time_str(end) - self.time_start = start - self.time_end = end - self.duration_hours = end - start - return {'warning': { - 'title': _('Moved to Available Slot'), - 'message': _( - 'The selected time conflicts with %s (%s - %s).\n' - 'Automatically moved to: %s - %s.' - ) % (conflict_name, conflict_start, conflict_end, - new_start_str, new_end_str), - }} - else: - return {'warning': { - 'title': _('No Available Slots'), - 'message': _( - 'The selected time conflicts with %s (%s - %s) ' - 'and no other slots are available on this day.' - ) % (conflict_name, conflict_start, conflict_end), - }} - return None - - # ------------------------------------------------------------------ - # DEFAULT_GET - Calendar pre-fill - # ------------------------------------------------------------------ - - def _snap_to_quarter(self, hour_float): - """Round a float hour to the nearest 15-minute slot and clamp to store hours.""" - s_open, s_close = self._get_store_hours() - snapped = round(hour_float * 4) / 4 - return max(s_open, min(s_close, snapped)) - - @api.model - def default_get(self, fields_list): - """Handle calendar time range selection: pre-fill date + times from context.""" - res = super().default_get(fields_list) - ctx = self.env.context - - # Set duration default based on task type from context - task_type = ctx.get('default_task_type', res.get('task_type', 'delivery')) - if 'duration_hours' not in res or not res.get('duration_hours'): - res['duration_hours'] = self.TASK_TYPE_DURATIONS.get(task_type, 1.0) - - # When user clicks a time range on the calendar, Odoo passes - # default_datetime_start/end in UTC - dt_start_utc = None - dt_end_utc = None - if ctx.get('default_datetime_start'): - try: - dt_start_utc = fields.Datetime.from_string(ctx['default_datetime_start']) - except (ValueError, TypeError): - pass - if ctx.get('default_datetime_end'): - try: - dt_end_utc = fields.Datetime.from_string(ctx['default_datetime_end']) - except (ValueError, TypeError): - pass - - if dt_start_utc or dt_end_utc: - import pytz - user_tz = pytz.timezone(self.env.user.tz or 'UTC') - - if dt_start_utc: - dt_start_local = pytz.utc.localize(dt_start_utc).astimezone(user_tz) - res['scheduled_date'] = dt_start_local.date() - start_float = self._snap_to_quarter( - dt_start_local.hour + dt_start_local.minute / 60.0) - res['time_start'] = start_float - - if dt_end_utc: - dt_end_local = pytz.utc.localize(dt_end_utc).astimezone(user_tz) - end_float = self._snap_to_quarter( - dt_end_local.hour + dt_end_local.minute / 60.0) - if 'time_start' in res and end_float <= res['time_start']: - end_float = res['time_start'] + 1.0 - res['time_end'] = end_float - # Compute duration from the calendar drag - if 'time_start' in res: - res['duration_hours'] = end_float - res['time_start'] - - # Always compute end from start + duration if not already set - if 'time_end' not in res and 'time_start' in res and 'duration_hours' in res: - _open, close = self._get_store_hours() - res['time_end'] = min( - res['time_start'] + res['duration_hours'], close) - - return res - - # ------------------------------------------------------------------ - # CRUD OVERRIDES - # ------------------------------------------------------------------ - - @api.model_create_multi - def create(self, vals_list): - for vals in vals_list: - if vals.get('name', _('New')) == _('New'): - vals['name'] = self.env['ir.sequence'].next_by_code('fusion.technician.task') or _('New') - if not vals.get('x_fc_sync_uuid') and not vals.get('x_fc_sync_source'): - vals['x_fc_sync_uuid'] = str(uuid.uuid4()) - # Auto-populate address from sale order if not provided - if vals.get('sale_order_id') and not vals.get('address_street'): - order = self.env['sale.order'].browse(vals['sale_order_id']) - addr = order.partner_shipping_id or order.partner_id - if addr: - self._fill_address_vals(vals, addr) - if not vals.get('partner_id'): - vals['partner_id'] = order.partner_id.id - # Auto-populate address from partner if sale order not set - elif vals.get('partner_id') and not vals.get('address_street'): - partner = self.env['res.partner'].browse(vals['partner_id']) - if partner.street: - self._fill_address_vals(vals, partner) - records = super().create(vals_list) - # Post creation notice to linked sale order chatter - for rec in records: - rec._post_task_created_to_sale_order() - # If created from "Ready for Delivery" flow, mark the sale order - if self.env.context.get('mark_ready_for_delivery'): - records._mark_sale_order_ready_for_delivery() - if self.env.context.get('mark_odsp_ready_for_delivery'): - for rec in records: - order = rec.sale_order_id - if order and order.x_fc_is_odsp_sale and order._get_odsp_status() != 'ready_delivery': - order._odsp_advance_status('ready_delivery', - "Order is ready for delivery. Delivery task scheduled.") - # Auto-calculate travel times for the full day chain - if not self.env.context.get('skip_travel_recalc'): - records._recalculate_day_travel_chains() - # Send "Appointment Scheduled" email - for rec in records: - rec._send_task_scheduled_email() - # Push new local tasks to remote instances - local_records = records.filtered(lambda r: not r.x_fc_sync_source) - if local_records and not self.env.context.get('skip_task_sync'): - self.env['fusion.task.sync.config']._push_tasks(local_records, 'create') - return records - - def write(self, vals): - if self.env.context.get('skip_travel_recalc'): - return super().write(vals) - - # Safety: ensure time_end is consistent when start/duration change - # but time_end wasn't sent (readonly field in view may not save) - if ('time_start' in vals or 'duration_hours' in vals) and 'time_end' not in vals: - _open, close = self._get_store_hours() - start = vals.get('time_start', self[:1].time_start if len(self) == 1 else 9.0) - dur = vals.get('duration_hours', self[:1].duration_hours if len(self) == 1 else 1.0) or 1.0 - vals['time_end'] = min(start + dur, close) - - # Detect reschedule mode: capture old values BEFORE write - reschedule_mode = self.env.context.get('reschedule_mode') - old_schedule = {} - schedule_fields = {'scheduled_date', 'time_start', 'time_end', - 'duration_hours', 'technician_id'} - schedule_changed = schedule_fields & set(vals.keys()) - if reschedule_mode and schedule_changed: - for task in self: - old_schedule[task.id] = { - 'date': task.scheduled_date, - 'time_start': task.time_start, - 'time_end': task.time_end, - } - - # Capture old tech+date combos BEFORE write for travel recalc - travel_fields = {'address_street', 'address_city', 'address_zip', 'address_lat', 'address_lng', - 'scheduled_date', 'sequence', 'time_start', 'technician_id'} - needs_travel_recalc = travel_fields & set(vals.keys()) - old_combos = set() - if needs_travel_recalc: - old_combos = {(t.technician_id.id, t.scheduled_date) for t in self} - res = super().write(vals) - if needs_travel_recalc: - new_combos = {(t.technician_id.id, t.scheduled_date) for t in self} - all_combos = old_combos | new_combos - self._recalculate_combos_travel(all_combos) - - # After write: send reschedule email if schedule actually changed - if reschedule_mode and old_schedule: - for task in self: - old = old_schedule.get(task.id, {}) - if old and ( - old['date'] != task.scheduled_date - or abs(old['time_start'] - task.time_start) > 0.01 - or abs(old['time_end'] - task.time_end) > 0.01 - ): - task._post_status_message('rescheduled') - task._send_task_rescheduled_email( - old_date=old['date'], - old_start=old['time_start'], - old_end=old['time_end'], - ) - # Push updates to remote instances for local tasks - sync_fields = {'technician_id', 'scheduled_date', 'time_start', 'time_end', - 'duration_hours', 'status', 'task_type', 'address_street', - 'address_city', 'address_zip', 'address_lat', 'address_lng', - 'partner_id'} - if sync_fields & set(vals.keys()) and not self.env.context.get('skip_task_sync'): - local_records = self.filtered(lambda r: not r.x_fc_sync_source) - if local_records: - self.env['fusion.task.sync.config']._push_tasks(local_records, 'write') - return res - - @api.model - def _fill_address_vals(self, vals, partner): - """Helper to fill address vals dict from a partner record.""" - vals.update({ - 'address_partner_id': partner.id, - 'address_street': partner.street or '', - 'address_street2': partner.street2 or '', - 'address_city': partner.city or '', - 'address_state_id': partner.state_id.id if partner.state_id else False, - 'address_zip': partner.zip or '', - 'address_lat': partner.x_fc_latitude if hasattr(partner, 'x_fc_latitude') else 0, - 'address_lng': partner.x_fc_longitude if hasattr(partner, 'x_fc_longitude') else 0, - }) - - def _post_task_created_to_sale_order(self): - """Post a brief task creation notice to the linked sale order's chatter.""" - self.ensure_one() - if not self.sale_order_id: - return - task_type_label = dict(self._fields['task_type'].selection).get(self.task_type, self.task_type) - date_str = self.scheduled_date.strftime('%B %d, %Y') if self.scheduled_date else 'TBD' - time_str = self._float_to_time_str(self.time_start) - task_url = f'/web#id={self.id}&model=fusion.technician.task&view_type=form' - body = Markup( - f'
      ' - f' Technician Task Scheduled
      ' - f'{self.name} ({task_type_label}) - {date_str} at {time_str}
      ' - f'Technician: {self.technician_id.name}
      ' - f'View Task' - f'
      ' - ) - self.sale_order_id.message_post( - body=body, message_type='notification', subtype_xmlid='mail.mt_note', - ) - - def _mark_sale_order_ready_for_delivery(self): - """Mark linked sale orders as Ready for Delivery. - - Called when a delivery task is created from the "Ready for Delivery" - button on the sale order. This replaces the old wizard workflow. - """ - for task in self: - order = task.sale_order_id - if not order: - continue - # Only update if not already marked - if order.x_fc_adp_application_status == 'ready_delivery': - continue - - user_name = self.env.user.name - tech_name = task.technician_id.name or '' - - # Save current status so we can revert if task is cancelled - previous_status = order.x_fc_adp_application_status - - # Update the sale order status and delivery fields - order.with_context(skip_status_validation=True).write({ - 'x_fc_adp_application_status': 'ready_delivery', - 'x_fc_status_before_delivery': previous_status, - 'x_fc_delivery_technician_ids': [(4, task.technician_id.id)], - 'x_fc_ready_for_delivery_date': fields.Datetime.now(), - 'x_fc_scheduled_delivery_datetime': task.datetime_start, - }) - - # Post chatter message - early_badge = '' - if order.x_fc_early_delivery: - early_badge = ' Early Delivery' - - scheduled_str = '' - if task.scheduled_date: - time_str = task._float_to_time_str(task.time_start) if task.time_start else '' - date_str = task.scheduled_date.strftime('%B %d, %Y') - scheduled_str = f'
    7. Scheduled: {date_str} at {time_str}
    8. ' - - notes_str = '' - if task.description: - notes_str = f'

      Delivery Notes: {task.description}

      ' - - chatter_body = Markup( - f'' - ) - order.message_post( - body=chatter_body, - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - - # Send email notifications - try: - order._send_ready_for_delivery_email( - technicians=task.technician_id, - scheduled_datetime=task.datetime_start, - notes=task.description, - ) - except Exception as e: - _logger.warning("Ready for delivery email failed for %s: %s", order.name, e) - - def _recalculate_day_travel_chains(self): - """Recalculate travel for all tech+date combos affected by these tasks.""" - combos = {(t.technician_id.id, t.scheduled_date) for t in self if t.technician_id and t.scheduled_date} - self._recalculate_combos_travel(combos) - - def _get_technician_start_address(self, tech_id): - """Get the start address for a technician. - - Priority: - 1. Technician's personal x_fc_start_address (if set) - 2. Company default HQ address (fusion_claims.technician_start_address) - Returns the address string or ''. - """ - tech_user = self.env['res.users'].sudo().browse(tech_id) - if tech_user.exists() and tech_user.x_fc_start_address: - return tech_user.x_fc_start_address.strip() - # Fallback to company default - return (self.env['ir.config_parameter'].sudo() - .get_param('fusion_claims.technician_start_address', '') or '').strip() - - def _geocode_address_string(self, address, api_key): - """Geocode an address string and return (lat, lng) or (0.0, 0.0).""" - if not address or not api_key: - return 0.0, 0.0 - try: - url = 'https://maps.googleapis.com/maps/api/geocode/json' - params = {'address': address, 'key': api_key, 'region': 'ca'} - resp = requests.get(url, params=params, timeout=10) - data = resp.json() - if data.get('status') == 'OK' and data.get('results'): - loc = data['results'][0]['geometry']['location'] - return loc['lat'], loc['lng'] - except Exception as e: - _logger.warning("Address geocoding failed for '%s': %s", address, e) - return 0.0, 0.0 - - def _recalculate_combos_travel(self, combos): - """Recalculate travel for a set of (tech_id, date) combinations.""" - ICP = self.env['ir.config_parameter'].sudo() - enabled = ICP.get_param('fusion_claims.google_distance_matrix_enabled', False) - if not enabled: - return - api_key = self._get_google_maps_api_key() - - # Cache geocoded start addresses per technician to avoid repeated API calls - start_coords_cache = {} - - for tech_id, date in combos: - if not tech_id or not date: - continue - all_day_tasks = self.sudo().search([ - ('technician_id', '=', tech_id), - ('scheduled_date', '=', date), - ('status', 'not in', ['cancelled']), - ], order='time_start, sequence, id') - if not all_day_tasks: - continue - - # Get this technician's start location (personal or company default) - if tech_id not in start_coords_cache: - addr = self._get_technician_start_address(tech_id) - start_coords_cache[tech_id] = self._geocode_address_string(addr, api_key) - - prev_lat, prev_lng = start_coords_cache[tech_id] - for i, task in enumerate(all_day_tasks): - if not (task.address_lat and task.address_lng): - task._geocode_address() - travel_vals = {} - if prev_lat and prev_lng and task.address_lat and task.address_lng: - task.with_context(skip_travel_recalc=True)._calculate_travel_time(prev_lat, prev_lng) - travel_vals['previous_task_id'] = all_day_tasks[i - 1].id if i > 0 else False - travel_vals['travel_origin'] = 'Start Location' if i == 0 else f'Task {all_day_tasks[i - 1].name}' - if travel_vals: - task.with_context(skip_travel_recalc=True).write(travel_vals) - prev_lat = task.address_lat or prev_lat - prev_lng = task.address_lng or prev_lng - - # ------------------------------------------------------------------ - # STATUS ACTIONS - # ------------------------------------------------------------------ - - def _check_previous_tasks_completed(self): - """Check that all earlier tasks for the same technician+date are completed.""" - self.ensure_one() - earlier_incomplete = self.sudo().search([ - ('technician_id', '=', self.technician_id.id), - ('scheduled_date', '=', self.scheduled_date), - ('time_start', '<', self.time_start), - ('status', 'not in', ['completed', 'cancelled']), - ('id', '!=', self.id), - ], limit=1) - if earlier_incomplete: - raise UserError(_( - "Please complete previous task %s first before starting this one." - ) % earlier_incomplete.name) - - def action_start_en_route(self): - """Mark task as En Route.""" - for task in self: - if task.status != 'scheduled': - raise UserError(_("Only scheduled tasks can be marked as En Route.")) - task._check_previous_tasks_completed() - task.status = 'en_route' - task._post_status_message('en_route') - - def action_start_task(self): - """Mark task as In Progress.""" - for task in self: - if task.status not in ('scheduled', 'en_route'): - raise UserError(_("Task must be scheduled or en route to start.")) - task._check_previous_tasks_completed() - task.status = 'in_progress' - task._post_status_message('in_progress') - - def action_view_sale_order(self): - """Open the linked sale order / case.""" - self.ensure_one() - if not self.sale_order_id: - return - return { - 'name': self.sale_order_id.name, - 'type': 'ir.actions.act_window', - 'res_model': 'sale.order', - 'view_mode': 'form', - 'res_id': self.sale_order_id.id, - } - - def action_complete_task(self): - """Mark task as Completed.""" - for task in self: - if task.status not in ('in_progress', 'en_route', 'scheduled'): - raise UserError(_("Task must be in progress to complete.")) - task.with_context(skip_travel_recalc=True).write({ - 'status': 'completed', - 'completion_datetime': fields.Datetime.now(), - }) - task._post_status_message('completed') - # Post completion notes to sale order chatter if linked - if task.sale_order_id and task.completion_notes: - task._post_completion_to_sale_order() - # Notify the person who scheduled the task - task._notify_scheduler_on_completion() - # Auto-advance ODSP status for delivery tasks - if (task.task_type == 'delivery' - and task.sale_order_id - and task.sale_order_id.x_fc_is_odsp_sale - and task.sale_order_id._get_odsp_status() == 'ready_delivery'): - task.sale_order_id._odsp_advance_status( - 'delivered', - "Delivery task completed by technician. Order marked as delivered.", - ) - - def action_cancel_task(self): - """Cancel the task. Sends cancellation email and reverts sale order if delivery.""" - for task in self: - if task.status == 'completed': - raise UserError(_("Cannot cancel a completed task.")) - task.status = 'cancelled' - task._post_status_message('cancelled') - # If this was a delivery task linked to a sale order that is - # currently in "Ready for Delivery" -- revert the order back. - # _revert_sale_order_on_cancel also sends the cancellation email - # for delivery tasks. - if task.task_type == 'delivery': - task._revert_sale_order_on_cancel() - else: - # Non-delivery tasks: still send a cancellation email - task._send_task_cancelled_email() - - def _revert_sale_order_on_cancel(self): - """When a delivery task is cancelled, check if the linked sale order - should revert to its previous status. Only reverts if: - - Task is a delivery type - - Sale order is currently 'ready_delivery' - - No other active (non-cancelled) delivery tasks exist for this order - """ - self.ensure_one() - if self.task_type != 'delivery' or not self.sale_order_id: - return - order = self.sale_order_id - if order.x_fc_adp_application_status != 'ready_delivery': - return - - # Check if any other non-cancelled delivery tasks exist for this order - other_delivery_tasks = self.sudo().search([ - ('sale_order_id', '=', order.id), - ('task_type', '=', 'delivery'), - ('status', 'not in', ['cancelled']), - ('id', '!=', self.id), - ], limit=1) - if other_delivery_tasks: - return # Other active delivery tasks still exist, don't revert - - # Revert to the status saved before Ready for Delivery - prev_status = order.x_fc_status_before_delivery or 'approved' - status_labels = dict(order._fields['x_fc_adp_application_status'].selection) - prev_label = status_labels.get(prev_status, prev_status) - - # skip_status_emails prevents the "Approved" email from re-firing - order.with_context( - skip_status_validation=True, - skip_status_emails=True, - ).write({ - 'x_fc_adp_application_status': prev_status, - 'x_fc_status_before_delivery': False, - }) - - # Post chatter message about the revert - body = Markup( - f'' - ) - order.message_post( - body=body, - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - - # Send a "Delivery Cancelled" email instead - self._send_task_cancelled_email() - - def action_reschedule(self): - """Open the reschedule form for this task. - Saves old schedule info, then opens the same task form for editing. - On save, the write() method detects the reschedule and sends emails.""" - self.ensure_one() - return { - 'type': 'ir.actions.act_window', - 'res_model': 'fusion.technician.task', - 'res_id': self.id, - 'view_mode': 'form', - 'target': 'new', - 'context': { - 'reschedule_mode': True, - 'old_date': str(self.scheduled_date) if self.scheduled_date else '', - 'old_time_start': self.time_start, - 'old_time_end': self.time_end, - }, - } - - def action_reset_to_scheduled(self): - """Reset task back to scheduled.""" - for task in self: - task.status = 'scheduled' - - # ------------------------------------------------------------------ - # CHATTER / NOTIFICATIONS - # ------------------------------------------------------------------ - - def _post_status_message(self, new_status): - """Post a status change message to the task chatter.""" - self.ensure_one() - status_labels = dict(self._fields['status'].selection) - label = status_labels.get(new_status, new_status) - icons = { - 'en_route': 'fa-road', - 'in_progress': 'fa-wrench', - 'completed': 'fa-check-circle', - 'cancelled': 'fa-times-circle', - 'rescheduled': 'fa-calendar', - } - icon = icons.get(new_status, 'fa-info-circle') - body = Markup( - f'

      Task status changed to ' - f'{label} by {self.env.user.name}

      ' - ) - self.message_post(body=body, message_type='notification', subtype_xmlid='mail.mt_note') - - def _post_completion_to_sale_order(self): - """Post the completion notes to the linked sale order's chatter.""" - self.ensure_one() - if not self.sale_order_id or not self.completion_notes: - return - task_type_label = dict(self._fields['task_type'].selection).get(self.task_type, self.task_type) - body = Markup( - f'
      ' - f'
      Technician Task Completed
      ' - f'
        ' - f'
      • Task: {self.name} ({task_type_label})
      • ' - f'
      • Technician: {self.technician_id.name}
      • ' - f'
      • Completed: {self.completion_datetime.strftime("%B %d, %Y at %I:%M %p") if self.completion_datetime else "N/A"}
      • ' - f'
      ' - f'
      ' - f'{self.completion_notes}' - f'
      ' - ) - self.sale_order_id.message_post( - body=body, - message_type='notification', - subtype_xmlid='mail.mt_note', - ) - - def _notify_scheduler_on_completion(self): - """Send an Odoo notification to whoever created/scheduled the task.""" - self.ensure_one() - # Notify the task creator (scheduler) if they're not the technician - if self.create_uid and self.create_uid != self.technician_id: - task_type_label = dict(self._fields['task_type'].selection).get(self.task_type, self.task_type) - task_url = f'/web#id={self.id}&model=fusion.technician.task&view_type=form' - client_name = self.partner_id.name or 'N/A' - case_ref = self.sale_order_id.name if self.sale_order_id else '' - # Build address string - addr_parts = [p for p in [ - self.address_street, - self.address_street2, - self.address_city, - self.address_state_id.name if self.address_state_id else '', - self.address_zip, - ] if p] - address_str = ', '.join(addr_parts) or 'No address' - # Build subject - subject = f'Task Completed: {client_name}' - if case_ref: - subject += f' ({case_ref})' - body = Markup( - f'
      ' - f'

      ' - f'{task_type_label} Completed

      ' - f'' - f'' - f'' - f'' - f'' - f'' - f'' - f'' - f'' - f'' - f'' - f'
      Client:{client_name}
      Case:{case_ref or "N/A"}
      Task:{self.name}
      Technician:{self.technician_id.name}
      Location:{address_str}
      ' - f'

      View Task

      ' - f'
      ' - ) - # Use Odoo's internal notification system - self.env['mail.thread'].sudo().message_notify( - partner_ids=[self.create_uid.partner_id.id], - body=body, - subject=subject, - ) - - # ------------------------------------------------------------------ - # TASK EMAIL NOTIFICATIONS - # ------------------------------------------------------------------ - - def _get_task_email_details(self): - """Build common detail rows for task emails.""" - self.ensure_one() - type_label = dict(self._fields['task_type'].selection).get( - self.task_type, self.task_type or '') - rows = [ - ('Task', f'{self.name} ({type_label})'), - ('Client', self.partner_id.name or 'N/A'), - ] - if self.sale_order_id: - rows.append(('Case', self.sale_order_id.name)) - if self.scheduled_date: - date_str = self.scheduled_date.strftime('%B %d, %Y') - start_str = self._float_to_time_str(self.time_start) - end_str = self._float_to_time_str(self.time_end) - rows.append(('Scheduled', f'{date_str}, {start_str} - {end_str}')) - if self.technician_id: - rows.append(('Technician', self.technician_id.name)) - if self.address_display: - rows.append(('Address', self.address_display)) - return rows - - def _get_task_email_recipients(self): - """Get email recipients for task notifications. - Returns dict with 'to' (client), 'cc' (technician, sales rep, office).""" - self.ensure_one() - to_emails = [] - cc_emails = [] - - # Client email - if self.partner_id and self.partner_id.email: - to_emails.append(self.partner_id.email) - - # Technician email - if self.technician_id and self.technician_id.email: - cc_emails.append(self.technician_id.email) - - # Sales rep from the sale order - if self.sale_order_id and self.sale_order_id.user_id and \ - self.sale_order_id.user_id.email: - cc_emails.append(self.sale_order_id.user_id.email) - - # Office notification recipients - if self.sale_order_id: - try: - office_cc = self.sale_order_id._get_email_recipients( - include_client=False).get('office_cc', []) - cc_emails.extend(office_cc) - except Exception: - pass - - return {'to': to_emails, 'cc': list(set(cc_emails))} - - def _send_task_cancelled_email(self): - """Send cancellation email for a task/delivery/appointment.""" - self.ensure_one() - order = self.sale_order_id - if not order: - return False - try: - if not order._is_email_notifications_enabled(): - return False - except Exception: - return False - - recipients = self._get_task_email_recipients() - to_emails = recipients.get('to', []) - cc_emails = recipients.get('cc', []) - if not to_emails and not cc_emails: - return False - - client_name = self.partner_id.name or 'Client' - type_label = dict(self._fields['task_type'].selection).get( - self.task_type, self.task_type or 'Task') - sender_name = self.env.user.name - - detail_rows = self._get_task_email_details() - detail_rows.append(('Cancelled By', sender_name)) - - body_html = order._email_build( - title=f'{type_label.title()} Cancelled', - summary=( - f'The scheduled {type_label.lower()} for ' - f'{client_name} has been cancelled.' - ), - email_type='urgent', - sections=[('Cancellation Details', detail_rows)], - note=( - 'What happens next: If you need to reschedule, ' - 'please contact our office and we will arrange a new appointment.' - ), - note_color='#e53e3e', - button_url=f'{order.get_base_url()}/web#id={order.id}&model=sale.order&view_type=form', - sender_name=sender_name, - ) - - email_to = ', '.join(to_emails) if to_emails else ', '.join(cc_emails[:1]) - email_cc = ', '.join(cc_emails) if to_emails else ', '.join(cc_emails[1:]) - try: - self.env['mail.mail'].sudo().create({ - 'subject': f'{type_label.title()} Cancelled - {client_name} - {order.name}', - 'body_html': body_html, - 'email_to': email_to, - 'email_cc': email_cc, - 'model': 'sale.order', - 'res_id': order.id, - }).send() - order._email_chatter_log( - f'{type_label.title()} Cancelled email sent', email_to, email_cc) - return True - except Exception as e: - _logger.error("Failed to send task cancelled email for %s: %s", self.name, e) - return False - - def _send_task_scheduled_email(self): - """Send appointment scheduled email to client, technician, and sales rep.""" - self.ensure_one() - order = self.sale_order_id - if not order: - return False - try: - if not order._is_email_notifications_enabled(): - return False - except Exception: - return False - - recipients = self._get_task_email_recipients() - to_emails = recipients.get('to', []) - cc_emails = recipients.get('cc', []) - if not to_emails and not cc_emails: - return False - - client_name = self.partner_id.name or 'Client' - type_label = dict(self._fields['task_type'].selection).get( - self.task_type, self.task_type or 'Task') - sender_name = self.env.user.name - - detail_rows = self._get_task_email_details() - if self.description: - detail_rows.append(('Notes', self.description)) - - body_html = order._email_build( - title=f'{type_label.title()} Scheduled', - summary=( - f'A {type_label.lower()} has been scheduled for ' - f'{client_name}.' - ), - email_type='success', - sections=[('Appointment Details', detail_rows)], - note=( - 'Please note: If you need to change this appointment, ' - 'please contact our office as soon as possible so we can accommodate ' - 'the change.' - ), - note_color='#38a169', - button_url=f'{order.get_base_url()}/web#id={order.id}&model=sale.order&view_type=form', - sender_name=sender_name, - ) - - email_to = ', '.join(to_emails) if to_emails else ', '.join(cc_emails[:1]) - email_cc = ', '.join(cc_emails) if to_emails else ', '.join(cc_emails[1:]) - try: - self.env['mail.mail'].sudo().create({ - 'subject': f'{type_label.title()} Scheduled - {client_name} - {order.name}', - 'body_html': body_html, - 'email_to': email_to, - 'email_cc': email_cc, - 'model': 'sale.order', - 'res_id': order.id, - }).send() - order._email_chatter_log( - f'{type_label.title()} Scheduled email sent', email_to, email_cc) - return True - except Exception as e: - _logger.error("Failed to send task scheduled email for %s: %s", self.name, e) - return False - - def _send_task_rescheduled_email(self, old_date=None, old_start=None, old_end=None): - """Send reschedule email to client, technician, and sales rep. - Shows old vs new schedule for clarity.""" - self.ensure_one() - order = self.sale_order_id - if not order: - return False - try: - if not order._is_email_notifications_enabled(): - return False - except Exception: - return False - - recipients = self._get_task_email_recipients() - to_emails = recipients.get('to', []) - cc_emails = recipients.get('cc', []) - if not to_emails and not cc_emails: - return False - - client_name = self.partner_id.name or 'Client' - type_label = dict(self._fields['task_type'].selection).get( - self.task_type, self.task_type or 'Task') - sender_name = self.env.user.name - - detail_rows = self._get_task_email_details() - - # Show old schedule if provided - if old_date or old_start is not None: - old_parts = [] - if old_date: - old_parts.append(old_date.strftime('%B %d, %Y')) - if old_start is not None: - old_parts.append( - f'{self._float_to_time_str(old_start)} - ' - f'{self._float_to_time_str(old_end or old_start + 1.0)}') - detail_rows.insert(3, ('Previous Schedule', ', '.join(old_parts))) - - body_html = order._email_build( - title=f'{type_label.title()} Rescheduled', - summary=( - f'The {type_label.lower()} for ' - f'{client_name} has been rescheduled.' - ), - email_type='attention', - sections=[('Updated Appointment Details', detail_rows)], - note=( - 'Please note: The appointment has been updated ' - 'to the new date and time shown above. If you have any questions, ' - 'please contact our office.' - ), - note_color='#d69e2e', - button_url=f'{order.get_base_url()}/web#id={order.id}&model=sale.order&view_type=form', - sender_name=sender_name, - ) - - email_to = ', '.join(to_emails) if to_emails else ', '.join(cc_emails[:1]) - email_cc = ', '.join(cc_emails) if to_emails else ', '.join(cc_emails[1:]) - try: - self.env['mail.mail'].sudo().create({ - 'subject': f'{type_label.title()} Rescheduled - {client_name} - {order.name}', - 'body_html': body_html, - 'email_to': email_to, - 'email_cc': email_cc, - 'model': 'sale.order', - 'res_id': order.id, - }).send() - order._email_chatter_log( - f'{type_label.title()} Rescheduled email sent', email_to, email_cc) - return True - except Exception as e: - _logger.error("Failed to send rescheduled email for %s: %s", self.name, e) - return False - - def get_next_task_for_technician(self): - """Get the next task in sequence for the same technician+date after this one.""" - self.ensure_one() - return self.sudo().search([ - ('technician_id', '=', self.technician_id.id), - ('scheduled_date', '=', self.scheduled_date), - ('time_start', '>=', self.time_start), - ('status', 'in', ['scheduled', 'en_route']), - ('id', '!=', self.id), - ], order='time_start, sequence, id', limit=1) - - # ------------------------------------------------------------------ - # GOOGLE MAPS INTEGRATION - # ------------------------------------------------------------------ - - def _get_google_maps_api_key(self): - """Get the Google Maps API key from config.""" - return self.env['ir.config_parameter'].sudo().get_param( - 'fusion_claims.google_maps_api_key', '' - ) - - @api.model - def get_map_data(self, domain=None): - """Return task data, technician locations, and Google Maps API key. - - Args: - domain: optional extra domain from the search bar filters. - """ - api_key = self.env['ir.config_parameter'].sudo().get_param( - 'fusion_claims.google_maps_api_key', '') - local_instance = self.env['ir.config_parameter'].sudo().get_param( - 'fusion_claims.sync_instance_id', '') - base_domain = [ - ('status', 'not in', ['cancelled']), - ] - if domain: - base_domain = expression.AND([base_domain, domain]) - tasks = self.sudo().search_read( - base_domain, - ['name', 'partner_id', 'technician_id', 'task_type', - 'address_lat', 'address_lng', 'address_display', - 'time_start', 'time_start_display', 'time_end_display', - 'status', 'scheduled_date', 'travel_time_minutes', - 'x_fc_sync_client_name', 'x_fc_is_shadow', 'x_fc_sync_source'], - order='scheduled_date asc, time_start asc', - limit=500, - ) - locations = self.env['fusion.technician.location'].get_latest_locations() - return { - 'api_key': api_key, - 'tasks': tasks, - 'locations': locations, - 'local_instance_id': local_instance, - } - - def _geocode_address(self): - """Geocode the task address using Google Geocoding API.""" - self.ensure_one() - api_key = self._get_google_maps_api_key() - if not api_key or not self.address_display: - return False - - try: - url = 'https://maps.googleapis.com/maps/api/geocode/json' - params = { - 'address': self.address_display, - 'key': api_key, - 'region': 'ca', - } - resp = requests.get(url, params=params, timeout=10) - data = resp.json() - if data.get('status') == 'OK' and data.get('results'): - location = data['results'][0]['geometry']['location'] - self.write({ - 'address_lat': location['lat'], - 'address_lng': location['lng'], - }) - return True - except Exception as e: - _logger.warning(f"Geocoding failed for task {self.name}: {e}") - return False - - def _calculate_travel_time(self, origin_lat, origin_lng): - """Calculate travel time from origin to this task using Distance Matrix API.""" - self.ensure_one() - api_key = self._get_google_maps_api_key() - if not api_key: - return False - if not (origin_lat and origin_lng and self.address_lat and self.address_lng): - return False - - try: - url = 'https://maps.googleapis.com/maps/api/distancematrix/json' - params = { - 'origins': f'{origin_lat},{origin_lng}', - 'destinations': f'{self.address_lat},{self.address_lng}', - 'key': api_key, - 'mode': 'driving', - 'avoid': 'tolls', - 'traffic_model': 'best_guess', - 'departure_time': 'now', - } - resp = requests.get(url, params=params, timeout=10) - data = resp.json() - if data.get('status') == 'OK': - element = data['rows'][0]['elements'][0] - if element.get('status') == 'OK': - duration_seconds = element['duration_in_traffic']['value'] if 'duration_in_traffic' in element else element['duration']['value'] - distance_meters = element['distance']['value'] - self.write({ - 'travel_time_minutes': round(duration_seconds / 60), - 'travel_distance_km': round(distance_meters / 1000, 1), - }) - return True - except Exception as e: - _logger.warning(f"Travel time calculation failed for task {self.name}: {e}") - return False - - def action_calculate_travel_times(self): - """Calculate travel times for a day's schedule. Called from backend button or cron.""" - self._do_calculate_travel_times() - # Return False to stay on the current form without navigation - return False - - def _do_calculate_travel_times(self): - """Internal: calculate travel times for tasks. Does not return an action.""" - # Group tasks by technician and date - task_groups = {} - for task in self: - key = (task.technician_id.id, task.scheduled_date) - if key not in task_groups: - task_groups[key] = self.env['fusion.technician.task'] - task_groups[key] |= task - - api_key = self._get_google_maps_api_key() - start_coords_cache = {} - - for (tech_id, date), tasks in task_groups.items(): - sorted_tasks = tasks.sorted(lambda t: (t.sequence, t.time_start)) - - # Get this technician's start location (personal or company default) - if tech_id not in start_coords_cache: - addr = self._get_technician_start_address(tech_id) - start_coords_cache[tech_id] = self._geocode_address_string(addr, api_key) - - prev_lat, prev_lng = start_coords_cache[tech_id] - - for i, task in enumerate(sorted_tasks): - # Geocode task if needed - if not (task.address_lat and task.address_lng): - task._geocode_address() - - if prev_lat and prev_lng and task.address_lat and task.address_lng: - task._calculate_travel_time(prev_lat, prev_lng) - task.previous_task_id = sorted_tasks[i - 1].id if i > 0 else False - task.travel_origin = 'Start Location' if i == 0 else f'Task {sorted_tasks[i - 1].name}' - - prev_lat = task.address_lat - prev_lng = task.address_lng - - @api.model - def _cron_calculate_travel_times(self): - """Cron job: Calculate travel times for today and tomorrow.""" - today = fields.Date.context_today(self) - tomorrow = today + timedelta(days=1) - tasks = self.search([ - ('scheduled_date', 'in', [today, tomorrow]), - ('status', 'in', ['scheduled', 'en_route']), - ]) - if tasks: - tasks._do_calculate_travel_times() - _logger.info(f"Calculated travel times for {len(tasks)} tasks") - - # ------------------------------------------------------------------ - # PORTAL HELPERS - # ------------------------------------------------------------------ - - def get_technician_tasks_for_date(self, user_id, date): - """Get all tasks for a technician on a given date, ordered by sequence.""" - return self.sudo().search([ - ('technician_id', '=', user_id), - ('scheduled_date', '=', date), - ('status', '!=', 'cancelled'), - ], order='sequence, time_start, id') - - def get_next_task(self, user_id): - """Get the next upcoming task for a technician.""" - today = fields.Date.context_today(self) - return self.sudo().search([ - ('technician_id', '=', user_id), - ('scheduled_date', '>=', today), - ('status', 'in', ['scheduled', 'en_route']), - ], order='scheduled_date, sequence, time_start', limit=1) - - def get_current_task(self, user_id): - """Get the current in-progress task for a technician.""" - today = fields.Date.context_today(self) - return self.sudo().search([ - ('technician_id', '=', user_id), - ('scheduled_date', '=', today), - ('status', '=', 'in_progress'), - ], limit=1) - - # ------------------------------------------------------------------ - # PUSH NOTIFICATIONS - # ------------------------------------------------------------------ - - def _send_push_notification(self, title, body_text, url=None): - """Send a web push notification for this task.""" - self.ensure_one() - PushSub = self.env['fusion.push.subscription'].sudo() - subscriptions = PushSub.search([ - ('user_id', '=', self.technician_id.id), - ('active', '=', True), - ]) - if not subscriptions: - return - - ICP = self.env['ir.config_parameter'].sudo() - vapid_private = ICP.get_param('fusion_claims.vapid_private_key', '') - vapid_public = ICP.get_param('fusion_claims.vapid_public_key', '') - if not vapid_private or not vapid_public: - _logger.warning("VAPID keys not configured, cannot send push notification") - return - - try: - from pywebpush import webpush, WebPushException - except ImportError: - _logger.warning("pywebpush not installed, cannot send push notifications") - return - - payload = json.dumps({ - 'title': title, - 'body': body_text, - 'url': url or f'/my/technician/task/{self.id}', - 'task_id': self.id, - 'task_type': self.task_type, - }) - - for sub in subscriptions: - try: - webpush( - subscription_info={ - 'endpoint': sub.endpoint, - 'keys': { - 'p256dh': sub.p256dh_key, - 'auth': sub.auth_key, - }, - }, - data=payload, - vapid_private_key=vapid_private, - vapid_claims={'sub': 'mailto:support@nexasystems.ca'}, - ) - except Exception as e: - _logger.warning(f"Push notification failed for subscription {sub.id}: {e}") - # Deactivate invalid subscriptions - if 'gone' in str(e).lower() or '410' in str(e): - sub.active = False - - self.write({ - 'push_notified': True, - 'push_notified_datetime': fields.Datetime.now(), - }) - - @api.model - def _cron_send_push_notifications(self): - """Cron: Send push notifications for upcoming tasks.""" - ICP = self.env['ir.config_parameter'].sudo() - if not ICP.get_param('fusion_claims.push_enabled', False): - return - - advance_minutes = int(ICP.get_param('fusion_claims.push_advance_minutes', '30')) - now = fields.Datetime.now() - - # Find tasks starting within advance_minutes that haven't been notified - tasks = self.search([ - ('scheduled_date', '=', now.date()), - ('status', '=', 'scheduled'), - ('push_notified', '=', False), - ]) - - for task in tasks: - # Check if task is within the notification window - task_start_hour = int(task.time_start) - task_start_min = int((task.time_start % 1) * 60) - task_start_dt = now.replace(hour=task_start_hour, minute=task_start_min, second=0) - - minutes_until = (task_start_dt - now).total_seconds() / 60 - if 0 <= minutes_until <= advance_minutes: - task_type_label = dict(self._fields['task_type'].selection).get(task.task_type, task.task_type) - title = f'Upcoming: {task_type_label}' - body_text = f'{task.partner_id.name or "Task"} - {task.time_start_display}' - if task.travel_time_minutes: - body_text += f' ({task.travel_time_minutes} min drive)' - task._send_push_notification(title, body_text) - - # ------------------------------------------------------------------ - # HELPERS - # ------------------------------------------------------------------ - - @staticmethod - def _float_to_time_str(value): - """Convert float hours to time string like '9:30 AM'.""" - if not value and value != 0: - return '' - hours = int(value) - minutes = int(round((value % 1) * 60)) - period = 'AM' if hours < 12 else 'PM' - display_hour = hours % 12 or 12 - return f'{display_hour}:{minutes:02d} {period}' - - def get_google_maps_url(self): - """Get Google Maps navigation URL. Uses lat/lng coordinates to - navigate to the exact location (text addresses cause Google to - resolve to nearby business names instead).""" - self.ensure_one() - if self.address_lat and self.address_lng: - return f'https://www.google.com/maps/dir/?api=1&destination={self.address_lat},{self.address_lng}&travelmode=driving' - elif self.address_display: - return f'https://www.google.com/maps/dir/?api=1&destination={urllib.parse.quote(self.address_display)}&travelmode=driving' - return '' diff --git a/fusion_claims/fusion_claims/models/xml_parser.py b/fusion_claims/fusion_claims/models/xml_parser.py deleted file mode 100644 index 9c3fc3c..0000000 --- a/fusion_claims/fusion_claims/models/xml_parser.py +++ /dev/null @@ -1,735 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024-2026 Nexa Systems Inc. -# License OPL-1 (Odoo Proprietary License v1.0) - -import base64 -import json -import logging -import xml.etree.ElementTree as ET -from collections import OrderedDict -from datetime import datetime - -from odoo import api, models - -_logger = logging.getLogger(__name__) - - -class FusionXmlParser(models.AbstractModel): - """Utility to parse ADP application XML files and create/update - client profiles and application data records. - - Captures ALL ~300 XML fields for round-trip export fidelity. - """ - _name = 'fusion.xml.parser' - _description = 'ADP XML Parser' - - # ------------------------------------------------------------------ - # PUBLIC API - # ------------------------------------------------------------------ - @api.model - def parse_from_binary(self, binary_data, sale_order=None): - """Parse from binary field (base64 encoded). - Returns tuple (profile, application_data) or (False, False). - """ - if not binary_data: - return False, False - try: - xml_content = base64.b64decode(binary_data).decode('utf-8') - except Exception as e: - _logger.warning('Failed to decode XML binary: %s', e) - return False, False - return self.parse_and_create(xml_content, sale_order) - - @api.model - def parse_and_create(self, xml_content, sale_order=None): - """Parse raw XML string, create/update profile and application data. - Returns tuple (profile, application_data) or (False, False). - """ - try: - root = ET.fromstring(xml_content) - except ET.ParseError as e: - _logger.warning('Failed to parse ADP XML: %s', e) - return False, False - - form = root.find('Form') - if form is None: - form = root - - # Step 1: Build complete JSON dict (every field, dot-notation keys) - json_dict = self._xml_to_json(form) - - # Step 2: Extract individual model fields from JSON - model_vals = self._json_to_model_vals(json_dict) - model_vals['raw_xml'] = xml_content - model_vals['xml_data_json'] = json.dumps(json_dict, ensure_ascii=False) - - # Step 3: Create/update profile - profile = self._find_or_create_profile(model_vals, sale_order) - - # Step 4: Create application data record - model_vals['profile_id'] = profile.id - model_vals['sale_order_id'] = sale_order.id if sale_order else False - app_data = self.env['fusion.adp.application.data'].create(model_vals) - - return profile, app_data - - @api.model - def reparse_existing(self, app_data_record): - """Re-parse an existing application data record from its raw_xml. - Updates all fields in place without creating a new record. - """ - if not app_data_record.raw_xml: - return False - try: - root = ET.fromstring(app_data_record.raw_xml) - except ET.ParseError as e: - _logger.warning('Failed to re-parse XML: %s', e) - return False - - form = root.find('Form') - if form is None: - form = root - - json_dict = self._xml_to_json(form) - model_vals = self._json_to_model_vals(json_dict) - model_vals['xml_data_json'] = json.dumps(json_dict, ensure_ascii=False) - - # Remove fields that shouldn't be overwritten - model_vals.pop('raw_xml', None) - model_vals.pop('profile_id', None) - model_vals.pop('sale_order_id', None) - - app_data_record.write(model_vals) - - # Also update the linked profile - if app_data_record.profile_id: - profile_vals = {} - if model_vals.get('medical_condition'): - profile_vals['medical_condition'] = model_vals['medical_condition'] - if model_vals.get('mobility_status'): - profile_vals['mobility_status'] = model_vals['mobility_status'] - if model_vals.get('applicant_first_name'): - profile_vals['first_name'] = model_vals['applicant_first_name'] - if model_vals.get('applicant_last_name'): - profile_vals['last_name'] = model_vals['applicant_last_name'] - assessment = model_vals.get('assessment_date') - if assessment: - profile_vals['last_assessment_date'] = assessment - if profile_vals: - app_data_record.profile_id.write(profile_vals) - - return True - - # ------------------------------------------------------------------ - # STEP 1: XML -> FLAT JSON DICT (every field preserved) - # ------------------------------------------------------------------ - def _xml_to_json(self, form): - """Convert the entire Form element to a flat JSON dict with dot-notation keys.""" - d = OrderedDict() - d['deviceCategory'] = self._t(form, 'deviceCategory') - d['VersionNumber'] = self._t(form, 'VersionNumber') - - # Section 1 - s1 = form.find('section1') - if s1 is not None: - for tag in ['applicantLastname', 'applicantFirstname', 'applicantMiddleinitial', - 'healthNo', 'versionNo', 'DateOfBirth', 'nameLTCH', - 'unitNo', 'streetNo', 'streetName', 'rrRoute', - 'city', 'province', 'postalCode', - 'homePhone', 'busPhone', 'phoneExtension']: - d[f'section1.{tag}'] = self._t(s1, tag) - cob = s1.find('confirmationOfBenefit') - if cob is not None: - for tag in ['q1Yn', 'q1Ifyes', 'q2Yn', 'q3Yn']: - d[f'section1.confirmationOfBenefit.{tag}'] = self._t(cob, tag) - - # Section 2 - s2 = form.find('section2') - if s2 is not None: - de = s2.find('devicesandEligibility') - if de is not None: - for tag in ['condition', 'status', 'none', 'forearm', 'wheeled', 'manual', - 'power', 'addOn', 'scooter', 'seating', 'tiltSystem', 'reclineSystem', - 'legRests', 'frame', 'stroller', 'deviceForearm', 'deviceWheeled', - 'deviceManual', 'deviceAmbulation', 'deviceDependent', 'deviceDynamic', - 'manualDyanmic', 'manualWheelchair', 'powerBase', 'powerScooter', - 'ambulation', 'positioning', 'highTech', 'standingFrame', - 'adpFunded', 'nonADPFunded']: - d[f'section2.devicesandEligibility.{tag}'] = self._t(de, tag) - - # Section 2a - s2a = s2.find('section2a') - if s2a is not None: - for tag in ['walker', 'paediatricFrame', 'forearmCrutches', 'none', - 'reason', 'replacementStatus', 'replacementSize', 'replacementADP', 'replacementSpecial', - 'confirmation1', 'confirmation2', 'confirmation3', 'confirmation4', 'confirmation5', 'confirmation6', - 'seatHeight', 'seatHeightmeasurement', 'handleHeight', 'handleHeightmeasurement', - 'handGrips', 'forearm', 'widthHandles', 'widthHandlesmeasurement', - 'clientWeight', 'clientWeightmeasurement', - 'brakes', 'brakeType', 'noWheels', 'wheelSize', 'backSupport', - 'adpWalker', 'adpFrame', 'adpStanding', - 'nonADP1', 'nonADP2', 'nonADP3', 'nonADP4', 'nonADP5', 'nonADP6', 'nonADP7', 'nonADP8', 'nonADP9', - 'setup1', 'setup2', 'setup3', 'setup4', 'setup5', 'setup6', 'setup7', 'setup8', 'setup9', - 'setup10', 'setup11', 'setup12', 'setup13', 'setup14', 'setup15', 'setup16', 'setup17', 'setup18', - 'custom', 'costLabour']: - d[f'section2.section2a.{tag}'] = self._t(s2a, tag) - - # Section 2b - s2b = s2.find('section2b') - if s2b is not None: - for tag in ['baseDevice', 'powerAddOndevice', - 'reason', 'replacementStatus', 'replacementSize', 'replacementADP', 'replacementSpecial', - 'confirmation1', 'confirmation2', 'confirmation3', 'confirmation4', 'confirmation5', - 'confirmation6', 'confirmation7', 'confirmation8', 'confirmation9', 'confirmation10', - 'confirmation11', 'confirmation12', 'confirmation13', - 'seatWidth', 'seatWidthmeasurement', 'seatDepth', 'seatDepthmeasurement', - 'floorHeight', 'floorHeightmeasurement', 'caneHeight', 'caneHeightmeasurement', - 'backHeight', 'backHeightmeasurement', 'restLength', 'restLengthmeasurement', - 'clientWeight', 'clientWeightmeasurement', - 'adjustableTension', 'heavyDuty', 'recliner', 'footplates', 'legrests', - 'spoke', 'projected', 'standardManual', 'gradeAids', 'casterPin', - 'amputeeAxle', 'quickRelease', 'stroller', 'oxygen', 'ventilator', - 'titanium', 'clothingGuards', 'oneArm', 'uniLateral', 'plastic', - 'rationale', - 'nonADP1', 'nonADP2', 'nonADP3', 'nonADP4', 'nonADP5', 'nonADP6', 'nonADP7', 'nonADP8', 'nonADP9', - 'setup1', 'setup2', 'setup3', 'setup4', 'setup5', 'setup6', 'setup7', 'setup8', 'setup9', - 'setup10', 'setup11', 'setup12', 'setup13', 'setup14', 'setup15', 'setup16', 'setup17', 'setup18', - 'custom', 'costLabour']: - d[f'section2.section2b.{tag}'] = self._t(s2b, tag) - - # Section 2c - s2c = s2.find('section2c') - if s2c is not None: - for tag in ['baseDevice', - 'reason', 'replacementStatus', 'replacementSize', 'replacementADP', 'replacementSpecial', - 'confirmation1', 'confirmation2', 'confirmation3', 'confirmation4', 'confirmation5', - 'seatWidth', 'seatWidthmeasurement', 'backHeight', 'backHeightmeasurement', - 'floorHeight', 'floorHeightmeasurement', 'restLength', 'restLengthmeasurement', - 'seatDepth', 'seatDepthmeasurement', 'clientWeight', 'clientWeightmeasurement', - 'adjustableTension', 'midline', 'manualRecline', 'footplates', 'legrests', - 'swingaway', 'onePiece', 'seatPackage1', 'seatPackage2', 'oxygen', 'ventilator', - 'spControls1', 'spControls2', 'spControls3', 'spControls4', 'spControls5', 'spControls6', - 'autoCorrection', 'rationale', - 'powerTilt', 'powerRecline', 'tiltAndRecline', 'powerElevating', 'ControlBox', - 'nonADP1', 'nonADP2', 'nonADP3', 'nonADP4', 'nonADP5', 'nonADP6', 'nonADP7', 'nonADP8', 'nonADP9', - 'setup1', 'setup2', 'setup3', 'setup4', 'setup5', 'setup6', 'setup7', 'setup8', 'setup9', - 'setup10', 'setup11', 'setup12', 'setup13', 'setup14', 'setup15', 'setup16', 'setup17', 'setup18', - 'custom', 'costLabour']: - d[f'section2.section2c.{tag}'] = self._t(s2c, tag) - - # Section 2d - s2d = s2.find('section2d') - if s2d is not None: - for tag in ['seatM', 'seatCF', 'coverM', 'coverCF', 'optionM', 'optionCF', 'hardwareM', 'hardwareCF', - 'adductorM', 'adductorCF', 'pommelCF', - 'backM', 'backCF', 'supportoptionM', 'supportoptionCF', 'backcoverCF', 'backHardwareM', 'backHardwareCF', - 'completeM', 'completeCF', - 'headrestM', 'headrestCF', 'headoptionCF', 'headhardwareM', 'headhardwareCF', - 'beltM', 'beltCF', 'beltoptionCF', - 'armsupportM', 'armsupportCF', 'armoptionM', 'armoptionCF', 'armhardwareM', 'armhardwareCF', - 'trayM', 'trayCF', 'trayoptionM', 'trayoptionCF', - 'lateralsupportM', 'lateralsupportCF', 'lateraloptionCF', 'lateralhardwareCF', - 'footsupportM', 'footsupportCF', 'footoptionM', 'footoptionCF', 'foothardwareM', 'foothardwareCF', - 'reason', 'replacementStatus', 'replacementSize', 'replacementADP', 'replacementSpecial', - 'confirmation1', 'confirmation2', - 'nonADP1', 'nonADP2', 'nonADP3', 'nonADP4', 'nonADP5', 'nonADP6', 'nonADP7', 'nonADP8', 'nonADP9', - 'setup1', 'setup2', 'setup3', 'setup4', 'setup5', 'setup6', 'setup7', 'setup8', 'setup9', - 'setup10', 'setup11', 'setup12', 'setup13', 'setup14', 'setup15', 'setup16', 'setup17', 'setup18', - 'custom', 'costLabour']: - d[f'section2.section2d.{tag}'] = self._t(s2d, tag) - - # Section 3 - s3 = form.find('section3') - if s3 is not None: - sig = s3.find('sig') - if sig is not None: - for tag in ['signature', 'person', 'Date']: - d[f'section3.sig.{tag}'] = self._t(sig, tag) - contact = s3.find('contact') - if contact is not None: - for tag in ['relationship', 'applicantLastname', 'applicantFirstname', 'applicantMiddleinitial', - 'unitNo', 'streetNo', 'streetName', 'rrRoute', - 'city', 'province', 'postalCode', 'homePhone', 'busPhone', 'phoneExtension']: - d[f'section3.contact.{tag}'] = self._t(contact, tag) - - # Section 4 - s4 = form.find('section4') - if s4 is not None: - auth = s4.find('authorizer') - if auth is not None: - for tag in ['authorizerLastname', 'authorizerFirstname', 'busPhone', 'phoneExtension', 'adpNo', 'signature', 'Date']: - d[f'section4.authorizer.{tag}'] = self._t(auth, tag) - vendor = s4.find('vendor') - if vendor is not None: - for tag in ['vendorBusName', 'adpVendorRegNo', 'vendorLastfirstname', 'positionTitle', 'vendorLocation', 'busPhone', 'phoneExtension', 'signature', 'Date']: - d[f'section4.vendor.{tag}'] = self._t(vendor, tag) - v2 = s4.find('vendor2') - if v2 is not None: - for tag in ['vendorBusName', 'adpVendorRegNo', 'vendorLastfirstname', 'positionTitle', 'vendorLocation', 'busPhone', 'phoneExtension', 'signature', 'Date']: - d[f'section4.vendor2.{tag}'] = self._t(v2, tag) - eq = s4.find('equipmentSpec') - if eq is not None: - d['section4.equipmentSpec.vendorInvoiceNo'] = self._t(eq, 'vendorInvoiceNo') - d['section4.equipmentSpec.vendorADPRegNo'] = self._t(eq, 'vendorADPRegNo') - t2 = eq.find('Table2') - if t2 is not None: - r1 = t2.find('Row1') - if r1 is not None: - for tag in ['Cell1', 'Cell2', 'Cell3', 'Cell4', 'Cell5']: - d[f'section4.equipmentSpec.Table2.Row1.{tag}'] = self._t(r1, tag) - pod = s4.find('proofOfDelivery') - if pod is not None: - for tag in ['signature', 'receivedBy', 'Date']: - d[f'section4.proofOfDelivery.{tag}'] = self._t(pod, tag) - note = s4.find('noteToADP') - if note is not None: - for tag in ['section1', 'section2a', 'section2b', 'section2c', 'section2d', - 'section3and4', 'vendorReplacement', 'vendorCustom', 'fundingChart', 'letter']: - d[f'section4.noteToADP.{tag}'] = self._t(note, tag) - - return d - - # ------------------------------------------------------------------ - # STEP 2: JSON DICT -> MODEL FIELD VALUES - # ------------------------------------------------------------------ - def _json_to_model_vals(self, d): - """Map flat JSON dict to fusion.adp.application.data field values.""" - g = d.get # shorthand - vals = {} - - # Metadata - vals['device_category'] = g('deviceCategory', '') or 'MD' - vals['version_number'] = g('VersionNumber', '') - - # Section 1 - Applicant - vals['applicant_last_name'] = g('section1.applicantLastname', '') - vals['applicant_first_name'] = g('section1.applicantFirstname', '') - vals['applicant_middle_initial'] = g('section1.applicantMiddleinitial', '') - vals['health_card_number'] = g('section1.healthNo', '') - vals['health_card_version'] = g('section1.versionNo', '') - vals['date_of_birth'] = self._pd(g('section1.DateOfBirth', '')) - vals['ltch_name'] = g('section1.nameLTCH', '') - vals['unit_number'] = g('section1.unitNo', '') - vals['street_number'] = g('section1.streetNo', '') - vals['street_name'] = g('section1.streetName', '') - vals['rural_route'] = g('section1.rrRoute', '') - vals['city'] = g('section1.city', '') - vals['province'] = g('section1.province', '') - vals['postal_code'] = g('section1.postalCode', '') - vals['home_phone'] = g('section1.homePhone', '') - vals['business_phone'] = g('section1.busPhone', '') - vals['phone_extension'] = g('section1.phoneExtension', '') - - # Benefits - q1 = g('section1.confirmationOfBenefit.q1Yn', '').lower() - vals['receives_social_assistance'] = q1 == 'yes' - q1type = g('section1.confirmationOfBenefit.q1Ifyes', '').lower() - vals['benefit_owp'] = 'owp' in q1type if q1type else False - vals['benefit_odsp'] = 'odsp' in q1type if q1type else False - vals['benefit_acsd'] = 'acsd' in q1type if q1type else False - if vals['benefit_owp']: - vals['benefit_type'] = 'owp' - elif vals['benefit_odsp']: - vals['benefit_type'] = 'odsp' - elif vals['benefit_acsd']: - vals['benefit_type'] = 'acsd' - vals['wsib_eligible'] = g('section1.confirmationOfBenefit.q2Yn', '').lower() == 'yes' - vals['vac_eligible'] = g('section1.confirmationOfBenefit.q3Yn', '').lower() == 'yes' - - # Section 2 - Devices & Eligibility - vals['medical_condition'] = g('section2.devicesandEligibility.condition', '') - vals['mobility_status'] = g('section2.devicesandEligibility.status', '') - - # Previously funded - vals['prev_funded_none'] = bool(g('section2.devicesandEligibility.none', '')) - vals['prev_funded_forearm'] = bool(g('section2.devicesandEligibility.forearm', '')) - vals['prev_funded_wheeled'] = bool(g('section2.devicesandEligibility.wheeled', '')) - vals['prev_funded_manual'] = bool(g('section2.devicesandEligibility.manual', '')) - vals['prev_funded_power'] = bool(g('section2.devicesandEligibility.power', '')) - vals['prev_funded_addon'] = bool(g('section2.devicesandEligibility.addOn', '')) - vals['prev_funded_scooter'] = bool(g('section2.devicesandEligibility.scooter', '')) - vals['prev_funded_seating'] = bool(g('section2.devicesandEligibility.seating', '')) - vals['prev_funded_tilt'] = bool(g('section2.devicesandEligibility.tiltSystem', '')) - vals['prev_funded_recline'] = bool(g('section2.devicesandEligibility.reclineSystem', '')) - vals['prev_funded_legrests'] = bool(g('section2.devicesandEligibility.legRests', '')) - vals['prev_funded_frame'] = bool(g('section2.devicesandEligibility.frame', '')) - vals['prev_funded_stroller'] = bool(g('section2.devicesandEligibility.stroller', '')) - - # Devices currently required - vals['device_forearm_crutches'] = bool(g('section2.devicesandEligibility.deviceForearm', '')) - vals['device_wheeled_walker'] = bool(g('section2.devicesandEligibility.deviceWheeled', '')) - vals['device_manual_wheelchair'] = bool(g('section2.devicesandEligibility.deviceManual', '')) - vals['device_ambulation_manual'] = bool(g('section2.devicesandEligibility.deviceAmbulation', '')) - vals['device_dependent_wheelchair'] = bool(g('section2.devicesandEligibility.deviceDependent', '')) - vals['device_dynamic_tilt'] = bool(g('section2.devicesandEligibility.deviceDynamic', '')) - vals['device_manual_dynamic'] = bool(g('section2.devicesandEligibility.manualDyanmic', '')) - vals['device_manual_power_addon'] = bool(g('section2.devicesandEligibility.manualWheelchair', '')) - vals['device_power_base'] = bool(g('section2.devicesandEligibility.powerBase', '')) - vals['device_power_scooter'] = bool(g('section2.devicesandEligibility.powerScooter', '')) - vals['device_ambulation_power'] = bool(g('section2.devicesandEligibility.ambulation', '')) - vals['device_positioning'] = bool(g('section2.devicesandEligibility.positioning', '')) - vals['device_high_tech'] = bool(g('section2.devicesandEligibility.highTech', '')) - vals['device_standing_frame'] = bool(g('section2.devicesandEligibility.standingFrame', '')) - vals['device_adp_funded_mods'] = bool(g('section2.devicesandEligibility.adpFunded', '')) - vals['device_non_adp_funded_mods'] = bool(g('section2.devicesandEligibility.nonADPFunded', '')) - - # Section 2a - Walkers - vals['s2a_base_device'] = g('section2.section2a.walker', '') - vals['s2a_paediatric_frame'] = g('section2.section2a.paediatricFrame', '') - vals['s2a_forearm_crutches'] = g('section2.section2a.forearmCrutches', '') - vals['s2a_none'] = g('section2.section2a.none', '') - vals['s2a_reason'] = g('section2.section2a.reason', '') - vals['s2a_replacement_status'] = g('section2.section2a.replacementStatus', '') - vals['s2a_replacement_size'] = g('section2.section2a.replacementSize', '') - vals['s2a_replacement_adp'] = g('section2.section2a.replacementADP', '') - vals['s2a_replacement_special'] = g('section2.section2a.replacementSpecial', '') - for i in range(1, 7): - vals[f's2a_confirm{i}'] = g(f'section2.section2a.confirmation{i}', '') - vals['s2a_seat_height'] = g('section2.section2a.seatHeight', '') - vals['s2a_seat_height_unit'] = g('section2.section2a.seatHeightmeasurement', '') - vals['s2a_handle_height'] = g('section2.section2a.handleHeight', '') - vals['s2a_handle_height_unit'] = g('section2.section2a.handleHeightmeasurement', '') - vals['s2a_hand_grips'] = g('section2.section2a.handGrips', '') - vals['s2a_forearm_attachments'] = g('section2.section2a.forearm', '') - vals['s2a_width_handles'] = g('section2.section2a.widthHandles', '') - vals['s2a_width_handles_unit'] = g('section2.section2a.widthHandlesmeasurement', '') - vals['s2a_client_weight'] = g('section2.section2a.clientWeight', '') - vals['s2a_client_weight_unit'] = g('section2.section2a.clientWeightmeasurement', '') - vals['s2a_brakes'] = g('section2.section2a.brakes', '') - vals['s2a_brake_type'] = g('section2.section2a.brakeType', '') - vals['s2a_num_wheels'] = g('section2.section2a.noWheels', '') - vals['s2a_wheel_size'] = g('section2.section2a.wheelSize', '') - vals['s2a_back_support'] = g('section2.section2a.backSupport', '') - vals['s2a_adp_walker'] = g('section2.section2a.adpWalker', '') - vals['s2a_adp_frame'] = g('section2.section2a.adpFrame', '') - vals['s2a_adp_standing'] = g('section2.section2a.adpStanding', '') - vals['s2a_custom'] = g('section2.section2a.custom', '') - vals['s2a_cost_labour'] = g('section2.section2a.costLabour', '') - - # Section 2b - Manual Wheelchairs - vals['s2b_base_device'] = g('section2.section2b.baseDevice', '') - vals['s2b_power_addon'] = g('section2.section2b.powerAddOndevice', '') - vals['s2b_reason'] = g('section2.section2b.reason', '') - vals['s2b_replacement_status'] = g('section2.section2b.replacementStatus', '') - vals['s2b_replacement_size'] = g('section2.section2b.replacementSize', '') - vals['s2b_replacement_adp'] = g('section2.section2b.replacementADP', '') - vals['s2b_replacement_special'] = g('section2.section2b.replacementSpecial', '') - for i in range(1, 14): - vals[f's2b_confirm{i}'] = g(f'section2.section2b.confirmation{i}', '') - vals['s2b_seat_width'] = g('section2.section2b.seatWidth', '') - vals['s2b_seat_width_unit'] = g('section2.section2b.seatWidthmeasurement', '') - vals['s2b_seat_depth'] = g('section2.section2b.seatDepth', '') - vals['s2b_seat_depth_unit'] = g('section2.section2b.seatDepthmeasurement', '') - vals['s2b_floor_height'] = g('section2.section2b.floorHeight', '') - vals['s2b_floor_height_unit'] = g('section2.section2b.floorHeightmeasurement', '') - vals['s2b_cane_height'] = g('section2.section2b.caneHeight', '') - vals['s2b_cane_height_unit'] = g('section2.section2b.caneHeightmeasurement', '') - vals['s2b_back_height'] = g('section2.section2b.backHeight', '') - vals['s2b_back_height_unit'] = g('section2.section2b.backHeightmeasurement', '') - vals['s2b_rest_length'] = g('section2.section2b.restLength', '') - vals['s2b_rest_length_unit'] = g('section2.section2b.restLengthmeasurement', '') - vals['s2b_client_weight'] = g('section2.section2b.clientWeight', '') - vals['s2b_client_weight_unit'] = g('section2.section2b.clientWeightmeasurement', '') - vals['s2b_adjustable_tension'] = bool(g('section2.section2b.adjustableTension', '')) - vals['s2b_heavy_duty'] = bool(g('section2.section2b.heavyDuty', '')) - vals['s2b_recliner'] = bool(g('section2.section2b.recliner', '')) - vals['s2b_footplates'] = bool(g('section2.section2b.footplates', '')) - vals['s2b_legrests'] = bool(g('section2.section2b.legrests', '')) - vals['s2b_spoke'] = bool(g('section2.section2b.spoke', '')) - vals['s2b_projected'] = bool(g('section2.section2b.projected', '')) - vals['s2b_standard_manual'] = bool(g('section2.section2b.standardManual', '')) - vals['s2b_grade_aids'] = bool(g('section2.section2b.gradeAids', '')) - vals['s2b_caster_pin'] = bool(g('section2.section2b.casterPin', '')) - vals['s2b_amputee_axle'] = bool(g('section2.section2b.amputeeAxle', '')) - vals['s2b_quick_release'] = bool(g('section2.section2b.quickRelease', '')) - vals['s2b_stroller'] = bool(g('section2.section2b.stroller', '')) - vals['s2b_oxygen'] = bool(g('section2.section2b.oxygen', '')) - vals['s2b_ventilator'] = bool(g('section2.section2b.ventilator', '')) - vals['s2b_titanium'] = bool(g('section2.section2b.titanium', '')) - vals['s2b_clothing_guards'] = bool(g('section2.section2b.clothingGuards', '')) - vals['s2b_one_arm'] = bool(g('section2.section2b.oneArm', '')) - vals['s2b_uni_lateral'] = bool(g('section2.section2b.uniLateral', '')) - vals['s2b_plastic'] = bool(g('section2.section2b.plastic', '')) - vals['s2b_rationale'] = g('section2.section2b.rationale', '') - vals['s2b_custom'] = g('section2.section2b.custom', '') - vals['s2b_cost_labour'] = g('section2.section2b.costLabour', '') - - # Section 2c - Power Bases / Scooters - vals['s2c_base_device'] = g('section2.section2c.baseDevice', '') - vals['s2c_reason'] = g('section2.section2c.reason', '') - vals['s2c_replacement_status'] = g('section2.section2c.replacementStatus', '') - vals['s2c_replacement_size'] = g('section2.section2c.replacementSize', '') - vals['s2c_replacement_adp'] = g('section2.section2c.replacementADP', '') - vals['s2c_replacement_special'] = g('section2.section2c.replacementSpecial', '') - for i in range(1, 6): - vals[f's2c_confirm{i}'] = g(f'section2.section2c.confirmation{i}', '') - vals['s2c_seat_width'] = g('section2.section2c.seatWidth', '') - vals['s2c_seat_width_unit'] = g('section2.section2c.seatWidthmeasurement', '') - vals['s2c_back_height'] = g('section2.section2c.backHeight', '') - vals['s2c_back_height_unit'] = g('section2.section2c.backHeightmeasurement', '') - vals['s2c_floor_height'] = g('section2.section2c.floorHeight', '') - vals['s2c_floor_height_unit'] = g('section2.section2c.floorHeightmeasurement', '') - vals['s2c_rest_length'] = g('section2.section2c.restLength', '') - vals['s2c_rest_length_unit'] = g('section2.section2c.restLengthmeasurement', '') - vals['s2c_seat_depth'] = g('section2.section2c.seatDepth', '') - vals['s2c_seat_depth_unit'] = g('section2.section2c.seatDepthmeasurement', '') - vals['s2c_client_weight'] = g('section2.section2c.clientWeight', '') - vals['s2c_client_weight_unit'] = g('section2.section2c.clientWeightmeasurement', '') - vals['s2c_adjustable_tension'] = bool(g('section2.section2c.adjustableTension', '')) - vals['s2c_midline'] = bool(g('section2.section2c.midline', '')) - vals['s2c_manual_recline'] = bool(g('section2.section2c.manualRecline', '')) - vals['s2c_footplates'] = bool(g('section2.section2c.footplates', '')) - vals['s2c_legrests'] = bool(g('section2.section2c.legrests', '')) - vals['s2c_swingaway'] = bool(g('section2.section2c.swingaway', '')) - vals['s2c_one_piece'] = bool(g('section2.section2c.onePiece', '')) - vals['s2c_seat_package_1'] = bool(g('section2.section2c.seatPackage1', '')) - vals['s2c_seat_package_2'] = bool(g('section2.section2c.seatPackage2', '')) - vals['s2c_oxygen'] = bool(g('section2.section2c.oxygen', '')) - vals['s2c_ventilator'] = bool(g('section2.section2c.ventilator', '')) - vals['s2c_sp_controls_1'] = bool(g('section2.section2c.spControls1', '')) - vals['s2c_sp_controls_2'] = bool(g('section2.section2c.spControls2', '')) - vals['s2c_sp_controls_3'] = bool(g('section2.section2c.spControls3', '')) - vals['s2c_sp_controls_4'] = bool(g('section2.section2c.spControls4', '')) - vals['s2c_sp_controls_5'] = bool(g('section2.section2c.spControls5', '')) - vals['s2c_sp_controls_6'] = bool(g('section2.section2c.spControls6', '')) - vals['s2c_auto_correction'] = bool(g('section2.section2c.autoCorrection', '')) - vals['s2c_rationale'] = g('section2.section2c.rationale', '') - vals['s2c_power_tilt'] = bool(g('section2.section2c.powerTilt', '')) - vals['s2c_power_recline'] = bool(g('section2.section2c.powerRecline', '')) - vals['s2c_tilt_and_recline'] = bool(g('section2.section2c.tiltAndRecline', '')) - vals['s2c_power_elevating'] = bool(g('section2.section2c.powerElevating', '')) - vals['s2c_control_box'] = bool(g('section2.section2c.ControlBox', '')) - vals['s2c_custom'] = g('section2.section2c.custom', '') - vals['s2c_cost_labour'] = g('section2.section2c.costLabour', '') - - # Section 2d - Positioning/Seating - vals['s2d_seat_modular'] = bool(g('section2.section2d.seatM', '')) - vals['s2d_seat_custom'] = bool(g('section2.section2d.seatCF', '')) - vals['s2d_seat_cover_modular'] = bool(g('section2.section2d.coverM', '')) - vals['s2d_seat_cover_custom'] = bool(g('section2.section2d.coverCF', '')) - vals['s2d_seat_option_modular'] = bool(g('section2.section2d.optionM', '')) - vals['s2d_seat_option_custom'] = bool(g('section2.section2d.optionCF', '')) - vals['s2d_seat_hardware_modular'] = bool(g('section2.section2d.hardwareM', '')) - vals['s2d_seat_hardware_custom'] = bool(g('section2.section2d.hardwareCF', '')) - vals['s2d_adductor_modular'] = bool(g('section2.section2d.adductorM', '')) - vals['s2d_adductor_custom'] = bool(g('section2.section2d.adductorCF', '')) - vals['s2d_pommel_custom'] = bool(g('section2.section2d.pommelCF', '')) - vals['s2d_back_modular'] = bool(g('section2.section2d.backM', '')) - vals['s2d_back_custom'] = bool(g('section2.section2d.backCF', '')) - vals['s2d_back_option_modular'] = bool(g('section2.section2d.supportoptionM', '')) - vals['s2d_back_option_custom'] = bool(g('section2.section2d.supportoptionCF', '')) - vals['s2d_back_cover_custom'] = bool(g('section2.section2d.backcoverCF', '')) - vals['s2d_back_hardware_modular'] = bool(g('section2.section2d.backHardwareM', '')) - vals['s2d_back_hardware_custom'] = bool(g('section2.section2d.backHardwareCF', '')) - vals['s2d_complete_modular'] = bool(g('section2.section2d.completeM', '')) - vals['s2d_complete_custom'] = bool(g('section2.section2d.completeCF', '')) - vals['s2d_headrest_modular'] = bool(g('section2.section2d.headrestM', '')) - vals['s2d_headrest_custom'] = bool(g('section2.section2d.headrestCF', '')) - vals['s2d_head_option_custom'] = bool(g('section2.section2d.headoptionCF', '')) - vals['s2d_head_hardware_modular'] = bool(g('section2.section2d.headhardwareM', '')) - vals['s2d_head_hardware_custom'] = bool(g('section2.section2d.headhardwareCF', '')) - vals['s2d_belt_modular'] = bool(g('section2.section2d.beltM', '')) - vals['s2d_belt_custom'] = bool(g('section2.section2d.beltCF', '')) - vals['s2d_belt_option_custom'] = bool(g('section2.section2d.beltoptionCF', '')) - vals['s2d_arm_modular'] = bool(g('section2.section2d.armsupportM', '')) - vals['s2d_arm_custom'] = bool(g('section2.section2d.armsupportCF', '')) - vals['s2d_arm_option_modular'] = bool(g('section2.section2d.armoptionM', '')) - vals['s2d_arm_option_custom'] = bool(g('section2.section2d.armoptionCF', '')) - vals['s2d_arm_hardware_modular'] = bool(g('section2.section2d.armhardwareM', '')) - vals['s2d_arm_hardware_custom'] = bool(g('section2.section2d.armhardwareCF', '')) - vals['s2d_tray_modular'] = bool(g('section2.section2d.trayM', '')) - vals['s2d_tray_custom'] = bool(g('section2.section2d.trayCF', '')) - vals['s2d_tray_option_modular'] = bool(g('section2.section2d.trayoptionM', '')) - vals['s2d_tray_option_custom'] = bool(g('section2.section2d.trayoptionCF', '')) - vals['s2d_lateral_modular'] = bool(g('section2.section2d.lateralsupportM', '')) - vals['s2d_lateral_custom'] = bool(g('section2.section2d.lateralsupportCF', '')) - vals['s2d_lateral_option_custom'] = bool(g('section2.section2d.lateraloptionCF', '')) - vals['s2d_lateral_hardware_custom'] = bool(g('section2.section2d.lateralhardwareCF', '')) - vals['s2d_foot_modular'] = bool(g('section2.section2d.footsupportM', '')) - vals['s2d_foot_custom'] = bool(g('section2.section2d.footsupportCF', '')) - vals['s2d_foot_option_modular'] = bool(g('section2.section2d.footoptionM', '')) - vals['s2d_foot_option_custom'] = bool(g('section2.section2d.footoptionCF', '')) - vals['s2d_foot_hardware_modular'] = bool(g('section2.section2d.foothardwareM', '')) - vals['s2d_foot_hardware_custom'] = bool(g('section2.section2d.foothardwareCF', '')) - vals['s2d_reason'] = g('section2.section2d.reason', '') - vals['s2d_replacement_status'] = g('section2.section2d.replacementStatus', '') - vals['s2d_replacement_size'] = g('section2.section2d.replacementSize', '') - vals['s2d_replacement_adp'] = g('section2.section2d.replacementADP', '') - vals['s2d_replacement_special'] = g('section2.section2d.replacementSpecial', '') - vals['s2d_confirm1'] = g('section2.section2d.confirmation1', '') - vals['s2d_confirm2'] = g('section2.section2d.confirmation2', '') - vals['s2d_custom'] = g('section2.section2d.custom', '') - vals['s2d_cost_labour'] = g('section2.section2d.costLabour', '') - - # Section 3 - Consent - vals['consent_date'] = self._pd(g('section3.sig.Date', '')) - person = g('section3.sig.person', '').lower() - vals['consent_signed_by'] = 'applicant' if 'applicant' in person else ('agent' if 'agent' in person else False) - vals['agent_relationship'] = g('section3.contact.relationship', '') - vals['agent_last_name'] = g('section3.contact.applicantLastname', '') - vals['agent_first_name'] = g('section3.contact.applicantFirstname', '') - vals['agent_middle_initial'] = g('section3.contact.applicantMiddleinitial', '') - vals['agent_unit'] = g('section3.contact.unitNo', '') - vals['agent_street_no'] = g('section3.contact.streetNo', '') - vals['agent_street_name'] = g('section3.contact.streetName', '') - vals['agent_rural_route'] = g('section3.contact.rrRoute', '') - vals['agent_city'] = g('section3.contact.city', '') - vals['agent_province'] = g('section3.contact.province', '') - vals['agent_postal_code'] = g('section3.contact.postalCode', '') - vals['agent_home_phone'] = g('section3.contact.homePhone', '') - vals['agent_bus_phone'] = g('section3.contact.busPhone', '') - vals['agent_phone_ext'] = g('section3.contact.phoneExtension', '') - - # Section 4 - Authorizer - vals['authorizer_last_name'] = g('section4.authorizer.authorizerLastname', '') - vals['authorizer_first_name'] = g('section4.authorizer.authorizerFirstname', '') - vals['authorizer_phone'] = g('section4.authorizer.busPhone', '') - vals['authorizer_phone_ext'] = g('section4.authorizer.phoneExtension', '') - vals['authorizer_adp_number'] = g('section4.authorizer.adpNo', '') - vals['assessment_date'] = self._pd(g('section4.authorizer.Date', '')) - vals['application_date'] = vals['consent_date'] or vals['assessment_date'] - - # Section 4 - Vendor 1 - vals['vendor_business_name'] = g('section4.vendor.vendorBusName', '') - vals['vendor_adp_number'] = g('section4.vendor.adpVendorRegNo', '') - vals['vendor_representative'] = g('section4.vendor.vendorLastfirstname', '') - vals['vendor_position'] = g('section4.vendor.positionTitle', '') - vals['vendor_location'] = g('section4.vendor.vendorLocation', '') - vals['vendor_phone'] = g('section4.vendor.busPhone', '') - vals['vendor_phone_ext'] = g('section4.vendor.phoneExtension', '') - vals['vendor_sign_date'] = self._pd(g('section4.vendor.Date', '')) - - # Section 4 - Vendor 2 - vals['vendor2_business_name'] = g('section4.vendor2.vendorBusName', '') - vals['vendor2_adp_number'] = g('section4.vendor2.adpVendorRegNo', '') - vals['vendor2_representative'] = g('section4.vendor2.vendorLastfirstname', '') - vals['vendor2_position'] = g('section4.vendor2.positionTitle', '') - vals['vendor2_location'] = g('section4.vendor2.vendorLocation', '') - vals['vendor2_phone'] = g('section4.vendor2.busPhone', '') - vals['vendor2_phone_ext'] = g('section4.vendor2.phoneExtension', '') - vals['vendor2_sign_date'] = self._pd(g('section4.vendor2.Date', '')) - - # Equipment Spec - vals['equip_vendor_invoice_no'] = g('section4.equipmentSpec.vendorInvoiceNo', '') - vals['equip_vendor_adp_reg'] = g('section4.equipmentSpec.vendorADPRegNo', '') - vals['equip_cell1'] = g('section4.equipmentSpec.Table2.Row1.Cell1', '') - vals['equip_cell2'] = g('section4.equipmentSpec.Table2.Row1.Cell2', '') - vals['equip_cell3'] = g('section4.equipmentSpec.Table2.Row1.Cell3', '') - vals['equip_cell4'] = g('section4.equipmentSpec.Table2.Row1.Cell4', '') - vals['equip_cell5'] = g('section4.equipmentSpec.Table2.Row1.Cell5', '') - vals['pod_received_by'] = g('section4.proofOfDelivery.receivedBy', '') - vals['pod_date'] = self._pd(g('section4.proofOfDelivery.Date', '')) - - # Note to ADP - vals['note_section1'] = bool(g('section4.noteToADP.section1', '')) - vals['note_section2a'] = bool(g('section4.noteToADP.section2a', '')) - vals['note_section2b'] = bool(g('section4.noteToADP.section2b', '')) - vals['note_section2c'] = bool(g('section4.noteToADP.section2c', '')) - vals['note_section2d'] = bool(g('section4.noteToADP.section2d', '')) - vals['note_section3and4'] = bool(g('section4.noteToADP.section3and4', '')) - vals['note_vendor_replacement'] = g('section4.noteToADP.vendorReplacement', '') - vals['note_vendor_custom'] = g('section4.noteToADP.vendorCustom', '') - vals['note_funding_chart'] = g('section4.noteToADP.fundingChart', '') - vals['note_letter'] = g('section4.noteToADP.letter', '') - - return vals - - # ------------------------------------------------------------------ - # PROFILE MANAGEMENT - # ------------------------------------------------------------------ - def _find_or_create_profile(self, vals, sale_order=None): - """Find or create a client profile from parsed application data.""" - Profile = self.env['fusion.client.profile'] - hc = (vals.get('health_card_number') or '').strip() - first = (vals.get('applicant_first_name') or '').strip() - last = (vals.get('applicant_last_name') or '').strip() - dob = vals.get('date_of_birth') - - profile = False - if hc: - profile = Profile.search([('health_card_number', '=', hc)], limit=1) - if not profile and first and last and dob: - profile = Profile.search([ - ('first_name', '=ilike', first), - ('last_name', '=ilike', last), - ('date_of_birth', '=', dob), - ], limit=1) - - profile_vals = { - 'first_name': first, - 'last_name': last, - 'middle_initial': vals.get('applicant_middle_initial', ''), - 'health_card_number': hc, - 'health_card_version': vals.get('health_card_version', ''), - 'date_of_birth': dob, - 'ltch_name': vals.get('ltch_name', ''), - 'unit_number': vals.get('unit_number', ''), - 'street_number': vals.get('street_number', ''), - 'street_name': vals.get('street_name', ''), - 'rural_route': vals.get('rural_route', ''), - 'city': vals.get('city', ''), - 'province': vals.get('province', '') or 'ON', - 'postal_code': vals.get('postal_code', ''), - 'home_phone': vals.get('home_phone', ''), - 'business_phone': vals.get('business_phone', ''), - 'phone_extension': vals.get('phone_extension', ''), - 'medical_condition': vals.get('medical_condition', ''), - 'mobility_status': vals.get('mobility_status', ''), - } - if vals.get('receives_social_assistance'): - profile_vals['receives_social_assistance'] = True - profile_vals['benefit_type'] = vals.get('benefit_type') - if vals.get('wsib_eligible'): - profile_vals['wsib_eligible'] = True - if vals.get('vac_eligible'): - profile_vals['vac_eligible'] = True - if vals.get('assessment_date'): - profile_vals['last_assessment_date'] = vals['assessment_date'] - - # Link to partner - if sale_order and sale_order.partner_id: - profile_vals['partner_id'] = sale_order.partner_id.id - elif not profile or not profile.partner_id: - partner = self._find_partner(first, last) - if partner: - profile_vals['partner_id'] = partner.id - - if profile: - profile.write(profile_vals) - else: - profile = Profile.create(profile_vals) - - return profile - - def _find_partner(self, first_name, last_name): - """Try to find a matching res.partner.""" - if not first_name or not last_name: - return False - Partner = self.env['res.partner'] - partner = Partner.search([('name', 'ilike', f'{first_name} {last_name}')], limit=1) - if not partner: - partner = Partner.search([('name', 'ilike', f'{last_name}, {first_name}')], limit=1) - return partner or False - - # ------------------------------------------------------------------ - # HELPERS - # ------------------------------------------------------------------ - @staticmethod - def _t(element, tag): - """Get text of child element, empty string if missing.""" - child = element.find(tag) - if child is not None and child.text: - return child.text.strip() - return '' - - @staticmethod - def _pd(date_str): - """Parse date string, return date or False.""" - if not date_str: - return False - for fmt in ('%Y/%m/%d', '%Y-%m-%d', '%Y%m%d'): - try: - return datetime.strptime(date_str.strip(), fmt).date() - except ValueError: - continue - return False diff --git a/fusion_claims/fusion_claims/report/invoice_report_landscape.xml b/fusion_claims/fusion_claims/report/invoice_report_landscape.xml deleted file mode 100644 index b64231a..0000000 --- a/fusion_claims/fusion_claims/report/invoice_report_landscape.xml +++ /dev/null @@ -1,410 +0,0 @@ - - - - - diff --git a/fusion_claims/fusion_claims/report/invoice_report_portrait.xml b/fusion_claims/fusion_claims/report/invoice_report_portrait.xml deleted file mode 100644 index 35882e4..0000000 --- a/fusion_claims/fusion_claims/report/invoice_report_portrait.xml +++ /dev/null @@ -1,377 +0,0 @@ - - - - - diff --git a/fusion_claims/fusion_claims/report/report_accessibility_contract.xml b/fusion_claims/fusion_claims/report/report_accessibility_contract.xml deleted file mode 100644 index cf19654..0000000 --- a/fusion_claims/fusion_claims/report/report_accessibility_contract.xml +++ /dev/null @@ -1,342 +0,0 @@ - - - - - diff --git a/fusion_claims/fusion_claims/report/report_actions.xml b/fusion_claims/fusion_claims/report/report_actions.xml deleted file mode 100644 index 31f468b..0000000 --- a/fusion_claims/fusion_claims/report/report_actions.xml +++ /dev/null @@ -1,184 +0,0 @@ - - - - - - A4 Landscape (Fusion Central) - - A4 - Landscape - 20 - 20 - 7 - 7 - - 20 - 90 - - - - - Quotation / Order (Portrait - ADP) - sale.order - qweb-pdf - fusion_claims.report_saleorder_portrait - fusion_claims.report_saleorder_portrait - (object.state in ('draft', 'sent') and 'Quotation - %s' % object.name) or 'Order - %s' % object.name - - report - - - - - Quotation / Order (Landscape - ADP) - sale.order - qweb-pdf - fusion_claims.report_saleorder_landscape - fusion_claims.report_saleorder_landscape - '%s - %s' % (object.name, object.partner_id.name) - - report - - - - - - Invoice (Portrait) - account.move - qweb-pdf - fusion_claims.report_invoice_portrait - fusion_claims.report_invoice_portrait - 'Invoice - %s' % object.name - - report - - - - - Invoice (Landscape - ADP) - account.move - qweb-pdf - fusion_claims.report_invoice_landscape - fusion_claims.report_invoice_landscape - 'Invoice - %s' % object.name - - report - - - - - - - - ADP Proof of Delivery - sale.order - qweb-pdf - fusion_claims.report_proof_of_delivery - fusion_claims.report_proof_of_delivery - 'ADP Proof of Delivery - %s' % object.name - - report - - - - - - - Proof of Delivery - sale.order - qweb-pdf - fusion_claims.report_proof_of_delivery_standard - fusion_claims.report_proof_of_delivery_standard - 'Proof of Delivery - %s' % object.name - - report - - - - - - - Proof of Pickup - sale.order - qweb-pdf - fusion_claims.report_proof_of_pickup - fusion_claims.report_proof_of_pickup - 'Proof of Pickup - %s' % object.name - - report - - - - - - - Rental Agreement - sale.order - qweb-pdf - fusion_claims.report_rental_agreement - fusion_claims.report_rental_agreement - 'Rental Agreement - %s' % object.name - - report - - - - - - - Grab Bar Installation Waiver - sale.order - qweb-pdf - fusion_claims.report_grab_bar_waiver - fusion_claims.report_grab_bar_waiver - 'Grab Bar Waiver - %s' % object.name - - report - - - - - - - Accessibility Equipment Contract - sale.order - qweb-pdf - fusion_claims.report_accessibility_contract - fusion_claims.report_accessibility_contract - 'Accessibility Contract - %s' % object.name - - report - - - - - - - March of Dimes Quotation - sale.order - qweb-pdf - fusion_claims.report_mod_quotation - fusion_claims.report_mod_quotation - 'MOD Quotation - %s' % object.name - - report - - - - - - - March of Dimes Invoice - account.move - qweb-pdf - fusion_claims.report_mod_invoice - fusion_claims.report_mod_invoice - 'MOD Invoice - %s' % object.name - - report - - diff --git a/fusion_claims/fusion_claims/report/report_grab_bar_waiver.xml b/fusion_claims/fusion_claims/report/report_grab_bar_waiver.xml deleted file mode 100644 index b703cc5..0000000 --- a/fusion_claims/fusion_claims/report/report_grab_bar_waiver.xml +++ /dev/null @@ -1,184 +0,0 @@ - - - - - diff --git a/fusion_claims/fusion_claims/report/report_invoice_adp.xml b/fusion_claims/fusion_claims/report/report_invoice_adp.xml deleted file mode 100644 index 0519ecb..0000000 --- a/fusion_claims/fusion_claims/report/report_invoice_adp.xml +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/fusion_claims/fusion_claims/report/report_mod_invoice.xml b/fusion_claims/fusion_claims/report/report_mod_invoice.xml deleted file mode 100644 index fae2982..0000000 --- a/fusion_claims/fusion_claims/report/report_mod_invoice.xml +++ /dev/null @@ -1,227 +0,0 @@ - - - - - diff --git a/fusion_claims/fusion_claims/report/report_mod_quotation.xml b/fusion_claims/fusion_claims/report/report_mod_quotation.xml deleted file mode 100644 index 417b09a..0000000 --- a/fusion_claims/fusion_claims/report/report_mod_quotation.xml +++ /dev/null @@ -1,250 +0,0 @@ - - - - - diff --git a/fusion_claims/fusion_claims/report/report_proof_of_delivery.xml b/fusion_claims/fusion_claims/report/report_proof_of_delivery.xml deleted file mode 100644 index 355b90d..0000000 --- a/fusion_claims/fusion_claims/report/report_proof_of_delivery.xml +++ /dev/null @@ -1,303 +0,0 @@ - - - - - diff --git a/fusion_claims/fusion_claims/report/report_proof_of_delivery_standard.xml b/fusion_claims/fusion_claims/report/report_proof_of_delivery_standard.xml deleted file mode 100644 index 895fbe5..0000000 --- a/fusion_claims/fusion_claims/report/report_proof_of_delivery_standard.xml +++ /dev/null @@ -1,289 +0,0 @@ - - - - - diff --git a/fusion_claims/fusion_claims/report/report_proof_of_pickup.xml b/fusion_claims/fusion_claims/report/report_proof_of_pickup.xml deleted file mode 100644 index f0679c0..0000000 --- a/fusion_claims/fusion_claims/report/report_proof_of_pickup.xml +++ /dev/null @@ -1,260 +0,0 @@ - - - - - diff --git a/fusion_claims/fusion_claims/report/report_rental_agreement.xml b/fusion_claims/fusion_claims/report/report_rental_agreement.xml deleted file mode 100644 index f30ae1f..0000000 --- a/fusion_claims/fusion_claims/report/report_rental_agreement.xml +++ /dev/null @@ -1,340 +0,0 @@ - - - - - diff --git a/fusion_claims/fusion_claims/report/report_saleorder_adp.xml b/fusion_claims/fusion_claims/report/report_saleorder_adp.xml deleted file mode 100644 index 0519ecb..0000000 --- a/fusion_claims/fusion_claims/report/report_saleorder_adp.xml +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/fusion_claims/fusion_claims/report/report_templates.xml b/fusion_claims/fusion_claims/report/report_templates.xml deleted file mode 100644 index c35e830..0000000 --- a/fusion_claims/fusion_claims/report/report_templates.xml +++ /dev/null @@ -1,203 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/fusion_claims/fusion_claims/report/sale_report_landscape.xml b/fusion_claims/fusion_claims/report/sale_report_landscape.xml deleted file mode 100644 index 8eaecb2..0000000 --- a/fusion_claims/fusion_claims/report/sale_report_landscape.xml +++ /dev/null @@ -1,303 +0,0 @@ - - - - - diff --git a/fusion_claims/fusion_claims/report/sale_report_portrait.xml b/fusion_claims/fusion_claims/report/sale_report_portrait.xml deleted file mode 100644 index 287ce4f..0000000 --- a/fusion_claims/fusion_claims/report/sale_report_portrait.xml +++ /dev/null @@ -1,281 +0,0 @@ - - - - - - diff --git a/fusion_claims/fusion_claims/scripts/import_adp_mobility_manual.py b/fusion_claims/fusion_claims/scripts/import_adp_mobility_manual.py deleted file mode 100644 index 1ccefea..0000000 --- a/fusion_claims/fusion_claims/scripts/import_adp_mobility_manual.py +++ /dev/null @@ -1,196 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -ADP Mobility Manual CSV to JSON Converter - -This script reads the ADP Mobility Manual CSV file, cleans the data, -and outputs a JSON file that can be imported into Odoo's fusion.adp.device.code model. - -Usage: - python import_adp_mobility_manual.py input.csv output.json - -Or run without arguments to use default paths. - -Copyright 2024-2025 Nexa Systems Inc. -License OPL-1 (Odoo Proprietary License v1.0) -""" - -import csv -import json -import re -import sys -import os - - -def clean_text(text): - """Clean text from weird characters, normalize encoding.""" - if not text: - return '' - # Convert to string if not already - text = str(text) - # Replace curly quotes with straight quotes - text = text.replace('"', '"').replace('"', '"') - text = text.replace(''', "'").replace(''', "'") - # Replace various dashes with standard hyphen - text = text.replace('–', '-').replace('—', '-') - # Remove non-printable characters except newlines - text = ''.join(char if char.isprintable() or char in '\n\r\t' else ' ' for char in text) - # Normalize multiple spaces - text = re.sub(r'\s+', ' ', text) - # Strip leading/trailing whitespace - return text.strip() - - -def parse_price(price_str): - """Parse price string like '$64.00' or '$2,578.00' to float.""" - if not price_str: - return 0.0 - # Remove currency symbols, commas, spaces, quotes - price_str = str(price_str).strip() - price_str = re.sub(r'[\$,"\'\s]', '', price_str) - try: - return float(price_str) - except ValueError: - return 0.0 - - -def convert_csv_to_json(input_path, output_path): - """Convert ADP Mobility Manual CSV to JSON format.""" - data = [] - errors = [] - skipped = 0 - - # Try different encodings - encodings = ['utf-8-sig', 'utf-8', 'latin-1', 'cp1252'] - content = None - - for encoding in encodings: - try: - with open(input_path, 'r', encoding=encoding) as f: - content = f.read() - break - except UnicodeDecodeError: - continue - - if content is None: - print(f"Error: Could not read file with any known encoding") - return None - - # Parse CSV - reader = csv.DictReader(content.splitlines()) - - for idx, row in enumerate(reader, start=2): # Start at 2 (header is line 1) - try: - # Get device code - skip if empty - device_code = clean_text(row.get('Device Code', '')) - if not device_code: - skipped += 1 - continue - - # Get device type - device_type = clean_text(row.get('Device Type', '')) - if not device_type: - skipped += 1 - continue - - # Get manufacturer - manufacturer = clean_text(row.get('Manufacturer', '')) - - # Get device description - clean it - device_description = clean_text(row.get('Device Description', '')) - - # Parse quantity - qty_str = row.get('Qty', '1') or '1' - try: - quantity = int(qty_str) - except ValueError: - quantity = 1 - - # Parse price (handle both ' Approved Price ' with spaces and 'Approved Price') - price = 0.0 - for key in row.keys(): - if 'price' in key.lower() and 'approved' in key.lower(): - price = parse_price(row.get(key, '')) - break - - # Parse serial requirement - serial_str = clean_text(row.get('Serial', 'No')).upper() - sn_required = serial_str in ('YES', 'Y', 'TRUE', '1') - - data.append({ - 'Device Type': device_type, - 'Manufacturer': manufacturer, - 'Device Description': device_description, - 'Device Code': device_code, - 'Quantity': quantity, - 'ADP Price': price, - 'SN Required': 'Yes' if sn_required else 'No', - }) - - except Exception as e: - errors.append(f"Row {idx}: {str(e)}") - - # Write JSON output - with open(output_path, 'w', encoding='utf-8') as f: - json.dump(data, f, indent=2, ensure_ascii=False) - - # Print summary - print(f"\n{'='*60}") - print(f"ADP Mobility Manual Import Summary") - print(f"{'='*60}") - print(f"Input file: {input_path}") - print(f"Output file: {output_path}") - print(f"Records processed: {len(data)}") - print(f"Records skipped: {skipped}") - print(f"Errors: {len(errors)}") - - if errors: - print(f"\nFirst 10 errors:") - for err in errors[:10]: - print(f" - {err}") - - # Print device type summary - device_types = {} - for item in data: - dt = item['Device Type'] - device_types[dt] = device_types.get(dt, 0) + 1 - - print(f"\nDevice Types ({len(device_types)} unique):") - for dt in sorted(device_types.keys())[:20]: - print(f" - {dt}: {device_types[dt]} devices") - if len(device_types) > 20: - print(f" ... and {len(device_types) - 20} more") - - print(f"\n{'='*60}") - print(f"JSON file ready for import into Odoo!") - print(f"Use: Sales > Configuration > ADP Device Codes > Import") - print(f"{'='*60}\n") - - return data - - -def main(): - # Default paths - default_input = r"C:\Users\gur_p\Downloads\ADP-Mobility-Manual.csv" - default_output = r"C:\Users\gur_p\Downloads\ADP-Mobility-Manual-cleaned.json" - - if len(sys.argv) >= 3: - input_path = sys.argv[1] - output_path = sys.argv[2] - elif len(sys.argv) == 2: - input_path = sys.argv[1] - output_path = os.path.splitext(input_path)[0] + '-cleaned.json' - else: - input_path = default_input - output_path = default_output - - if not os.path.exists(input_path): - print(f"Error: Input file not found: {input_path}") - print(f"\nUsage: python {sys.argv[0]} input.csv [output.json]") - sys.exit(1) - - convert_csv_to_json(input_path, output_path) - - -if __name__ == '__main__': - main() diff --git a/fusion_claims/fusion_claims/security/ir.model.access.csv b/fusion_claims/fusion_claims/security/ir.model.access.csv deleted file mode 100644 index dfa3ce3..0000000 --- a/fusion_claims/fusion_claims/security/ir.model.access.csv +++ /dev/null @@ -1,75 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_fusion_claims_config_user,fusion.central.config.user,model_fusion_claims_config,base.group_user,1,1,1,1 -access_fusion_claims_export_wizard_user,fusion.central.export.wizard.user,model_fusion_claims_export_wizard,account.group_account_invoice,1,1,1,1 -access_fusion_claims_export_wizard_manager,fusion.central.export.wizard.manager,model_fusion_claims_export_wizard,account.group_account_manager,1,1,1,1 -access_fusion_adp_device_code_user,fusion.adp.device.code.user,model_fusion_adp_device_code,base.group_user,1,0,0,0 -access_fusion_adp_device_code_sales,fusion.adp.device.code.sales,model_fusion_adp_device_code,sales_team.group_sale_salesman,1,1,1,0 -access_fusion_adp_device_code_manager,fusion.adp.device.code.manager,model_fusion_adp_device_code,sales_team.group_sale_manager,1,1,1,1 -access_fusion_device_import_wizard,fusion.central.device.import.wizard,model_fusion_claims_device_import_wizard,sales_team.group_sale_manager,1,1,1,1 -access_fusion_device_approval_wizard,fusion.device.approval.wizard.user,model_fusion_claims_device_approval_wizard,sales_team.group_sale_salesman,1,1,1,1 -access_fusion_device_approval_wizard_line,fusion.device.approval.wizard.line.user,model_fusion_claims_device_approval_wizard_line,sales_team.group_sale_salesman,1,1,1,1 -access_fusion_submission_verification_wizard,fusion.submission.verification.wizard.user,model_fusion_claims_submission_verification_wizard,sales_team.group_sale_salesman,1,1,1,1 -access_fusion_submission_verification_wizard_line,fusion.submission.verification.wizard.line.user,model_fusion_claims_submission_verification_wizard_line,sales_team.group_sale_salesman,1,1,1,1 -access_fusion_status_change_reason_wizard,fusion.status.change.reason.wizard.user,model_fusion_status_change_reason_wizard,sales_team.group_sale_salesman,1,1,1,1 -access_fusion_case_close_verification_wizard,fusion.case.close.verification.wizard.user,model_fusion_claims_case_close_verification_wizard,sales_team.group_sale_salesman,1,1,1,1 -access_fusion_schedule_assessment_wizard,fusion.schedule.assessment.wizard.user,model_fusion_claims_schedule_assessment_wizard,sales_team.group_sale_salesman,1,1,1,1 -access_fusion_assessment_completed_wizard,fusion.assessment.completed.wizard.user,model_fusion_claims_assessment_completed_wizard,sales_team.group_sale_salesman,1,1,1,1 -access_fusion_application_received_wizard,fusion.application.received.wizard.user,model_fusion_claims_application_received_wizard,sales_team.group_sale_salesman,1,1,1,1 -access_fusion_ready_for_submission_wizard,fusion.ready.for.submission.wizard.user,model_fusion_claims_ready_for_submission_wizard,sales_team.group_sale_salesman,1,1,1,1 -access_fusion_ready_to_bill_wizard,fusion.ready.to.bill.wizard.user,model_fusion_claims_ready_to_bill_wizard,sales_team.group_sale_salesman,1,1,1,1 -access_fusion_submission_history_user,fusion.submission.history.user,model_fusion_submission_history,sales_team.group_sale_salesman,1,1,1,0 -access_fusion_submission_history_manager,fusion.submission.history.manager,model_fusion_submission_history,sales_team.group_sale_manager,1,1,1,1 -access_fusion_loaner_checkout_user,fusion.loaner.checkout.user,model_fusion_loaner_checkout,sales_team.group_sale_salesman,1,1,1,0 -access_fusion_loaner_checkout_manager,fusion.loaner.checkout.manager,model_fusion_loaner_checkout,sales_team.group_sale_manager,1,1,1,1 -access_fusion_loaner_history_user,fusion.loaner.history.user,model_fusion_loaner_history,sales_team.group_sale_salesman,1,0,0,0 -access_fusion_loaner_history_manager,fusion.loaner.history.manager,model_fusion_loaner_history,sales_team.group_sale_manager,1,1,1,1 -access_fusion_loaner_checkout_wizard,fusion.loaner.checkout.wizard.user,model_fusion_loaner_checkout_wizard,sales_team.group_sale_salesman,1,1,1,1 -access_fusion_loaner_return_wizard,fusion.loaner.return.wizard.user,model_fusion_loaner_return_wizard,sales_team.group_sale_salesman,1,1,1,1 -access_fusion_ready_for_delivery_wizard,fusion.ready.for.delivery.wizard.user,model_fusion_ready_for_delivery_wizard,sales_team.group_sale_salesman,1,1,1,1 -access_fusion_client_profile_user,fusion.client.profile.user,model_fusion_client_profile,sales_team.group_sale_salesman,1,1,1,0 -access_fusion_client_profile_manager,fusion.client.profile.manager,model_fusion_client_profile,sales_team.group_sale_manager,1,1,1,1 -access_fusion_adp_application_data_user,fusion.adp.application.data.user,model_fusion_adp_application_data,sales_team.group_sale_salesman,1,1,1,0 -access_fusion_adp_application_data_manager,fusion.adp.application.data.manager,model_fusion_adp_application_data,sales_team.group_sale_manager,1,1,1,1 -access_fusion_client_chat_session_user,fusion.client.chat.session.user,model_fusion_client_chat_session,sales_team.group_sale_salesman,1,1,1,0 -access_fusion_client_chat_session_manager,fusion.client.chat.session.manager,model_fusion_client_chat_session,sales_team.group_sale_manager,1,1,1,1 -access_fusion_client_chat_message_user,fusion.client.chat.message.user,model_fusion_client_chat_message,sales_team.group_sale_salesman,1,1,1,0 -access_fusion_client_chat_message_manager,fusion.client.chat.message.manager,model_fusion_client_chat_message,sales_team.group_sale_manager,1,1,1,1 -access_fusion_xml_import_wizard,fusion.xml.import.wizard.user,model_fusion_xml_import_wizard,sales_team.group_sale_manager,1,1,1,1 -access_fusion_claims_dashboard_user,fusion.claims.dashboard.user,model_fusion_claims_dashboard,sales_team.group_sale_salesman,1,1,1,1 -access_fusion_technician_task_user,fusion.technician.task.user,model_fusion_technician_task,sales_team.group_sale_salesman,1,1,1,0 -access_fusion_technician_task_manager,fusion.technician.task.manager,model_fusion_technician_task,sales_team.group_sale_manager,1,1,1,1 -access_fusion_technician_task_technician,fusion.technician.task.technician,model_fusion_technician_task,fusion_claims.group_field_technician,1,1,0,0 -access_fusion_technician_task_portal,fusion.technician.task.portal,model_fusion_technician_task,base.group_portal,1,0,0,0 -access_fusion_push_subscription_user,fusion.push.subscription.user,model_fusion_push_subscription,base.group_user,1,1,1,0 -access_fusion_push_subscription_portal,fusion.push.subscription.portal,model_fusion_push_subscription,base.group_portal,1,1,1,0 -access_fusion_technician_location_manager,fusion.technician.location.manager,model_fusion_technician_location,sales_team.group_sale_manager,1,1,1,1 -access_fusion_technician_location_user,fusion.technician.location.user,model_fusion_technician_location,sales_team.group_sale_salesman,1,0,0,0 -access_fusion_technician_location_portal,fusion.technician.location.portal,model_fusion_technician_location,base.group_portal,0,0,1,0 -access_fusion_send_to_mod_wizard_user,fusion_claims.send.to.mod.wizard.user,model_fusion_claims_send_to_mod_wizard,sales_team.group_sale_salesman,1,1,1,0 -access_fusion_send_to_mod_wizard_manager,fusion_claims.send.to.mod.wizard.manager,model_fusion_claims_send_to_mod_wizard,sales_team.group_sale_manager,1,1,1,1 -access_fusion_mod_awaiting_wizard_user,fusion_claims.mod.awaiting.funding.wizard.user,model_fusion_claims_mod_awaiting_funding_wizard,sales_team.group_sale_salesman,1,1,1,0 -access_fusion_mod_awaiting_wizard_manager,fusion_claims.mod.awaiting.funding.wizard.manager,model_fusion_claims_mod_awaiting_funding_wizard,sales_team.group_sale_manager,1,1,1,1 -access_fusion_mod_approved_wizard_user,fusion_claims.mod.funding.approved.wizard.user,model_fusion_claims_mod_funding_approved_wizard,sales_team.group_sale_salesman,1,1,1,0 -access_fusion_mod_approved_wizard_manager,fusion_claims.mod.funding.approved.wizard.manager,model_fusion_claims_mod_funding_approved_wizard,sales_team.group_sale_manager,1,1,1,1 -access_fusion_mod_approved_line_user,fusion_claims.mod.funding.approved.wizard.line.user,model_fusion_claims_mod_funding_approved_wizard_line,sales_team.group_sale_salesman,1,1,1,0 -access_fusion_mod_approved_line_manager,fusion_claims.mod.funding.approved.wizard.line.manager,model_fusion_claims_mod_funding_approved_wizard_line,sales_team.group_sale_manager,1,1,1,1 -access_fusion_mod_pca_wizard_user,fusion_claims.mod.pca.received.wizard.user,model_fusion_claims_mod_pca_received_wizard,sales_team.group_sale_salesman,1,1,1,0 -access_fusion_mod_pca_wizard_manager,fusion_claims.mod.pca.received.wizard.manager,model_fusion_claims_mod_pca_received_wizard,sales_team.group_sale_manager,1,1,1,1 -access_fusion_sa_mobility_wizard_user,fusion_claims.sa.mobility.wizard.user,model_fusion_claims_sa_mobility_wizard,sales_team.group_sale_salesman,1,1,1,0 -access_fusion_sa_mobility_wizard_manager,fusion_claims.sa.mobility.wizard.manager,model_fusion_claims_sa_mobility_wizard,sales_team.group_sale_manager,1,1,1,1 -access_fusion_sa_mobility_part_line_user,fusion_claims.sa.mobility.part.line.user,model_fusion_claims_sa_mobility_part_line,sales_team.group_sale_salesman,1,1,1,0 -access_fusion_sa_mobility_part_line_manager,fusion_claims.sa.mobility.part.line.manager,model_fusion_claims_sa_mobility_part_line,sales_team.group_sale_manager,1,1,1,1 -access_fusion_sa_mobility_labour_line_user,fusion_claims.sa.mobility.labour.line.user,model_fusion_claims_sa_mobility_labour_line,sales_team.group_sale_salesman,1,1,1,0 -access_fusion_sa_mobility_labour_line_manager,fusion_claims.sa.mobility.labour.line.manager,model_fusion_claims_sa_mobility_labour_line,sales_team.group_sale_manager,1,1,1,1 -access_fusion_sa_mobility_fee_line_user,fusion_claims.sa.mobility.fee.line.user,model_fusion_claims_sa_mobility_fee_line,sales_team.group_sale_salesman,1,1,1,0 -access_fusion_sa_mobility_fee_line_manager,fusion_claims.sa.mobility.fee.line.manager,model_fusion_claims_sa_mobility_fee_line,sales_team.group_sale_manager,1,1,1,1 -access_fusion_discretionary_wizard_user,fusion_claims.discretionary.benefit.wizard.user,model_fusion_claims_discretionary_benefit_wizard,sales_team.group_sale_salesman,1,1,1,0 -access_fusion_discretionary_wizard_manager,fusion_claims.discretionary.benefit.wizard.manager,model_fusion_claims_discretionary_benefit_wizard,sales_team.group_sale_manager,1,1,1,1 -access_fusion_odsp_pre_approved_wizard_user,fusion_claims.odsp.pre.approved.wizard.user,model_fusion_claims_odsp_pre_approved_wizard,sales_team.group_sale_salesman,1,1,1,0 -access_fusion_odsp_pre_approved_wizard_manager,fusion_claims.odsp.pre.approved.wizard.manager,model_fusion_claims_odsp_pre_approved_wizard,sales_team.group_sale_manager,1,1,1,1 -access_fusion_odsp_ready_delivery_wizard_user,fusion_claims.odsp.ready.delivery.wizard.user,model_fusion_claims_odsp_ready_delivery_wizard,sales_team.group_sale_salesman,1,1,1,0 -access_fusion_odsp_ready_delivery_wizard_manager,fusion_claims.odsp.ready.delivery.wizard.manager,model_fusion_claims_odsp_ready_delivery_wizard,sales_team.group_sale_manager,1,1,1,1 -access_fusion_submit_to_odsp_wizard_user,fusion_claims.submit.to.odsp.wizard.user,model_fusion_claims_submit_to_odsp_wizard,sales_team.group_sale_salesman,1,1,1,0 -access_fusion_submit_to_odsp_wizard_manager,fusion_claims.submit.to.odsp.wizard.manager,model_fusion_claims_submit_to_odsp_wizard,sales_team.group_sale_manager,1,1,1,1 -access_fusion_task_sync_config_manager,fusion.task.sync.config.manager,model_fusion_task_sync_config,sales_team.group_sale_manager,1,1,1,1 -access_fusion_task_sync_config_user,fusion.task.sync.config.user,model_fusion_task_sync_config,sales_team.group_sale_salesman,1,0,0,0 \ No newline at end of file diff --git a/fusion_claims/fusion_claims/security/security.xml b/fusion_claims/fusion_claims/security/security.xml deleted file mode 100644 index 7fa88b8..0000000 --- a/fusion_claims/fusion_claims/security/security.xml +++ /dev/null @@ -1,141 +0,0 @@ - - - - - - - - - Fusion Claims - 45 - - - - - - - - - Fusion Claims - 45 - - - - - - - - - - User - 10 - - - - - - - - - Administrator - 20 - - - - - - - - - - - Document Lock Override - - Can edit locked documents on old/legacy cases when the override setting is enabled. Assign only to specific trusted users. - - - - - - - - - - - Field Technician - - - - - - - - - - Technician Task: Manager Full Access - - [(1, '=', 1)] - - - - - - - - - - Technician Task: Sales User Access - - [(1, '=', 1)] - - - - - - - - - - Technician Task: Technician Own Tasks - - [('technician_id', '=', user.id)] - - - - - - - - - - Technician Task: Portal Technician Access - - [('technician_id', '=', user.id)] - - - - - - - - - - - - - - Push Subscription: Own Only - - [('user_id', '=', user.id)] - - - - - - Push Subscription: Portal Own Only - - [('user_id', '=', user.id)] - - - - diff --git a/fusion_claims/fusion_claims/static/description/icon.png b/fusion_claims/fusion_claims/static/description/icon.png deleted file mode 100644 index adb75fa9630b10a7644394e33b22760d8072e507..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46059 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 diff --git a/fusion_claims/fusion_claims/static/img/nexa_favicon.png b/fusion_claims/fusion_claims/static/img/nexa_favicon.png deleted file mode 100644 index 9633b4139973d8ff2843694c4c87682c9bf3a3a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12784 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%0A?k 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 diff --git a/fusion_claims/fusion_claims/static/src/css/fusion_task_map_view.scss b/fusion_claims/fusion_claims/static/src/css/fusion_task_map_view.scss deleted file mode 100644 index 5b7318b..0000000 --- a/fusion_claims/fusion_claims/static/src/css/fusion_task_map_view.scss +++ /dev/null @@ -1,386 +0,0 @@ -// ===================================================================== -// Fusion Task Map View - Sidebar + Google Maps -// Theme-aware: uses Odoo/Bootstrap variables for dark mode support -// ===================================================================== - -$sidebar-width: 340px; -$transition-speed: .25s; - -.o_fusion_task_map_view { - height: 100%; - - .o_content { - height: 100%; - display: flex; - flex-direction: column; - } -} - -// ── Main wrapper: sidebar + map side by side ──────────────────────── -.fc_map_wrapper { - display: flex; - flex-direction: row; - height: 100%; - min-height: 0; - overflow: hidden; - position: relative; -} - -// ── Sidebar ───────────────────────────────────────────────────────── -.fc_sidebar { - width: $sidebar-width; - min-width: $sidebar-width; - max-width: $sidebar-width; - background: var(--o-view-background-color, $o-view-background-color); - border-right: 1px solid $border-color; - display: flex; - flex-direction: column; - transition: width $transition-speed ease, min-width $transition-speed ease, - max-width $transition-speed ease, opacity $transition-speed ease; - overflow: hidden; - - &--collapsed { - width: 0; - min-width: 0; - max-width: 0; - opacity: 0; - border-right: none; - } -} - -.fc_sidebar_header { - padding: 14px 16px 12px; - border-bottom: 1px solid $border-color; - flex-shrink: 0; - - h6 { - font-size: 14px; - color: $headings-color; - } -} - -.fc_sidebar_body { - flex: 1 1 auto; - overflow-y: auto; - overflow-x: hidden; - padding: 6px 0; - - &::-webkit-scrollbar { width: 5px; } - &::-webkit-scrollbar-track { background: transparent; } - &::-webkit-scrollbar-thumb { background: $border-color; border-radius: 4px; } -} - -.fc_sidebar_footer { - padding: 10px 16px; - border-top: 1px solid $border-color; - flex-shrink: 0; -} - -.fc_sidebar_empty { - text-align: center; - padding: 40px 20px; - color: $text-muted; -} - -// ── Day filter chips ──────────────────────────────────────────────── -.fc_day_filters { - display: flex; - flex-wrap: wrap; - gap: 4px; -} - -.fc_day_chip { - display: inline-flex; - align-items: center; - gap: 4px; - padding: 2px 10px; - font-size: 11px; - font-weight: 600; - border: 1px solid $border-color; - border-radius: 12px; - background: transparent; - color: $text-muted; - cursor: pointer; - transition: all .15s; - line-height: 18px; - - &:hover { - border-color: rgba($primary, .3); - color: $body-color; - } - - &--active { - color: #fff !important; - border-color: transparent !important; - } - - &--all { - color: $body-color; - font-weight: 500; - &:hover { background: rgba($primary, .1); } - } -} - -.fc_day_chip_count { - font-size: 10px; - opacity: .8; -} - -.fc_group_hidden_tag { - font-size: 9px; - text-transform: uppercase; - letter-spacing: .5px; - color: $text-muted; - background: rgba($secondary, .1); - padding: 0 5px; - border-radius: 3px; - margin-left: 4px; - font-weight: 500; -} - -// Collapsed toggle button (floating) -.fc_sidebar_toggle_btn { - position: absolute; - left: 0; - top: 50%; - transform: translateY(-50%); - z-index: 15; - background: var(--o-view-background-color, $o-view-background-color); - border: 1px solid $border-color; - border-left: none; - border-radius: 0 8px 8px 0; - padding: 12px 6px; - cursor: pointer; - box-shadow: 2px 0 6px rgba(0,0,0,.08); - color: $text-muted; - transition: background .15s; - - &:hover { - background: $o-gray-100; - color: $body-color; - } -} - -// ── Group headers ─────────────────────────────────────────────────── -.fc_group_header { - display: flex; - align-items: center; - padding: 8px 16px; - cursor: pointer; - user-select: none; - font-weight: 600; - font-size: 12px; - color: $text-muted; - text-transform: uppercase; - letter-spacing: .5px; - background: rgba($secondary, .08); - border-bottom: 1px solid $border-color; - transition: background .15s; - - &:hover { - background: rgba($secondary, .15); - } - - .fa-caret-right, - .fa-caret-down { - width: 14px; - text-align: center; - font-size: 13px; - } -} - -.fc_group_label { - flex: 1; -} - -.fc_group_badge { - background: rgba($secondary, .2); - color: $body-color; - font-size: 10px; - font-weight: 700; - padding: 1px 7px; - border-radius: 10px; - min-width: 20px; - text-align: center; -} - -// ── Task cards ────────────────────────────────────────────────────── -.fc_group_tasks { - padding: 4px 0; -} - -.fc_task_card { - margin: 3px 10px; - padding: 10px 12px; - background: var(--o-view-background-color, $o-view-background-color); - border: 1px solid $border-color; - border-radius: 8px; - cursor: pointer; - transition: all .15s; - position: relative; - - &:hover { - background: rgba($primary, .05); - border-color: rgba($primary, .2); - box-shadow: 0 1px 4px rgba(0,0,0,.06); - } - - &--active { - background: rgba($primary, .1) !important; - border-color: rgba($primary, .35) !important; - box-shadow: 0 0 0 2px rgba($primary, .15); - } -} - -.fc_task_card_top { - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: 6px; -} - -.fc_task_num { - display: inline-block; - color: #fff; - font-size: 11px; - font-weight: 700; - padding: 1px 8px; - border-radius: 4px; - line-height: 18px; -} - -.fc_task_status { - font-size: 11px; - font-weight: 600; -} - -.fc_task_client { - font-size: 13px; - font-weight: 600; - color: $headings-color; - margin-bottom: 4px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.fc_task_meta { - display: flex; - gap: 12px; - font-size: 11px; - color: $body-color; - margin-bottom: 3px; - - .fa { opacity: .5; } -} - -.fc_task_detail { - font-size: 11px; - color: $body-color; - margin-bottom: 2px; - .fa { opacity: .5; } -} - -.fc_task_address { - font-size: 10px; - color: $text-muted; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - margin-top: 2px; -} - -.fc_task_bottom_row { - display: flex; - align-items: center; - gap: 6px; - margin-top: 4px; - flex-wrap: wrap; -} - -.fc_task_travel { - display: inline-flex; - align-items: center; - font-size: 10px; - color: $body-color; - background: rgba($secondary, .1); - padding: 1px 8px; - border-radius: 4px; - .fa { opacity: .5; } -} - -.fc_task_source { - display: inline-flex; - align-items: center; - font-size: 10px; - color: #fff; - font-weight: 600; - padding: 1px 8px; - border-radius: 4px; - .fa { opacity: .8; } -} - -// ── Map area ──────────────────────────────────────────────────────── -.fc_map_area { - flex: 1 1 auto; - display: flex; - flex-direction: column; - min-width: 0; - position: relative; -} - -.fc_map_legend_bar { - flex: 0 0 auto; - font-size: 12px; - min-height: 40px; -} - -.fc_map_container { - flex: 1 1 auto; - position: relative; - min-height: 400px; -} - -// ── Google Maps InfoWindow override (always light bg) ─────────────── -// InfoWindow is rendered by Google outside our DOM; we style via -// the .gm-style-iw container that Google injects. -.gm-style-iw-d { - overflow: auto !important; -} -.gm-style .gm-style-iw-c { - padding: 0 !important; - border-radius: 10px !important; -} - -// ── Responsive ────────────────────────────────────────────────────── -@media (max-width: 768px) { - .fc_map_wrapper { - flex-direction: column; - } - .fc_sidebar { - width: 100% !important; - min-width: 100% !important; - max-width: 100% !important; - max-height: 40vh; - border-right: none; - border-bottom: 1px solid $border-color; - - &--collapsed { - max-height: 0; - opacity: 0; - } - } - .fc_sidebar_toggle_btn { - top: auto; - bottom: 10px; - left: 50%; - transform: translateX(-50%); - border-radius: 8px; - border: 1px solid $border-color; - padding: 8px 16px; - } - .fc_map_area { - flex: 1; - min-height: 300px; - } -} diff --git a/fusion_claims/fusion_claims/static/src/js/attachment_image_compress.js b/fusion_claims/fusion_claims/static/src/js/attachment_image_compress.js deleted file mode 100644 index 8bdd92d..0000000 --- a/fusion_claims/fusion_claims/static/src/js/attachment_image_compress.js +++ /dev/null @@ -1,192 +0,0 @@ -/** @odoo-module **/ -/** - * Image compression for file uploads on Odoo. - * - * Problem: On iPhone, selecting 4+ photos (5-15MB each) causes the - * browser tab to crash because Odoo converts each to a base64 data URL - * before uploading. 7 photos = 50-100MB of strings in memory. - * - * Solution: Intercept at the FileUploader level, compress each image - * via Canvas BEFORE the data URL conversion. A 5MB photo becomes ~300KB. - * - * The FileUploader.onFileChange is completely overridden (not wrapped) - * to avoid any DataTransfer API issues on iPhone Safari. - */ -import { AttachmentUploadService } from "@mail/core/common/attachment_upload_service"; -import { FileUploader } from "@web/views/fields/file_handler"; -import { patch } from "@web/core/utils/patch"; -import { getDataURLFromFile } from "@web/core/utils/urls"; -import { checkFileSize } from "@web/core/utils/files"; - -const IMAGE_TYPES = new Set([ - "image/jpeg", "image/png", "image/webp", "image/bmp", - "image/heic", "image/heif", -]); -const MAX_DIMENSION = 1280; // Conservative for mobile memory -const JPEG_QUALITY = 0.80; -const SKIP_THRESHOLD = 500 * 1024; // 500KB - -/** - * Compress an image File via Canvas API. - * Returns the original file if anything fails. - */ -function compressImageFile(file) { - return new Promise((resolve) => { - try { - const img = new Image(); - const objectUrl = URL.createObjectURL(file); - const cleanup = () => { - try { URL.revokeObjectURL(objectUrl); } catch(e) {} - try { img.src = ""; } catch(e) {} - }; - const timeout = setTimeout(() => { - cleanup(); - resolve(file); // Timeout fallback after 10s - }, 10000); - img.onload = () => { - try { - clearTimeout(timeout); - let w = img.naturalWidth || img.width; - let h = img.naturalHeight || img.height; - if (w > MAX_DIMENSION || h > MAX_DIMENSION) { - const ratio = Math.min(MAX_DIMENSION / w, MAX_DIMENSION / h); - w = Math.round(w * ratio); - h = Math.round(h * ratio); - } - const canvas = document.createElement("canvas"); - canvas.width = w; - canvas.height = h; - canvas.getContext("2d").drawImage(img, 0, 0, w, h); - canvas.toBlob( - (blob) => { - cleanup(); - canvas.width = 0; - canvas.height = 0; - if (!blob) { resolve(file); return; } - const name = file.name.replace(/\.[^.]+$/, "") + ".jpg"; - resolve(new File([blob], name, { - type: "image/jpeg", - lastModified: file.lastModified, - })); - }, - "image/jpeg", - JPEG_QUALITY - ); - } catch (e) { - clearTimeout(timeout); - cleanup(); - resolve(file); - } - }; - img.onerror = () => { - clearTimeout(timeout); - cleanup(); - resolve(file); - }; - img.src = objectUrl; - } catch (e) { - resolve(file); - } - }); -} - -/** - * Override FileUploader.onFileChange to compress images before - * converting to data URLs. This prevents the massive memory spike - * that crashes mobile browsers. - * - * We re-implement onFileChange instead of wrapping it to avoid - * DataTransfer API issues on iPhone Safari. - */ -patch(FileUploader.prototype, { - async onFileChange(ev) { - const rawFiles = ev.target?.files; - if (!rawFiles || !rawFiles.length) { - return; - } - - // Check if any file needs compression - let hasLargeImages = false; - for (const f of rawFiles) { - if (IMAGE_TYPES.has(f.type) && f.size > SKIP_THRESHOLD) { - hasLargeImages = true; - break; - } - } - - // No large images -- use standard Odoo behavior - if (!hasLargeImages) { - return super.onFileChange(ev); - } - - // Process files one at a time with compression - const files = [...rawFiles].filter((f) => this.validFileType(f)); - const target = ev.target; - - for (const file of files) { - let processedFile = file; - - // Compress large images - if (IMAGE_TYPES.has(file.type) && file.size > SKIP_THRESHOLD) { - try { - processedFile = await compressImageFile(file); - } catch (e) { - processedFile = file; // fallback to original - } - } - - // Size check - if (this.props.checkSize && !checkFileSize(processedFile.size, this.notification)) { - continue; - } - - this.state.isUploading = true; - try { - const data = await getDataURLFromFile(processedFile); - if (!processedFile.size) { - this.notification.add( - `There was a problem while uploading: ${processedFile.name}`, - { type: "danger" } - ); - continue; - } - await this.props.onUploaded({ - name: processedFile.name, - size: processedFile.size, - type: processedFile.type, - data: data.split(",")[1], - objectUrl: - processedFile.type === "application/pdf" - ? URL.createObjectURL(processedFile) - : null, - }); - } catch (e) { - // Skip this file on error, continue with others - } finally { - this.state.isUploading = false; - } - } - - // Reset input so same file can be re-selected - target.value = null; - if (this.props.multiUpload && this.props.onUploadComplete) { - this.props.onUploadComplete({}); - } - }, -}); - -/** - * Safety net for drag-drop and paste uploads that bypass FileUploader. - */ -patch(AttachmentUploadService.prototype, { - async upload(thread, composer, file, options) { - if (file && IMAGE_TYPES.has(file.type) && file.size > SKIP_THRESHOLD) { - try { - file = await compressImageFile(file); - } catch (e) { - // Use original file - } - } - return super.upload(thread, composer, file, options); - }, -}); diff --git a/fusion_claims/fusion_claims/static/src/js/calendar_store_hours.js b/fusion_claims/fusion_claims/static/src/js/calendar_store_hours.js deleted file mode 100644 index 5efae5d..0000000 --- a/fusion_claims/fusion_claims/static/src/js/calendar_store_hours.js +++ /dev/null @@ -1,22 +0,0 @@ -/** @odoo-module **/ -// Fusion Claims - Calendar Store Hours Restriction -// Copyright 2024-2026 Nexa Systems Inc. -// License OPL-1 -// -// Restricts the technician task calendar view to only show store hours. -// Default: 9:00 AM - 6:00 PM (configurable in Settings). - -import { patch } from "@web/core/utils/patch"; -import { CalendarRenderer } from "@web/views/calendar/calendar_renderer"; - -patch(CalendarRenderer.prototype, { - get fcOptions() { - const options = super.fcOptions; - // Only restrict hours for the technician task calendar - if (this.props.model?.resModel === "fusion.technician.task") { - options.slotMinTime = "08:00:00"; - options.slotMaxTime = "19:00:00"; - } - return options; - }, -}); diff --git a/fusion_claims/fusion_claims/static/src/js/chatter_resize.js b/fusion_claims/fusion_claims/static/src/js/chatter_resize.js deleted file mode 100644 index 8660ec2..0000000 --- a/fusion_claims/fusion_claims/static/src/js/chatter_resize.js +++ /dev/null @@ -1,40 +0,0 @@ -/** @odoo-module **/ -// Fusion Claims - Chatter Topbar Tooltips -// Copyright 2024-2026 Nexa Systems Inc. -// License OPL-1 -// -// Adds title (tooltip) attributes to chatter topbar buttons that have -// their text hidden via CSS (icon-only mode). - -const TOOLTIPS = { - '.o-mail-Chatter-sendMessage': 'Send Message', - '.o-mail-Chatter-logNote': 'Log Note', - 'button[data-hotkey="shift+w"]': 'WhatsApp', - '.o-mail-Chatter-activity': 'Schedule Activity', - '.fusion-notes-mic-btn': 'Record Voice Note', - '.o-mail-Chatter-messageAuthorizer': 'Message Authorizer', -}; - -function applyTooltips() { - for (const [selector, title] of Object.entries(TOOLTIPS)) { - for (const btn of document.querySelectorAll(selector)) { - if (!btn.getAttribute('title')) { - btn.setAttribute('title', title); - } - } - } -} - -// Run on DOM changes (OWL re-renders) -const observer = new MutationObserver(() => applyTooltips()); - -// Start observing once DOM is ready -if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', () => { - observer.observe(document.body, { childList: true, subtree: true }); - applyTooltips(); - }); -} else { - observer.observe(document.body, { childList: true, subtree: true }); - applyTooltips(); -} diff --git a/fusion_claims/fusion_claims/static/src/js/document_preview.js b/fusion_claims/fusion_claims/static/src/js/document_preview.js deleted file mode 100644 index e6f5bf8..0000000 --- a/fusion_claims/fusion_claims/static/src/js/document_preview.js +++ /dev/null @@ -1,296 +0,0 @@ -/** @odoo-module **/ -// Fusion Claims - Document Preview (PDF and XML) -// Copyright 2024-2025 Nexa Systems Inc. -// License OPL-1 - -import { registry } from "@web/core/registry"; -import { _t } from "@web/core/l10n/translation"; -import { Component, useState, onMounted } from "@odoo/owl"; -import { Dialog } from "@web/core/dialog/dialog"; -import { useService } from "@web/core/utils/hooks"; - -/** - * PDF Document Preview Dialog Component - * Uses Odoo's built-in PDF.js viewer for XFA/protected PDF support - */ -export class DocumentPreviewDialog extends Component { - static template = "fusion_claims.DocumentPreviewDialog"; - static components = { Dialog }; - - setup() { - this.state = useState({ - isLoading: true, - isMaximized: false - }); - } - - getViewerUrl() { - const pdfUrl = `/web/content/${this.props.attachmentId}`; - const encodedUrl = encodeURIComponent(pdfUrl); - return `/web/static/lib/pdfjs/web/viewer.html?file=${encodedUrl}#pagemode=none`; - } - - onIframeLoad() { - this.state.isLoading = false; - } - - toggleMaximize() { - this.state.isMaximized = !this.state.isMaximized; - } - - getDialogSize() { - return this.state.isMaximized ? 'fullscreen' : 'xl'; - } - - getFrameStyle() { - return this.state.isMaximized - ? 'height: calc(98vh - 100px); width: 100%;' - : 'height: calc(85vh - 100px); width: 100%;'; - } -} - -/** - * XML Viewer Dialog Component - * Displays XML content with syntax highlighting - */ -export class XMLViewerDialog extends Component { - static template = "fusion_claims.XMLViewerDialog"; - static components = { Dialog }; - - setup() { - this.state = useState({ - isLoading: true, - isMaximized: false, - xmlContent: '', - formattedXml: '', - error: null - }); - this.notification = useService("notification"); - - onMounted(async () => { - await this.loadXmlContent(); - }); - } - - async loadXmlContent() { - try { - const response = await fetch(`/web/content/${this.props.attachmentId}`); - if (!response.ok) { - throw new Error('Failed to load XML file'); - } - const xmlText = await response.text(); - this.state.xmlContent = xmlText; - this.state.formattedXml = this.formatXml(xmlText); - this.state.isLoading = false; - } catch (error) { - this.state.error = error.message; - this.state.isLoading = false; - } - } - - formatXml(xml) { - // Format XML with indentation and syntax highlighting - let formatted = ''; - let indent = 0; - const tab = ' '; - - // Split by tags - xml = xml.replace(/>\s*<'); - const nodes = xml.split(/(<[^>]+>)/g).filter(n => n.trim()); - - for (const node of nodes) { - if (node.startsWith('')) { - // Self-closing tag - formatted += tab.repeat(indent) + this.highlightXml(node) + '\n'; - } else if (node.startsWith('<')) { - // Opening tag - formatted += tab.repeat(indent) + this.highlightXml(node) + '\n'; - indent++; - } else { - // Text content - const trimmed = node.trim(); - if (trimmed) { - formatted += tab.repeat(indent) + this.escapeHtml(trimmed) + '\n'; - } - } - } - - return formatted; - } - - highlightXml(str) { - // Escape HTML first - str = this.escapeHtml(str); - - // Highlight tag names - str = str.replace(/<(\/?)([\w:-]+)/g, - '<$1$2'); - - // Highlight attributes - str = str.replace(/([\w:-]+)=("[^&]*")/g, - '$1=$2'); - - return str; - } - - escapeHtml(str) { - return str - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"'); - } - - toggleMaximize() { - this.state.isMaximized = !this.state.isMaximized; - } - - getDialogSize() { - return this.state.isMaximized ? 'fullscreen' : 'xl'; - } - - async copyToClipboard() { - try { - await navigator.clipboard.writeText(this.state.xmlContent); - this.notification.add(_t("XML copied to clipboard"), { type: 'success' }); - } catch (error) { - this.notification.add(_t("Failed to copy to clipboard"), { type: 'warning' }); - } - } - - downloadXml() { - window.open(`/web/content/${this.props.attachmentId}?download=true`, '_blank'); - } -} - -/** - * Client action to preview a PDF document - */ -async function previewDocumentAction(env, action) { - const attachmentId = action.params?.attachment_id; - const title = action.params?.title || "Document Preview"; - - if (!attachmentId) { - env.services.notification.add( - _t("No document has been uploaded yet."), - { type: 'warning', title: _t("No Document") } - ); - return; - } - - env.services.dialog.add(DocumentPreviewDialog, { - attachmentId: attachmentId, - title: title - }); -} - -/** - * Client action to preview an XML document - */ -async function previewXmlAction(env, action) { - const attachmentId = action.params?.attachment_id; - const title = action.params?.title || "XML Viewer"; - - if (!attachmentId) { - env.services.notification.add( - _t("No XML file has been uploaded yet."), - { type: 'warning', title: _t("No Document") } - ); - return; - } - - env.services.dialog.add(XMLViewerDialog, { - attachmentId: attachmentId, - title: title - }); -} - -// Register client actions -registry.category("actions").add("fusion_claims.preview_document", previewDocumentAction); -registry.category("actions").add("fusion_claims.preview_xml", previewXmlAction); - -/** - * Image Preview Dialog Component - * Full-screen image preview with navigation - */ -export class ImagePreviewDialog extends Component { - static template = "fusion_claims.ImagePreviewDialog"; - static components = { Dialog }; - - setup() { - this.state = useState({ - currentIndex: this.props.initialIndex || 0, - isLoading: true - }); - } - - get currentImage() { - return this.props.images[this.state.currentIndex]; - } - - get imageUrl() { - return `/web/image/${this.currentImage.id}`; - } - - get hasMultiple() { - return this.props.images.length > 1; - } - - get currentPosition() { - return `${this.state.currentIndex + 1} / ${this.props.images.length}`; - } - - onImageLoad() { - this.state.isLoading = false; - } - - previousImage() { - if (this.state.currentIndex > 0) { - this.state.isLoading = true; - this.state.currentIndex--; - } - } - - nextImage() { - if (this.state.currentIndex < this.props.images.length - 1) { - this.state.isLoading = true; - this.state.currentIndex++; - } - } - - downloadImage() { - window.open(`/web/content/${this.currentImage.id}?download=true`, '_blank'); - } -} - -/** - * Client action to preview images - */ -async function previewImageAction(env, action) { - const images = action.params?.images || []; - const initialIndex = action.params?.initial_index || 0; - const title = action.params?.title || "Image Preview"; - - if (!images.length) { - env.services.notification.add( - _t("No images available."), - { type: 'warning', title: _t("No Images") } - ); - return; - } - - env.services.dialog.add(ImagePreviewDialog, { - images: images, - initialIndex: initialIndex, - title: title - }); -} - -registry.category("actions").add("fusion_claims.preview_image", previewImageAction); diff --git a/fusion_claims/fusion_claims/static/src/js/fusion_task_map_view.js b/fusion_claims/fusion_claims/static/src/js/fusion_task_map_view.js deleted file mode 100644 index c131766..0000000 --- a/fusion_claims/fusion_claims/static/src/js/fusion_task_map_view.js +++ /dev/null @@ -1,678 +0,0 @@ -/** @odoo-module **/ -// Fusion Claims - Google Maps Task View with Sidebar -// Copyright 2024-2026 Nexa Systems Inc. -// License OPL-1 - -import { registry } from "@web/core/registry"; -import { standardViewProps } from "@web/views/standard_view_props"; -import { useService } from "@web/core/utils/hooks"; -import { useModelWithSampleData } from "@web/model/model"; -import { useSetupAction } from "@web/search/action_hook"; -import { usePager } from "@web/search/pager_hook"; -import { useSearchBarToggler } from "@web/search/search_bar/search_bar_toggler"; -import { RelationalModel } from "@web/model/relational_model/relational_model"; -import { Layout } from "@web/search/layout"; -import { SearchBar } from "@web/search/search_bar/search_bar"; -import { CogMenu } from "@web/search/cog_menu/cog_menu"; -import { _t } from "@web/core/l10n/translation"; -import { - Component, - onMounted, - onPatched, - onWillUnmount, - useRef, - useState, -} from "@odoo/owl"; - -// ── Constants ─────────────────────────────────────────────────────── -const STATUS_COLORS = { - scheduled: "#3b82f6", - en_route: "#f59e0b", - in_progress: "#8b5cf6", - completed: "#10b981", - cancelled: "#ef4444", - rescheduled: "#f97316", -}; -const STATUS_LABELS = { - scheduled: "Scheduled", - en_route: "En Route", - in_progress: "In Progress", - completed: "Completed", - cancelled: "Cancelled", - rescheduled: "Rescheduled", -}; -const STATUS_ICONS = { - scheduled: "fa-clock-o", - en_route: "fa-truck", - in_progress: "fa-wrench", - completed: "fa-check-circle", - cancelled: "fa-times-circle", - rescheduled: "fa-calendar", -}; - -// Date group keys -const GROUP_YESTERDAY = "yesterday"; -const GROUP_TODAY = "today"; -const GROUP_TOMORROW = "tomorrow"; -const GROUP_THIS_WEEK = "this_week"; -const GROUP_LATER = "later"; -const GROUP_LABELS = { - [GROUP_YESTERDAY]: "Yesterday", - [GROUP_TODAY]: "Today", - [GROUP_TOMORROW]: "Tomorrow", - [GROUP_THIS_WEEK]: "This Week", - [GROUP_LATER]: "Upcoming", -}; - -// Pin colours by day group -const DAY_COLORS = { - [GROUP_YESTERDAY]: "#9ca3af", // Gray - [GROUP_TODAY]: "#ef4444", // Red - [GROUP_TOMORROW]: "#3b82f6", // Blue - [GROUP_THIS_WEEK]: "#10b981", // Green - [GROUP_LATER]: "#a855f7", // Purple -}; -const DAY_ICONS = { - [GROUP_YESTERDAY]: "fa-history", - [GROUP_TODAY]: "fa-exclamation-circle", - [GROUP_TOMORROW]: "fa-arrow-right", - [GROUP_THIS_WEEK]: "fa-calendar", - [GROUP_LATER]: "fa-calendar-o", -}; - -// ── SVG numbered pin ──────────────────────────────────────────────── -function numberedPinSvg(fill, number) { - const txt = String(number); - const fontSize = txt.length > 2 ? 13 : 16; - return ( - `` + - `` + - `` + - `#${txt}` + - `` - ); -} -function numberedPinUri(fill, number) { - return "data:image/svg+xml;charset=UTF-8," + encodeURIComponent(numberedPinSvg(fill, number)); -} - -// ── Helpers ───────────────────────────────────────────────────────── -let _gmapsPromise = null; -function loadGoogleMaps(apiKey) { - if (window.google && window.google.maps) return Promise.resolve(); - if (_gmapsPromise) return _gmapsPromise; - _gmapsPromise = new Promise((resolve, reject) => { - const cb = "_fc_gmap_" + Date.now(); - window[cb] = () => { delete window[cb]; resolve(); }; - const s = document.createElement("script"); - s.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&callback=${cb}`; - s.async = true; s.defer = true; - s.onerror = () => { _gmapsPromise = null; reject(new Error("Google Maps script failed")); }; - document.head.appendChild(s); - }); - return _gmapsPromise; -} - -function initialsOf(name) { - if (!name) return "?"; - const p = name.trim().split(/\s+/); - return p.length >= 2 - ? (p[0][0] + p[p.length - 1][0]).toUpperCase() - : p[0].substring(0, 2).toUpperCase(); -} - -/** Return "YYYY-MM-DD" for a JS Date in local tz */ -function localDateStr(d) { - return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`; -} - -/** Convert float hours (e.g. 13.5) to "1:30 PM" */ -function floatToTime12(flt) { - if (!flt && flt !== 0) return ""; - let h = Math.floor(flt); - let m = Math.round((flt - h) * 60); - if (m === 60) { h++; m = 0; } - const ampm = h >= 12 ? "PM" : "AM"; - const h12 = h === 0 ? 12 : h > 12 ? h - 12 : h; - return `${h12}:${String(m).padStart(2, "0")} ${ampm}`; -} - -/** Classify a "YYYY-MM-DD" string into one of our group keys */ -function classifyDate(dateStr) { - if (!dateStr) return GROUP_LATER; - const now = new Date(); - const todayStr = localDateStr(now); - - const yest = new Date(now); - yest.setDate(yest.getDate() - 1); - const yesterdayStr = localDateStr(yest); - - const tmr = new Date(now); - tmr.setDate(tmr.getDate() + 1); - const tomorrowStr = localDateStr(tmr); - - // End of this week (Sunday) - const endOfWeek = new Date(now); - endOfWeek.setDate(endOfWeek.getDate() + (7 - endOfWeek.getDay())); - const endOfWeekStr = localDateStr(endOfWeek); - - if (dateStr === yesterdayStr) return GROUP_YESTERDAY; - if (dateStr === todayStr) return GROUP_TODAY; - if (dateStr === tomorrowStr) return GROUP_TOMORROW; - if (dateStr <= endOfWeekStr && dateStr > tomorrowStr) return GROUP_THIS_WEEK; - if (dateStr < yesterdayStr) return GROUP_YESTERDAY; // older lumped with yesterday - return GROUP_LATER; -} - -const SOURCE_COLORS = { - westin: "#0d6efd", - mobility: "#198754", -}; - -/** Group + sort tasks, returning { groupKey: { label, tasks[], count } } */ -function groupTasks(tasksData, localInstanceId) { - // Sort by date ASC, time ASC - const sorted = [...tasksData].sort((a, b) => { - const da = a.scheduled_date || ""; - const db = b.scheduled_date || ""; - if (da !== db) return da < db ? -1 : 1; - return (a.time_start || 0) - (b.time_start || 0); - }); - - const groups = {}; - const order = [GROUP_YESTERDAY, GROUP_TODAY, GROUP_TOMORROW, GROUP_THIS_WEEK, GROUP_LATER]; - for (const key of order) { - groups[key] = { - key, - label: GROUP_LABELS[key], - dayColor: DAY_COLORS[key] || "#6b7280", - dayIcon: DAY_ICONS[key] || "fa-circle", - tasks: [], - count: 0, - }; - } - - let globalIdx = 0; - for (const task of sorted) { - globalIdx++; - const g = classifyDate(task.scheduled_date); - task._scheduleNum = globalIdx; - task._group = g; - task._dayColor = DAY_COLORS[g] || "#6b7280"; // Pin colour by day - task._statusColor = STATUS_COLORS[task.status] || "#6b7280"; - task._statusLabel = STATUS_LABELS[task.status] || task.status || ""; - task._statusIcon = STATUS_ICONS[task.status] || "fa-circle"; - task._clientName = task.x_fc_sync_client_name || (task.partner_id ? task.partner_id[1] : "N/A"); - task._techName = task.technician_id ? task.technician_id[1] : "Unassigned"; - task._typeLbl = task.task_type - ? task.task_type.charAt(0).toUpperCase() + task.task_type.slice(1).replace("_", " ") - : "Task"; - task._timeRange = `${task.time_start_display || floatToTime12(task.time_start)} - ${task.time_end_display || ""}`; - const src = task.x_fc_sync_source || localInstanceId || ""; - task._sourceLabel = src ? src.charAt(0).toUpperCase() + src.slice(1) : ""; - task._sourceColor = SOURCE_COLORS[src] || "#6c757d"; - task._hasCoords = task.address_lat && task.address_lng && task.address_lat !== 0 && task.address_lng !== 0; - groups[g].tasks.push(task); - groups[g].count++; - } - - // Return only non-empty groups in order - return order.map((k) => groups[k]).filter((g) => g.count > 0); -} - - -// ── Controller ────────────────────────────────────────────────────── -export class FusionTaskMapController extends Component { - static template = "fusion_claims.FusionTaskMapView"; - static components = { Layout, SearchBar, CogMenu }; - static props = { - ...standardViewProps, - Model: Function, - modelParams: Object, - Renderer: { type: Function, optional: true }, - buttonTemplate: String, - }; - - setup() { - this.orm = useService("orm"); - this.actionService = useService("action"); - this.mapRef = useRef("mapContainer"); - - this.state = useState({ - loading: true, - error: null, - showTasks: true, - showTechnicians: true, - showTraffic: true, - taskCount: 0, - techCount: 0, - // Sidebar - sidebarOpen: true, - groups: [], // [{key, label, tasks[], count}] - collapsedGroups: {}, // {groupKey: true} - activeTaskId: null, // Highlighted task - // Day filters for map pins (which groups show on map) - visibleGroups: { - [GROUP_YESTERDAY]: false, // hidden by default - [GROUP_TODAY]: true, - [GROUP_TOMORROW]: true, - [GROUP_THIS_WEEK]: false, // hidden by default - [GROUP_LATER]: false, // hidden by default - }, - }); - - // Yesterday collapsed by default in sidebar list - this.state.collapsedGroups[GROUP_YESTERDAY] = true; - this.state.collapsedGroups[GROUP_LATER] = true; - - this.map = null; - this.taskMarkers = []; - this.taskMarkerMap = {}; // id → marker - this.techMarkers = []; - this.infoWindow = null; - this.apiKey = ""; - this.tasksData = []; - this.locationsData = []; - - const Model = this.props.Model; - this.model = useModelWithSampleData(Model, this.props.modelParams); - useSetupAction({ getLocalState: () => this._meta() }); - usePager(() => ({ - offset: this._meta().offset || 0, - limit: this._meta().limit || 80, - total: this.model.data?.count || this._meta().resCount || 0, - onUpdate: ({ offset, limit }) => this.model.load({ offset, limit }), - })); - this.searchBarToggler = useSearchBarToggler(); - this.display = { controlPanel: {} }; - this._lastDomainStr = ""; - - onMounted(async () => { - window.__fusionMapOpenTask = (id) => this.openTask(id); - await this._loadAndRender(); - this._lastDomainStr = JSON.stringify(this._getDomain()); - }); - onPatched(() => { - const cur = JSON.stringify(this._getDomain()); - if (cur !== this._lastDomainStr && this.map) { - this._lastDomainStr = cur; - this._onModelUpdate(); - } - }); - onWillUnmount(() => { - this._clearMarkers(); - window.__fusionMapOpenTask = () => {}; - }); - } - - // ── Model helpers (safe access across different Model types) ──── - _meta() { - // RelationalModel uses .config, MapModel uses .metaData - return this.model.metaData || this.model.config || {}; - } - _getDomain() { - const m = this._meta(); - return m.domain || []; - } - - // ── Data ───────────────────────────────────────────────────────── - async _loadAndRender() { - try { - const domain = this._getDomain(); - const result = await this.orm.call("fusion.technician.task", "get_map_data", [domain]); - this.apiKey = result.api_key; - this.localInstanceId = result.local_instance_id || ""; - this.tasksData = result.tasks || []; - this.locationsData = result.locations || []; - this.state.taskCount = this.tasksData.length; - this.state.techCount = this.locationsData.length; - this.state.groups = groupTasks(this.tasksData, this.localInstanceId); - - if (!this.apiKey) { - this.state.error = _t("Google Maps API key not configured. Go to Settings > Fusion Claims."); - this.state.loading = false; - return; - } - await loadGoogleMaps(this.apiKey); - if (this.mapRef.el) this._initMap(); - this.state.loading = false; - } catch (e) { - console.error("FusionTaskMap load error:", e); - this.state.error = String(e); - this.state.loading = false; - } - } - - async _onModelUpdate() { - if (!this.map) return; - try { - const domain = this._getDomain(); - const result = await this.orm.call("fusion.technician.task", "get_map_data", [domain]); - this.localInstanceId = result.local_instance_id || this.localInstanceId || ""; - this.tasksData = result.tasks || []; - this.locationsData = result.locations || []; - this.state.taskCount = this.tasksData.length; - this.state.techCount = this.locationsData.length; - this.state.groups = groupTasks(this.tasksData, this.localInstanceId); - this._renderMarkers(); - } catch (e) { - console.error("FusionTaskMap update error:", e); - } - } - - // ── Map ────────────────────────────────────────────────────────── - _initMap() { - if (!this.mapRef.el) return; - this.map = new google.maps.Map(this.mapRef.el, { - zoom: 10, - center: { lat: 43.7, lng: -79.4 }, - mapTypeControl: true, - streetViewControl: false, - fullscreenControl: true, - zoomControl: true, - styles: [{ featureType: "poi", stylers: [{ visibility: "off" }] }], - }); - // Traffic layer (on by default, toggleable) - this.trafficLayer = new google.maps.TrafficLayer(); - this.trafficLayer.setMap(this.map); - - this.infoWindow = new google.maps.InfoWindow(); - // Close popup when clicking anywhere on the map - this.map.addListener("click", () => { - this.infoWindow.close(); - }); - // Clear sidebar highlight when popup closes (by any means) - this.infoWindow.addListener("closeclick", () => { - this.state.activeTaskId = null; - }); - this._renderMarkers(); - } - - _clearMarkers() { - for (const m of this.taskMarkers) m.setMap(null); - for (const m of this.techMarkers) m.setMap(null); - this.taskMarkers = []; - this.taskMarkerMap = {}; - this.techMarkers = []; - } - - _renderMarkers() { - this._clearMarkers(); - const bounds = new google.maps.LatLngBounds(); - let hasBounds = false; - - // Task pins: only show groups that are enabled in the day filter - if (this.state.showTasks) { - for (const group of this.state.groups) { - const groupVisible = this.state.visibleGroups[group.key] !== false; - for (const task of group.tasks) { - if (!task.address_lat || !task.address_lng) continue; - if (!groupVisible) continue; - const pos = { lat: task.address_lat, lng: task.address_lng }; - const num = task._scheduleNum; - const color = task._dayColor; - - const marker = new google.maps.Marker({ - position: pos, - map: this.map, - title: `#${num} ${task.name} - ${task._clientName}`, - icon: { - url: numberedPinUri(color, num), - scaledSize: new google.maps.Size(38, 50), - anchor: new google.maps.Point(19, 50), - }, - zIndex: 10 + num, - }); - - marker.addListener("click", () => this._openTaskPopup(task, marker)); - this.taskMarkers.push(marker); - this.taskMarkerMap[task.id] = marker; - bounds.extend(pos); - hasBounds = true; - } - } - } - - // Technician markers - if (this.state.showTechnicians) { - for (const loc of this.locationsData) { - if (!loc.latitude || !loc.longitude) continue; - const pos = { lat: loc.latitude, lng: loc.longitude }; - const initials = initialsOf(loc.name); - const svg = - `` + - `` + - `${initials}` + - ``; - const marker = new google.maps.Marker({ - position: pos, - map: this.map, - title: loc.name, - icon: { - url: "data:image/svg+xml;charset=UTF-8," + encodeURIComponent(svg), - scaledSize: new google.maps.Size(44, 44), - anchor: new google.maps.Point(22, 22), - }, - zIndex: 100, - }); - marker.addListener("click", () => { - this.infoWindow.setContent(` -

      -
      - ${loc.name} -
      -
      -
      Last seen: ${loc.logged_at || "Unknown"}
      -
      Accuracy: ${loc.accuracy ? Math.round(loc.accuracy) + "m" : "N/A"}
      -
      -
      `); - this.infoWindow.open(this.map, marker); - }); - this.techMarkers.push(marker); - bounds.extend(pos); - hasBounds = true; - } - } - - if (hasBounds) { - this.map.fitBounds(bounds); - if (this.taskMarkers.length + this.techMarkers.length === 1) { - this.map.setZoom(14); - } - } - } - - _openTaskPopup(task, marker) { - const c = task._dayColor; - const html = ` -
      -
      - #${task._scheduleNum}  ${task.name} -
      - ${task._statusLabel} - -
      -
      -
      -
      Client: ${task._clientName}
      -
      Type: ${task._typeLbl}
      -
      Technician: ${task._techName}
      -
      Date: ${task.scheduled_date || ""}
      -
      Time: ${task._timeRange}
      - ${task.address_display ? `
      Address: ${task.address_display}
      ` : ""} - ${task.travel_time_minutes ? `
      Travel: ${task.travel_time_minutes} min
      ` : ""} -
      -
      - - - Navigate → - -
      -
      `; - this.infoWindow.setContent(html); - this.infoWindow.open(this.map, marker); - } - - // ── Sidebar actions ───────────────────────────────────────────── - toggleSidebar() { - this.state.sidebarOpen = !this.state.sidebarOpen; - // Trigger map resize after CSS transition - if (this.map) { - setTimeout(() => google.maps.event.trigger(this.map, "resize"), 320); - } - } - - toggleGroup(groupKey) { - this.state.collapsedGroups[groupKey] = !this.state.collapsedGroups[groupKey]; - } - - isGroupCollapsed(groupKey) { - return !!this.state.collapsedGroups[groupKey]; - } - - focusTask(taskId) { - this.state.activeTaskId = taskId; - const marker = this.taskMarkerMap[taskId]; - if (marker && this.map) { - this.map.panTo(marker.getPosition()); - this.map.setZoom(15); - // Find the task data - for (const g of this.state.groups) { - for (const t of g.tasks) { - if (t.id === taskId) { - this._openTaskPopup(t, marker); - return; - } - } - } - } - } - - // ── Day filter toggle ──────────────────────────────────────────── - toggleDayFilter(groupKey) { - this.state.visibleGroups[groupKey] = !this.state.visibleGroups[groupKey]; - this._renderMarkers(); - } - - isGroupVisible(groupKey) { - return this.state.visibleGroups[groupKey] !== false; - } - - showAllDays() { - for (const k of Object.keys(this.state.visibleGroups)) { - this.state.visibleGroups[k] = true; - } - this._renderMarkers(); - } - - showTodayOnly() { - for (const k of Object.keys(this.state.visibleGroups)) { - this.state.visibleGroups[k] = k === GROUP_TODAY; - } - this._renderMarkers(); - } - - // ── Top bar actions ───────────────────────────────────────────── - toggleTraffic() { - this.state.showTraffic = !this.state.showTraffic; - if (this.trafficLayer) { - this.trafficLayer.setMap(this.state.showTraffic ? this.map : null); - } - } - toggleTasks() { - this.state.showTasks = !this.state.showTasks; - this._renderMarkers(); - } - toggleTechnicians() { - this.state.showTechnicians = !this.state.showTechnicians; - this._renderMarkers(); - } - onRefresh() { - this.state.loading = true; - this._loadAndRender(); - } - openTask(taskId) { - this.actionService.switchView("form", { resId: taskId }); - } - createNewTask() { - this.actionService.doAction({ - type: "ir.actions.act_window", - res_model: "fusion.technician.task", - views: [[false, "form"]], - target: "new", - context: { default_task_type: "delivery", dialog_size: "extra-large" }, - }, { - onClose: () => { - // Refresh map data after dialog closes (task may have been created) - this.onRefresh(); - }, - }); - } -} - -window.__fusionMapOpenTask = () => {}; - -// ── Minimal ArchParser for tags (no web_map dependency) ─────── -class FusionMapArchParser { - parse(xmlDoc, models, modelName) { - const fieldNames = []; - const activeFields = {}; - if (xmlDoc && xmlDoc.querySelectorAll) { - for (const fieldEl of xmlDoc.querySelectorAll("field")) { - const name = fieldEl.getAttribute("name"); - if (name) { - fieldNames.push(name); - activeFields[name] = { attrs: {}, options: {} }; - } - } - } - return { fieldNames, activeFields }; - } -} - -// ── View registration (self-contained, no @web_map dependency) ────── -const fusionTaskMapView = { - type: "map", - display_name: _t("Map"), - icon: "oi-view-map", - multiRecord: true, - searchMenuTypes: ["filter", "groupBy", "favorite"], - Controller: FusionTaskMapController, - Model: RelationalModel, - ArchParser: FusionMapArchParser, - buttonTemplate: "fusion_claims.FusionTaskMapView.Buttons", - props(genericProps, view, config) { - const { resModel, fields } = genericProps; - let archInfo = { fieldNames: [], activeFields: {} }; - if (view && view.arch) { - archInfo = new FusionMapArchParser().parse(view.arch); - } - return { - ...genericProps, - buttonTemplate: "fusion_claims.FusionTaskMapView.Buttons", - Model: RelationalModel, - modelParams: { - config: { - resModel, - fields, - activeFields: archInfo.activeFields || {}, - isMonoRecord: false, - }, - state: { - domain: genericProps.domain || [], - context: genericProps.context || {}, - groupBy: genericProps.groupBy || [], - orderBy: genericProps.orderBy || [], - }, - }, - }; - }, -}; -registry.category("views").add("fusion_task_map", fusionTaskMapView); diff --git a/fusion_claims/fusion_claims/static/src/js/gallery_preview.js b/fusion_claims/fusion_claims/static/src/js/gallery_preview.js deleted file mode 100644 index 044da03..0000000 --- a/fusion_claims/fusion_claims/static/src/js/gallery_preview.js +++ /dev/null @@ -1,120 +0,0 @@ -/** @odoo-module **/ -// Fusion Claims - Gallery Preview -// Uses Odoo's native FileViewer (same as chatter) -// Copyright 2024-2025 Nexa Systems Inc. -// License OPL-1 - -import { patch } from "@web/core/utils/patch"; -import { Many2ManyBinaryField } from "@web/views/fields/many2many_binary/many2many_binary_field"; -import { useFileViewer } from "@web/core/file_viewer/file_viewer_hook"; -import { onMounted, onWillUnmount } from "@odoo/owl"; - -/** - * Patch Many2ManyBinaryField to use Odoo's native FileViewer - * when inside our gallery section (fc-gallery-content class) - */ -patch(Many2ManyBinaryField.prototype, { - setup() { - super.setup(); - - // Use Odoo's native file viewer hook (same as chatter) - this.fileViewer = useFileViewer(); - - // Bind the click handler - this._onGalleryClick = this._onGalleryClick.bind(this); - - onMounted(() => { - // Find if we're inside a gallery section - const el = this.__owl__.bdom?.el; - if (el) { - const gallery = el.closest('.fc-gallery-content'); - if (gallery) { - // Add click listener to intercept downloads - el.addEventListener('click', this._onGalleryClick, true); - this._galleryElement = el; - } - } - }); - - onWillUnmount(() => { - if (this._galleryElement) { - this._galleryElement.removeEventListener('click', this._onGalleryClick, true); - } - }); - }, - - /** - * Handle clicks on attachments in gallery - intercept and use FileViewer - */ - _onGalleryClick(ev) { - // Check if click is anywhere inside an attachment box - const attachmentBox = ev.target.closest('.o_attachment'); - - if (!attachmentBox) { - return; // Not an attachment click - } - - // Skip if clicking on the delete button - if (ev.target.closest('.o_attachment_delete')) { - return; - } - - // Get file ID from any link or image within the attachment box - let fileId = null; - - // Try to get from link href - const link = attachmentBox.querySelector('a[href*="/web/content/"], a[href*="/web/image/"]'); - if (link) { - const href = link.getAttribute('href') || ''; - const match = href.match(/\/web\/(?:content|image)\/(\d+)/); - if (match) { - fileId = parseInt(match[1], 10); - } - } - - // Try to get from image src - if (!fileId) { - const imgEl = attachmentBox.querySelector('img[src*="/web/image/"]'); - if (imgEl) { - const src = imgEl.getAttribute('src') || ''; - const match = src.match(/\/web\/image\/(\d+)/); - if (match) { - fileId = parseInt(match[1], 10); - } - } - } - - if (!fileId) { - return; // Couldn't determine file ID - } - - // Prevent download - ev.preventDefault(); - ev.stopPropagation(); - - // Get all files and transform to FileViewer format - const files = this.files.map(file => { - const mimetype = file.mimetype || 'image/png'; - const isImage = mimetype.startsWith('image/'); - const isPdf = mimetype === 'application/pdf'; - - return { - id: file.id, - name: file.name || 'File', - mimetype: mimetype, - isImage: isImage, - isPdf: isPdf, - isViewable: isImage || isPdf, - defaultSource: isImage ? `/web/image/${file.id}` : `/web/content/${file.id}`, - downloadUrl: `/web/content/${file.id}?download=true`, - }; - }); - - // Find the clicked file and open FileViewer - const clickedFile = files.find(f => f.id === fileId); - - if (clickedFile && this.fileViewer) { - this.fileViewer.open(clickedFile, files); - } - } -}); diff --git a/fusion_claims/fusion_claims/static/src/js/google_address_autocomplete.js b/fusion_claims/fusion_claims/static/src/js/google_address_autocomplete.js deleted file mode 100644 index 70d4d6e..0000000 --- a/fusion_claims/fusion_claims/static/src/js/google_address_autocomplete.js +++ /dev/null @@ -1,1480 +0,0 @@ -/** @odoo-module **/ -// Fusion Claims - Google Address Autocomplete for Contacts -// Copyright 2024-2025 Nexa Systems Inc. -// License OPL-1 - -import { FormController } from "@web/views/form/form_controller"; -import { useService } from "@web/core/utils/hooks"; -import { onMounted, onWillUnmount } from "@odoo/owl"; -import { patch } from "@web/core/utils/patch"; - -// Store for autocomplete instances and services -let googleMapsLoaded = false; -let googleMapsLoading = false; -let googleMapsApiKey = null; -let globalOrm = null; -const autocompleteInstances = new Map(); - -/** - * Load Google Maps API dynamically - */ -async function loadGoogleMapsApi(apiKey) { - if (googleMapsLoaded) { - return Promise.resolve(); - } - - if (googleMapsLoading) { - return new Promise((resolve) => { - const checkLoaded = setInterval(() => { - if (googleMapsLoaded) { - clearInterval(checkLoaded); - resolve(); - } - }, 100); - }); - } - - googleMapsLoading = true; - - return new Promise((resolve, reject) => { - window.initGoogleMapsAutocomplete = () => { - googleMapsLoaded = true; - googleMapsLoading = false; - resolve(); - }; - - const script = document.createElement('script'); - script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places&callback=initGoogleMapsAutocomplete`; - script.async = true; - script.defer = true; - script.onerror = () => { - googleMapsLoading = false; - reject(new Error('Failed to load Google Maps API')); - }; - document.head.appendChild(script); - }); -} - -/** - * Get API key from Odoo config - */ -async function getGoogleMapsApiKey(orm) { - if (googleMapsApiKey) { - return googleMapsApiKey; - } - - try { - const result = await orm.call( - 'ir.config_parameter', - 'get_param', - ['fusion_claims.google_maps_api_key'] - ); - googleMapsApiKey = result || null; - return googleMapsApiKey; - } catch (error) { - console.warn('Could not fetch Google Maps API key:', error); - return null; - } -} - -/** - * Initialize autocomplete on a street input field - */ -function initAutocompleteOnField(input, formModel) { - if (!input || !window.google || !window.google.maps || !window.google.maps.places) { - return null; - } - - if (autocompleteInstances.has(input)) { - return autocompleteInstances.get(input); - } - - const autocomplete = new google.maps.places.Autocomplete(input, { - componentRestrictions: { country: 'ca' }, - types: ['address'], - fields: ['address_components', 'formatted_address', 'geometry'] - }); - - autocomplete.addListener('place_changed', async () => { - const place = autocomplete.getPlace(); - if (!place.address_components) { - return; - } - - // Parse address components - let streetNumber = ''; - let streetName = ''; - let unitNumber = ''; // For apartment/unit/suite - let city = ''; - let province = ''; - let postalCode = ''; - let countryCode = ''; - - for (const component of place.address_components) { - const types = component.types; - - if (types.includes('street_number')) { - streetNumber = component.long_name; - } else if (types.includes('route')) { - streetName = component.long_name; - } else if (types.includes('subpremise')) { - // Unit, apartment, suite number - unitNumber = component.long_name; - } else if (types.includes('floor')) { - // Floor number - if (!unitNumber) unitNumber = 'Floor ' + component.long_name; - } else if (types.includes('locality')) { - city = component.long_name; - } else if (types.includes('sublocality_level_1') && !city) { - city = component.long_name; - } else if (types.includes('administrative_area_level_1')) { - province = component.short_name; - } else if (types.includes('postal_code')) { - postalCode = component.long_name; - } else if (types.includes('country')) { - countryCode = component.short_name; - } - } - - const street = streetNumber ? `${streetNumber} ${streetName}` : streetName; - - console.log('[GooglePlaces] Parsed address:', { street, unitNumber, city, province, postalCode, countryCode }); - - if (!formModel || !formModel.root) { - console.warn('[GooglePlaces] No form model available'); - return; - } - - const record = formModel.root; - - // First, lookup country and state IDs - let countryId = null; - let stateId = null; - - if (globalOrm && countryCode) { - try { - // Find country - const countries = await globalOrm.searchRead( - 'res.country', - [['code', '=', countryCode]], - ['id'], - { limit: 1 } - ); - - if (countries.length) { - countryId = countries[0].id; - console.log('[GooglePlaces] Found country ID:', countryId); - - // Find state - if (province) { - const states = await globalOrm.searchRead( - 'res.country.state', - [['code', '=', province], ['country_id', '=', countryId]], - ['id'], - { limit: 1 } - ); - - if (states.length) { - stateId = states[0].id; - console.log('[GooglePlaces] Found state ID:', stateId); - } - } - } - } catch (error) { - console.error('[GooglePlaces] Error looking up country/state:', error); - } - } - - // Build complete update payload - const updatePayload = {}; - if (street) updatePayload.street = street; - if (unitNumber) updatePayload.street2 = unitNumber; - if (city) updatePayload.city = city; - if (postalCode) updatePayload.zip = postalCode; - if (countryId !== null) updatePayload.country_id = countryId; - if (stateId !== null) updatePayload.state_id = stateId; - - console.log('[GooglePlaces] Full update payload:', updatePayload); - console.log('[GooglePlaces] Record ID:', record.resId); - console.log('[GooglePlaces] Country ID to set:', countryId); - console.log('[GooglePlaces] State ID to set:', stateId); - - // If record is saved (has ID), use ORM write directly - if (record.resId && globalOrm) { - try { - console.log('[GooglePlaces] Using ORM write for saved record'); - - // First write country and text fields - const firstWrite = { ...updatePayload }; - delete firstWrite.state_id; // Remove state from first write - - await globalOrm.write('res.partner', [record.resId], firstWrite); - console.log('[GooglePlaces] First write (country + text) successful'); - - // Then write state separately after a small delay - if (stateId !== null) { - await new Promise(resolve => setTimeout(resolve, 100)); - await globalOrm.write('res.partner', [record.resId], { state_id: stateId }); - console.log('[GooglePlaces] Second write (state) successful'); - } - - // Reload the record to show updated values - await record.load(); - console.log('[GooglePlaces] Record reloaded'); - } catch (error) { - console.error('[GooglePlaces] ORM write failed:', error); - } - } else { - // For new records - use DOM manipulation approach - console.log('[GooglePlaces] New record - using DOM approach'); - - try { - // Update text fields through record.update (these work) - const textUpdate = {}; - if (street) textUpdate.street = street; - if (unitNumber) textUpdate.street2 = unitNumber; - if (city) textUpdate.city = city; - if (postalCode) textUpdate.zip = postalCode; - - if (Object.keys(textUpdate).length > 0) { - await record.update(textUpdate); - console.log('[GooglePlaces] Text fields updated'); - } - - // For Many2one fields, we need to simulate user interaction - const formEl = input.closest('.o_form_view') || input.closest('.o_content') || document.body; - - if (countryId !== null && globalOrm) { - // Get country and state names in parallel for speed - const [countryData, stateData] = await Promise.all([ - globalOrm.read('res.country', [countryId], ['display_name']), - stateId ? globalOrm.read('res.country.state', [stateId], ['display_name']) : Promise.resolve([]) - ]); - - const countryName = countryData[0]?.display_name || 'Canada'; - const stateName = stateData[0]?.display_name || province; - - // Find and update country field via DOM - await simulateMany2OneSelection(formEl, 'country_id', countryId, countryName); - - // Wait for country onchange to complete (reduced time) - await new Promise(resolve => setTimeout(resolve, 300)); - - // Now set state - if (stateId !== null) { - await simulateMany2OneSelection(formEl, 'state_id', stateId, stateName); - } - } - - } catch (error) { - console.error('[GooglePlaces] New record update failed:', error); - } - } - }); - - autocompleteInstances.set(input, autocomplete); - return autocomplete; -} - -/** - * Simulate Many2One field selection by finding the widget and triggering its update - */ -async function simulateMany2OneSelection(formEl, fieldName, valueId, displayName) { - console.log(`[GooglePlaces] Simulating selection for ${fieldName}: ${valueId} - ${displayName}`); - - // Find the field container - const fieldSelectors = [ - `[name="${fieldName}"]`, - `.o_field_widget[name="${fieldName}"]`, - `div[name="${fieldName}"]`, - ]; - - let fieldContainer = null; - for (const selector of fieldSelectors) { - fieldContainer = formEl.querySelector(selector); - if (fieldContainer) break; - } - - if (!fieldContainer) { - console.log(`[GooglePlaces] Field container not found for ${fieldName}`); - return false; - } - - console.log(`[GooglePlaces] Found field container for ${fieldName}`); - - // Try to find the OWL component instance - // In Odoo 17+, OWL components store their instance in __owl__ - let owlComponent = null; - let el = fieldContainer; - while (el && !owlComponent) { - if (el.__owl__) { - owlComponent = el.__owl__; - break; - } - el = el.parentElement; - } - - if (owlComponent && owlComponent.component) { - console.log(`[GooglePlaces] Found OWL component for ${fieldName}`); - - // Try to call the component's update method - const component = owlComponent.component; - - if (component.props && component.props.record) { - try { - // Try updating through the props record - await component.props.record.update({ [fieldName]: valueId }); - console.log(`[GooglePlaces] Updated via props.record for ${fieldName}`); - return true; - } catch (e) { - console.log(`[GooglePlaces] props.record.update failed for ${fieldName}:`, e.message); - } - } - - if (typeof component.updateValue === 'function') { - try { - await component.updateValue(valueId); - console.log(`[GooglePlaces] Updated via updateValue for ${fieldName}`); - return true; - } catch (e) { - console.log(`[GooglePlaces] updateValue failed for ${fieldName}:`, e.message); - } - } - } - - // Fallback: Try to find and manipulate the input directly - const inputEl = fieldContainer.querySelector('input:not([type="hidden"])'); - if (inputEl) { - // Focus the input first - inputEl.focus(); - - // Clear and set value - inputEl.value = ''; - inputEl.value = displayName; - - // Trigger input event to open dropdown - inputEl.dispatchEvent(new InputEvent('input', { - bubbles: true, - cancelable: true, - data: displayName, - inputType: 'insertText' - })); - - console.log(`[GooglePlaces] Triggered input event for ${fieldName}, waiting for dropdown...`); - - // Wait for dropdown to appear and search results to load (reduced) - await new Promise(resolve => setTimeout(resolve, 250)); - - // Look for dropdown items with various selectors used by Odoo - const dropdownSelectors = [ - '.o-autocomplete--dropdown-menu .o-autocomplete--dropdown-item', - '.o_m2o_dropdown_option', - '.dropdown-menu .dropdown-item', - '.o-autocomplete .dropdown-item', - 'ul.ui-autocomplete li', - '.o_field_many2one_selection li', - ]; - - let found = false; - for (const selector of dropdownSelectors) { - const dropdownItems = document.querySelectorAll(selector); - console.log(`[GooglePlaces] Checking selector "${selector}": found ${dropdownItems.length} items`); - - for (const item of dropdownItems) { - const itemText = item.textContent.trim(); - if (itemText.includes(displayName) || displayName.includes(itemText)) { - // Click the item - item.click(); - console.log(`[GooglePlaces] Clicked dropdown item for ${fieldName}: "${itemText}"`); - found = true; - break; - } - } - if (found) break; - } - - if (!found) { - console.log(`[GooglePlaces] No matching dropdown item found for ${fieldName}`); - - // Try pressing Enter to select the first option - inputEl.dispatchEvent(new KeyboardEvent('keydown', { - key: 'Enter', - code: 'Enter', - keyCode: 13, - bubbles: true - })); - console.log(`[GooglePlaces] Sent Enter key for ${fieldName}`); - - // Also try Tab to confirm selection - await new Promise(resolve => setTimeout(resolve, 50)); - inputEl.dispatchEvent(new KeyboardEvent('keydown', { - key: 'Tab', - code: 'Tab', - keyCode: 9, - bubbles: true - })); - } - - // Blur to finalize - await new Promise(resolve => setTimeout(resolve, 50)); - inputEl.blur(); - - return found; - } - - return false; -} - -/** - * Initialize company name autocomplete (searches for businesses) - */ -function initCompanyAutocomplete(input, formModel) { - if (!input || !window.google || !window.google.maps || !window.google.maps.places) { - return null; - } - - const instanceKey = 'company_' + input.id; - if (autocompleteInstances.has(instanceKey)) { - return autocompleteInstances.get(instanceKey); - } - - const autocomplete = new google.maps.places.Autocomplete(input, { - componentRestrictions: { country: 'ca' }, - types: ['establishment'], // Search for businesses - fields: ['place_id', 'name', 'address_components', 'formatted_address', 'formatted_phone_number', 'international_phone_number', 'website', 'geometry'] - }); - - autocomplete.addListener('place_changed', async () => { - let place = autocomplete.getPlace(); - if (!place.name && !place.place_id) { - return; - } - - console.log('[GooglePlaces] Company selected:', place.name); - console.log('[GooglePlaces] Initial place data:', place); - - // If phone/website not in initial response, fetch place details - if (place.place_id && (!place.formatted_phone_number && !place.website)) { - try { - const service = new google.maps.places.PlacesService(document.createElement('div')); - const detailsPromise = new Promise((resolve, reject) => { - service.getDetails( - { - placeId: place.place_id, - fields: ['formatted_phone_number', 'international_phone_number', 'website', 'name', 'address_components'] - }, - (result, status) => { - if (status === google.maps.places.PlacesServiceStatus.OK) { - resolve(result); - } else { - reject(new Error('Place details failed: ' + status)); - } - } - ); - }); - - const details = await detailsPromise; - console.log('[GooglePlaces] Fetched place details:', details); - - // Merge details into place - if (details.formatted_phone_number) place.formatted_phone_number = details.formatted_phone_number; - if (details.international_phone_number) place.international_phone_number = details.international_phone_number; - if (details.website) place.website = details.website; - } catch (e) { - console.log('[GooglePlaces] Could not fetch place details:', e.message); - } - } - - console.log('[GooglePlaces] Final place data:', place); - - // Parse address components - let streetNumber = ''; - let streetName = ''; - let unitNumber = ''; // For apartment/unit/suite - let city = ''; - let province = ''; - let postalCode = ''; - let countryCode = ''; - - if (place.address_components) { - for (const component of place.address_components) { - const types = component.types; - - if (types.includes('street_number')) { - streetNumber = component.long_name; - } else if (types.includes('route')) { - streetName = component.long_name; - } else if (types.includes('subpremise')) { - // Unit, apartment, suite number - unitNumber = component.long_name; - } else if (types.includes('floor')) { - // Floor number - add to unit if no unit already - if (!unitNumber) unitNumber = 'Floor ' + component.long_name; - } else if (types.includes('locality')) { - city = component.long_name; - } else if (types.includes('sublocality_level_1') && !city) { - city = component.long_name; - } else if (types.includes('administrative_area_level_1')) { - province = component.short_name; - } else if (types.includes('postal_code')) { - postalCode = component.long_name; - } else if (types.includes('country')) { - countryCode = component.short_name; - } - } - } - - const street = streetNumber ? `${streetNumber} ${streetName}` : streetName; - console.log('[GooglePlaces] Parsed: street=', street, 'unit=', unitNumber, 'city=', city); - - if (!formModel || !formModel.root) { - return; - } - - const record = formModel.root; - - // Lookup country and state IDs - let countryId = null; - let stateId = null; - - if (globalOrm && countryCode) { - try { - const [countryData, stateData] = await Promise.all([ - globalOrm.searchRead('res.country', [['code', '=', countryCode]], ['id'], { limit: 1 }), - province ? globalOrm.searchRead('res.country.state', [['code', '=', province], ['country_id.code', '=', countryCode]], ['id'], { limit: 1 }) : Promise.resolve([]) - ]); - - if (countryData.length) countryId = countryData[0].id; - if (stateData.length) stateId = stateData[0].id; - } catch (error) { - console.error('[GooglePlaces] Error looking up country/state:', error); - } - } - - // Get phone number (prefer formatted, fallback to international) - const phoneNumber = place.formatted_phone_number || place.international_phone_number || ''; - - // Build update payload - const updatePayload = { - name: place.name, - }; - if (street) updatePayload.street = street; - if (unitNumber) updatePayload.street2 = unitNumber; - if (city) updatePayload.city = city; - if (postalCode) updatePayload.zip = postalCode; - if (phoneNumber) updatePayload.phone = phoneNumber; - if (place.website) updatePayload.website = place.website; - if (countryId) updatePayload.country_id = countryId; - if (stateId) updatePayload.state_id = stateId; - - console.log('[GooglePlaces] Phone:', phoneNumber, 'Website:', place.website, 'Unit:', unitNumber); - - console.log('[GooglePlaces] Company update payload:', updatePayload); - - // For saved records, use ORM write - if (record.resId && globalOrm) { - try { - const writePayload = { ...updatePayload }; - delete writePayload.state_id; // Write state separately - - await globalOrm.write('res.partner', [record.resId], writePayload); - - if (stateId) { - await new Promise(resolve => setTimeout(resolve, 100)); - await globalOrm.write('res.partner', [record.resId], { state_id: stateId }); - } - - await record.load(); - console.log('[GooglePlaces] Company record updated'); - } catch (error) { - console.error('[GooglePlaces] Company ORM write failed:', error); - } - } else { - // For new records, update through the form - try { - // Text fields - const textFields = {}; - if (place.name) textFields.name = place.name; - if (street) textFields.street = street; - if (unitNumber) textFields.street2 = unitNumber; - if (city) textFields.city = city; - if (postalCode) textFields.zip = postalCode; - if (phoneNumber) textFields.phone = phoneNumber; - if (place.website) textFields.website = place.website; - - console.log('[GooglePlaces] New record text fields:', textFields); - - await record.update(textFields); - - // Country and state via DOM simulation - const formEl = input.closest('.o_form_view') || input.closest('.o_content') || document.body; - - if (countryId && globalOrm) { - const [countryInfo, stateInfo] = await Promise.all([ - globalOrm.read('res.country', [countryId], ['display_name']), - stateId ? globalOrm.read('res.country.state', [stateId], ['display_name']) : Promise.resolve([]) - ]); - - await simulateMany2OneSelection(formEl, 'country_id', countryId, countryInfo[0]?.display_name || 'Canada'); - - if (stateId) { - await new Promise(resolve => setTimeout(resolve, 300)); - await simulateMany2OneSelection(formEl, 'state_id', stateId, stateInfo[0]?.display_name || province); - } - } - - console.log('[GooglePlaces] Company new record updated'); - } catch (error) { - console.error('[GooglePlaces] Company update failed:', error); - } - } - }); - - autocompleteInstances.set(instanceKey, autocomplete); - return autocomplete; -} - -/** - * Setup autocomplete for partner form - */ -async function setupPartnerAutocomplete(el, model, orm) { - globalOrm = orm; - - const apiKey = await getGoogleMapsApiKey(orm); - if (!apiKey) { - console.log('[GooglePlaces] API key not configured'); - return; - } - - try { - await loadGoogleMapsApi(apiKey); - } catch (error) { - console.warn('[GooglePlaces] Failed to load API:', error); - return; - } - - // Find street input field for address autocomplete - const streetInputSelectors = [ - 'input[name="street"]', - '.o_field_widget[name="street"] input', - '[name="street"] input', - 'div[name="street"] input', - '.o_address_street input' - ]; - - let streetInput = null; - for (const selector of streetInputSelectors) { - streetInput = el.querySelector(selector); - if (streetInput) break; - } - - if (streetInput && !autocompleteInstances.has(streetInput)) { - initAutocompleteOnField(streetInput, model); - - // Add visual indicator - streetInput.style.backgroundImage = 'url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 24 24\' fill=\'%234CAF50\'%3E%3Cpath d=\'M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\'/%3E%3C/svg%3E")'; - streetInput.style.backgroundRepeat = 'no-repeat'; - streetInput.style.backgroundPosition = 'right 8px center'; - streetInput.style.backgroundSize = '20px'; - streetInput.style.paddingRight = '35px'; - - console.log('[GooglePlaces] Address autocomplete initialized on street field'); - } - - // Find company name input field for company autocomplete - const nameInputSelectors = [ - 'input[name="name"]', - '.o_field_widget[name="name"] input', - '[name="name"] input', - 'input.o_input[placeholder*="Lumber"]', // Odoo's placeholder for company name - '.o_field_char[name="name"] input', - ]; - - let nameInput = null; - for (const selector of nameInputSelectors) { - nameInput = el.querySelector(selector); - if (nameInput) { - console.log('[GooglePlaces] Found name input with selector:', selector); - break; - } - } - - // Check if company type is selected - try multiple ways - let isCompany = false; - - // Method 1: Check radio buttons - const companyRadio = el.querySelector('input[name="company_type"][value="company"]'); - if (companyRadio && companyRadio.checked) { - isCompany = true; - console.log('[GooglePlaces] Company detected via radio button'); - } - - // Method 2: Check for company-specific elements (building icon visible) - if (!isCompany) { - const companyIcon = el.querySelector('.fa-building, .o_field_partner_type .fa-building-o'); - if (companyIcon) { - isCompany = true; - console.log('[GooglePlaces] Company detected via building icon'); - } - } - - // Method 3: Check data attribute or class - if (!isCompany) { - const companyTypeField = el.querySelector('[name="company_type"]'); - if (companyTypeField) { - const selectedOption = companyTypeField.querySelector('.active, .selected, [aria-checked="true"]'); - if (selectedOption && selectedOption.textContent.toLowerCase().includes('company')) { - isCompany = true; - console.log('[GooglePlaces] Company detected via active option'); - } - } - } - - // Method 4: Check the model data - if (!isCompany && model && model.root && model.root.data) { - const companyType = model.root.data.company_type; - if (companyType === 'company') { - isCompany = true; - console.log('[GooglePlaces] Company detected via model data'); - } - } - - console.log('[GooglePlaces] isCompany:', isCompany, 'nameInput:', !!nameInput); - - if (nameInput) { - const instanceKey = 'company_' + (nameInput.id || 'default'); - - if (isCompany && !autocompleteInstances.has(instanceKey)) { - initCompanyAutocomplete(nameInput, model); - - // Add visual indicator (building icon) - nameInput.style.backgroundImage = 'url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 24 24\' fill=\'%232196F3\'%3E%3Cpath d=\'M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z\'/%3E%3C/svg%3E")'; - nameInput.style.backgroundRepeat = 'no-repeat'; - nameInput.style.backgroundPosition = 'right 8px center'; - nameInput.style.backgroundSize = '20px'; - nameInput.style.paddingRight = '35px'; - - console.log('[GooglePlaces] Company autocomplete initialized on name field'); - } else if (!isCompany && autocompleteInstances.has(instanceKey)) { - // Remove company autocomplete when switched to Person - autocompleteInstances.delete(instanceKey); - nameInput.style.backgroundImage = ''; - nameInput.style.paddingRight = ''; - console.log('[GooglePlaces] Company autocomplete removed (switched to Person)'); - } - } - - // Listen for company_type changes - try multiple selectors - const companyTypeSelectors = [ - 'input[name="company_type"]', - '[name="company_type"] input', - '.o_field_radio[name="company_type"] input', - '.o_field_widget[name="company_type"] input', - ]; - - for (const selector of companyTypeSelectors) { - const inputs = el.querySelectorAll(selector); - inputs.forEach(input => { - if (!input.dataset.googlePlacesListener) { - input.dataset.googlePlacesListener = 'true'; - input.addEventListener('change', () => { - console.log('[GooglePlaces] company_type changed, re-initializing...'); - setTimeout(() => { - setupPartnerAutocomplete(el, model, orm); - }, 200); - }); - console.log('[GooglePlaces] Added listener to company_type input'); - } - }); - } - - // Also listen for clicks on the company type labels/buttons - const companyTypeContainer = el.querySelector('[name="company_type"]'); - if (companyTypeContainer && !companyTypeContainer.dataset.googlePlacesListener) { - companyTypeContainer.dataset.googlePlacesListener = 'true'; - companyTypeContainer.addEventListener('click', () => { - console.log('[GooglePlaces] company_type container clicked, re-initializing...'); - setTimeout(() => { - setupPartnerAutocomplete(el, model, orm); - }, 300); - }); - } -} - -/** - * Cleanup autocomplete instances - */ -function cleanupAutocomplete(el) { - if (!el) return; - - const inputs = el.querySelectorAll('input'); - inputs.forEach(input => { - if (autocompleteInstances.has(input)) { - autocompleteInstances.delete(input); - } - }); -} - -/** - * Setup autocomplete for technician task form (address_street field) - */ -async function setupTaskAutocomplete(el, model, orm) { - globalOrm = orm; - - const apiKey = await getGoogleMapsApiKey(orm); - if (!apiKey) { - console.log('[GooglePlaces Task] API key not configured'); - return; - } - - try { - await loadGoogleMapsApi(apiKey); - } catch (error) { - console.warn('[GooglePlaces Task] Failed to load API:', error); - return; - } - - // Find address_street input - const streetSelectors = [ - 'div[name="address_street"] input', - '.o_field_widget[name="address_street"] input', - '[name="address_street"] input', - ]; - - let streetInput = null; - for (const selector of streetSelectors) { - streetInput = el.querySelector(selector); - if (streetInput) break; - } - - if (!streetInput || autocompleteInstances.has(streetInput)) { - return; - } - - _attachTaskAutocomplete(streetInput, el, model); -} - -/** - * Attach Google Places autocomplete to a task address_street input. - * Separated so it can be re-called after OWL re-renders the input. - */ -function _attachTaskAutocomplete(streetInput, el, model) { - if (!streetInput || !window.google?.maps?.places) return; - if (autocompleteInstances.has(streetInput)) return; - - console.log('[GooglePlaces Task] Attaching autocomplete on address_street'); - - const autocomplete = new google.maps.places.Autocomplete(streetInput, { - componentRestrictions: { country: 'ca' }, - types: ['address'], - fields: ['address_components', 'formatted_address', 'geometry'], - }); - - autocomplete.addListener('place_changed', async () => { - const place = autocomplete.getPlace(); - if (!place.address_components) return; - - let streetNumber = '', streetName = '', unitNumber = ''; - let city = '', province = '', postalCode = '', countryCode = ''; - let lat = 0, lng = 0; - - for (const c of place.address_components) { - const t = c.types; - if (t.includes('street_number')) streetNumber = c.long_name; - else if (t.includes('route')) streetName = c.long_name; - else if (t.includes('subpremise')) unitNumber = c.long_name; - else if (t.includes('floor') && !unitNumber) unitNumber = 'Floor ' + c.long_name; - else if (t.includes('locality')) city = c.long_name; - else if (t.includes('sublocality_level_1') && !city) city = c.long_name; - else if (t.includes('administrative_area_level_1')) province = c.short_name; - else if (t.includes('postal_code')) postalCode = c.long_name; - else if (t.includes('country')) countryCode = c.short_name; - } - - if (place.geometry && place.geometry.location) { - lat = place.geometry.location.lat(); - lng = place.geometry.location.lng(); - } - - const streetOnly = streetNumber ? `${streetNumber} ${streetName}` : streetName; - // Use the full formatted address from Google for the Street field - // so the user sees the complete address in one shot. - const fullAddress = place.formatted_address || streetOnly; - console.log('[GooglePlaces Task] Parsed:', { fullAddress, streetOnly, unitNumber, city, province, postalCode, lat, lng }); - - if (!model || !model.root) return; - const record = model.root; - - // Look up state ID - let stateId = false; - if (province && globalOrm) { - try { - const states = await globalOrm.searchRead( - 'res.country.state', - [['code', '=', province], ['country_id.code', '=', countryCode || 'CA']], - ['id'], - { limit: 1 } - ); - if (states.length) stateId = states[0].id; - } catch (e) { - console.warn('[GooglePlaces Task] State lookup failed:', e); - } - } - - // Update through the form model - // address_street gets the FULL formatted address so the user can see it. - // Hidden fields still get parsed components for data/geocoding/travel. - try { - const update = {}; - update.address_street = fullAddress; - if (unitNumber) update.address_street2 = unitNumber; - if (city) update.address_city = city; - if (postalCode) update.address_zip = postalCode; - if (lat) update.address_lat = lat; - if (lng) update.address_lng = lng; - if (stateId) update.address_state_id = stateId; - - await record.update(update); - console.log('[GooglePlaces Task] Address fields updated via model'); - } catch (err) { - console.error('[GooglePlaces Task] Update failed:', err); - } - - // After record.update(), OWL may re-render and replace the input element. - // Re-attach autocomplete on the (potentially new) input after a short delay. - setTimeout(() => { - _reattachTaskAutocomplete(el, model); - }, 400); - }); - - autocompleteInstances.set(streetInput, autocomplete); - - // Visual indicator - streetInput.style.backgroundImage = 'url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 24 24\' fill=\'%234CAF50\'%3E%3Cpath d=\'M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\'/%3E%3C/svg%3E")'; - streetInput.style.backgroundRepeat = 'no-repeat'; - streetInput.style.backgroundPosition = 'right 8px center'; - streetInput.style.backgroundSize = '20px'; - streetInput.style.paddingRight = '35px'; - - console.log('[GooglePlaces Task] Autocomplete ready on address_street'); -} - -/** - * Re-attach autocomplete after OWL re-renders the task form input. - * Finds the current address_street input and attaches if not already done. - */ -function _reattachTaskAutocomplete(el, model) { - const streetSelectors = [ - 'div[name="address_street"] input', - '.o_field_widget[name="address_street"] input', - '[name="address_street"] input', - ]; - - let streetInput = null; - for (const selector of streetSelectors) { - streetInput = el.querySelector(selector); - if (streetInput) break; - } - - if (streetInput && !autocompleteInstances.has(streetInput)) { - console.log('[GooglePlaces Task] Re-attaching autocomplete after re-render'); - _attachTaskAutocomplete(streetInput, el, model); - } -} - -/** - * Attach Google Places autocomplete to a simple Char field (address only, no parsing). - * Sets the full formatted address string in the input. - */ -function initSimpleAddressAutocomplete(input) { - if (!input || !window.google || !window.google.maps || !window.google.maps.places) return; - if (autocompleteInstances.has(input)) return; - - const autocomplete = new google.maps.places.Autocomplete(input, { - componentRestrictions: { country: 'ca' }, - types: ['address'], - fields: ['formatted_address'], - }); - - autocomplete.addListener('place_changed', () => { - const place = autocomplete.getPlace(); - if (place && place.formatted_address) { - // Use native setter for OWL reactivity - const nativeSetter = Object.getOwnPropertyDescriptor( - window.HTMLInputElement.prototype, 'value' - ).set; - nativeSetter.call(input, place.formatted_address); - input.dispatchEvent(new Event('input', { bubbles: true })); - input.dispatchEvent(new Event('change', { bubbles: true })); - console.log('[GooglePlaces] Simple address set:', place.formatted_address); - } - }); - - autocompleteInstances.set(input, autocomplete); - - // Visual indicator - input.style.backgroundImage = 'url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 24 24\' fill=\'%234CAF50\'%3E%3Cpath d=\'M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\'/%3E%3C/svg%3E")'; - input.style.backgroundRepeat = 'no-repeat'; - input.style.backgroundPosition = 'right 8px center'; - input.style.backgroundSize = '20px'; - input.style.paddingRight = '35px'; - - console.log('[GooglePlaces] Simple address autocomplete attached'); -} - -/** - * Setup autocomplete on simple address Char fields by name. - * Works for res.users (x_fc_start_address) and res.config.settings (fc_technician_start_address). - */ -async function setupSimpleAddressFields(el, orm) { - const apiKey = await getGoogleMapsApiKey(orm); - if (!apiKey) return; - try { await loadGoogleMapsApi(apiKey); } catch (e) { return; } - - const fieldNames = ['x_fc_start_address', 'fc_technician_start_address']; - for (const name of fieldNames) { - const selectors = [ - `div[name="${name}"] input`, - `.o_field_widget[name="${name}"] input`, - `[name="${name}"] input`, - ]; - for (const sel of selectors) { - const inp = el.querySelector(sel); - if (inp) { - initSimpleAddressAutocomplete(inp); - break; - } - } - } -} - -/** - * Patch FormController to add Google autocomplete for partner forms and dialog detection - */ -patch(FormController.prototype, { - setup() { - super.setup(); - - this.orm = useService("orm"); - - onMounted(() => { - // Store ORM globally for dialog watcher - globalOrm = this.orm; - - // Direct partner form - if (this.props.resModel === 'res.partner') { - setTimeout(() => { - if (this.rootRef && this.rootRef.el) { - setupPartnerAutocomplete(this.rootRef.el, this.model, this.orm); - } - }, 800); - - if (this.rootRef && this.rootRef.el) { - this._addressObserver = new MutationObserver((mutations) => { - const hasNewInputs = mutations.some(m => - m.addedNodes.length > 0 && - Array.from(m.addedNodes).some(n => - n.nodeType === 1 && (n.tagName === 'INPUT' || n.querySelector?.('input')) - ) - ); - if (hasNewInputs) { - setTimeout(() => { - setupPartnerAutocomplete(this.rootRef.el, this.model, this.orm); - }, 300); - } - }); - - this._addressObserver.observe(this.rootRef.el, { - childList: true, - subtree: true - }); - } - } - - // Technician task form - if (this.props.resModel === 'fusion.technician.task') { - setTimeout(() => { - if (this.rootRef && this.rootRef.el) { - setupTaskAutocomplete(this.rootRef.el, this.model, this.orm); - } - }, 800); - - if (this.rootRef && this.rootRef.el) { - this._taskAddressObserver = new MutationObserver((mutations) => { - const hasNewInputs = mutations.some(m => - m.addedNodes.length > 0 && - Array.from(m.addedNodes).some(n => - n.nodeType === 1 && (n.tagName === 'INPUT' || n.querySelector?.('input')) - ) - ); - if (hasNewInputs) { - setTimeout(() => { - setupTaskAutocomplete(this.rootRef.el, this.model, this.orm); - }, 300); - } - }); - - this._taskAddressObserver.observe(this.rootRef.el, { - childList: true, - subtree: true, - }); - - // "Calculate Travel" button -- handle via JS to prevent dialog close - const calcBtn = this.rootRef.el.querySelector('.o_fc_calculate_travel'); - if (calcBtn) { - const formModel = this.model; - const orm = this.orm; - calcBtn.addEventListener('click', async (ev) => { - ev.preventDefault(); - ev.stopPropagation(); - const resId = formModel.root.resId; - if (!resId) { - // New unsaved record -- save first - const saved = await formModel.root.save(); - if (!saved) return; - } else { - // Existing record -- save pending changes - if (formModel.root.isDirty) { - const saved = await formModel.root.save(); - if (!saved) return; - } - } - const id = formModel.root.resId; - if (!id) return; - // Show loading state on button - const origText = calcBtn.textContent; - calcBtn.disabled = true; - calcBtn.textContent = ' Calculating...'; - try { - await orm.call( - 'fusion.technician.task', - 'action_calculate_travel_times', - [id], - ); - // Reload form data to show updated travel fields - await formModel.root.load(); - } catch (e) { - console.error('[CalcTravel] Error:', e); - } finally { - calcBtn.disabled = false; - calcBtn.textContent = origText || ' Calculate Travel'; - } - }); - } - } - } - - // Simple address autocomplete: res.partner, res.users, res.config.settings - if (this.props.resModel === 'res.partner' || this.props.resModel === 'res.users' || this.props.resModel === 'res.config.settings') { - setTimeout(() => { - if (this.rootRef && this.rootRef.el) { - setupSimpleAddressFields(this.rootRef.el, this.orm); - } - }, 800); - - if (this.rootRef && this.rootRef.el) { - this._simpleAddrObserver = new MutationObserver((mutations) => { - const hasNewInputs = mutations.some(m => - m.addedNodes.length > 0 && - Array.from(m.addedNodes).some(n => - n.nodeType === 1 && (n.tagName === 'INPUT' || n.querySelector?.('input')) - ) - ); - if (hasNewInputs) { - setTimeout(() => { - setupSimpleAddressFields(this.rootRef.el, this.orm); - }, 300); - } - }); - this._simpleAddrObserver.observe(this.rootRef.el, { childList: true, subtree: true }); - } - } - - // Start global dialog watcher once - _startDialogWatcher(this.orm); - }); - - onWillUnmount(() => { - if (this._addressObserver) { - this._addressObserver.disconnect(); - } - if (this._taskAddressObserver) { - this._taskAddressObserver.disconnect(); - } - if (this._simpleAddrObserver) { - this._simpleAddrObserver.disconnect(); - } - if (this.rootRef && this.rootRef.el) { - cleanupAutocomplete(this.rootRef.el); - } - }); - } -}); - -/** - * Start the global dialog watcher (runs once, watches forever) - */ -let _dialogWatcherStarted = false; -let _dialogCheckTimer = null; -const _processedDialogs = new WeakSet(); - -function _startDialogWatcher(orm) { - if (_dialogWatcherStarted) return; - _dialogWatcherStarted = true; - - console.log('[GooglePlaces] Starting global dialog watcher...'); - - // Pre-load the API key and Google Maps - getGoogleMapsApiKey(orm).then(apiKey => { - if (!apiKey) { - console.log('[GooglePlaces] No API key, dialog watcher disabled'); - return; - } - - loadGoogleMapsApi(apiKey).then(() => { - console.log('[GooglePlaces] API loaded, dialog watcher active'); - - // Watch for ANY DOM change on body - const observer = new MutationObserver(() => { - if (_dialogCheckTimer) clearTimeout(_dialogCheckTimer); - _dialogCheckTimer = setTimeout(_checkDialogsForPartnerForms, 600); - }); - - observer.observe(document.body, { childList: true, subtree: true }); - - }).catch(err => console.warn('[GooglePlaces] API load failed:', err)); - }).catch(err => console.warn('[GooglePlaces] API key fetch failed:', err)); -} - -/** - * Check all open dialogs for partner address forms - */ -function _checkDialogsForPartnerForms() { - // Get all visible modals/dialogs - const modals = document.querySelectorAll( - '.o_dialog, .modal, .o_FormViewDialog, [role="dialog"]' - ); - - for (const modal of modals) { - // Skip already processed - if (_processedDialogs.has(modal)) continue; - - // Skip hidden modals - if (modal.offsetParent === null && !modal.classList.contains('show')) continue; - - // Check if this dialog has a street field (partner form) - const streetInput = modal.querySelector( - '[name="street"] input, ' + - '.o_address_street input, ' + - 'div[name="street"] input, ' + - '.o_field_widget[name="street"] input' - ); - - if (!streetInput) continue; - - // Mark as processed - _processedDialogs.add(modal); - - console.log('[GooglePlaces] Found partner dialog with street field!'); - - // Get form element and model - const formEl = modal.querySelector('.o_form_view') || modal; - let formModel = null; - - // Walk through ALL elements to find OWL component with model - const allEls = formEl.querySelectorAll('*'); - for (const el of allEls) { - if (el.__owl__?.component?.model) { - formModel = el.__owl__.component.model; - console.log('[GooglePlaces] Found form model via child element'); - break; - } - } - - // Also walk up from formEl - if (!formModel) { - let node = formEl; - while (node) { - if (node.__owl__?.component?.model) { - formModel = node.__owl__.component.model; - console.log('[GooglePlaces] Found form model via parent'); - break; - } - node = node.parentElement; - } - } - - // If still no model, try the modal itself and its controller - if (!formModel) { - let node = modal; - while (node) { - const comp = node.__owl__?.component; - if (comp) { - // Check if this component has a model property - if (comp.model) { - formModel = comp.model; - console.log('[GooglePlaces] Found form model via modal OWL component'); - break; - } - // Check props for FormViewDialog - if (comp.props?.record) { - formModel = { root: comp.props.record }; - console.log('[GooglePlaces] Found form model via dialog props.record'); - break; - } - } - node = node.parentElement; - } - } - - if (!formModel) { - console.log('[GooglePlaces] No form model found - will use DOM-only approach for dialog'); - } - - // Initialize autocomplete on the street field, with a special dialog handler - _initDialogAutocomplete(streetInput, formEl, formModel, modal); - - // Watch for re-renders inside the dialog - let innerTimer = null; - const innerObs = new MutationObserver(() => { - if (innerTimer) clearTimeout(innerTimer); - innerTimer = setTimeout(() => { - const newStreet = modal.querySelector( - '[name="street"] input, .o_address_street input, div[name="street"] input' - ); - if (newStreet && !autocompleteInstances.has(newStreet)) { - _initDialogAutocomplete(newStreet, formEl, formModel, modal); - } - }, 400); - }); - innerObs.observe(modal, { childList: true, subtree: true }); - } -} - -/** - * Initialize autocomplete specifically for dialog forms (handles DOM-only updates) - */ -function _initDialogAutocomplete(streetInput, formEl, formModel, modal) { - if (!streetInput || !window.google?.maps?.places) return; - if (autocompleteInstances.has(streetInput)) return; - - const autocomplete = new google.maps.places.Autocomplete(streetInput, { - componentRestrictions: { country: 'ca' }, - types: ['address'], - fields: ['address_components', 'formatted_address'] - }); - - autocomplete.addListener('place_changed', async () => { - const place = autocomplete.getPlace(); - if (!place.address_components) return; - - // Parse address components - let streetNumber = '', streetName = '', unitNumber = ''; - let city = '', province = '', postalCode = '', countryCode = ''; - - for (const c of place.address_components) { - const t = c.types; - if (t.includes('street_number')) streetNumber = c.long_name; - else if (t.includes('route')) streetName = c.long_name; - else if (t.includes('subpremise')) unitNumber = c.long_name; - else if (t.includes('floor') && !unitNumber) unitNumber = 'Floor ' + c.long_name; - else if (t.includes('locality')) city = c.long_name; - else if (t.includes('sublocality_level_1') && !city) city = c.long_name; - else if (t.includes('administrative_area_level_1')) province = c.short_name; - else if (t.includes('postal_code')) postalCode = c.long_name; - else if (t.includes('country')) countryCode = c.short_name; - } - - const street = streetNumber ? `${streetNumber} ${streetName}` : streetName; - console.log('[GooglePlaces Dialog] Parsed:', { street, unitNumber, city, province, postalCode, countryCode }); - - // Try record.update first (works if formModel is available) - if (formModel?.root) { - try { - const textUpdate = {}; - if (street) textUpdate.street = street; - if (unitNumber) textUpdate.street2 = unitNumber; - if (city) textUpdate.city = city; - if (postalCode) textUpdate.zip = postalCode; - await formModel.root.update(textUpdate); - console.log('[GooglePlaces Dialog] Text fields updated via model'); - - // Handle country and state via model - if (countryCode && globalOrm) { - const countries = await globalOrm.searchRead('res.country', [['code', '=', countryCode]], ['id'], { limit: 1 }); - if (countries.length) { - await formModel.root.update({ country_id: countries[0].id }); - console.log('[GooglePlaces Dialog] Country set via model'); - - if (province) { - await new Promise(r => setTimeout(r, 300)); - const states = await globalOrm.searchRead('res.country.state', [['code', '=', province], ['country_id', '=', countries[0].id]], ['id'], { limit: 1 }); - if (states.length) { - await formModel.root.update({ state_id: states[0].id }); - console.log('[GooglePlaces Dialog] State set via model'); - } - } - } - } - return; - } catch (err) { - console.log('[GooglePlaces Dialog] Model update failed, falling back to DOM:', err.message); - } - } - - // DOM fallback - directly set input values in the dialog - console.log('[GooglePlaces Dialog] Using DOM fallback'); - - function setFieldValue(container, fieldName, value) { - if (!value) return; - const field = container.querySelector(`[name="${fieldName}"] input, div[name="${fieldName}"] input`); - if (field) { - // Set value and trigger input event for OWL reactivity - const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set; - nativeInputValueSetter.call(field, value); - field.dispatchEvent(new Event('input', { bubbles: true })); - field.dispatchEvent(new Event('change', { bubbles: true })); - console.log(`[GooglePlaces Dialog] Set ${fieldName} = ${value}`); - } else { - console.log(`[GooglePlaces Dialog] Field ${fieldName} input not found`); - } - } - - // Set text fields via DOM - setFieldValue(modal, 'street', street); - setFieldValue(modal, 'street2', unitNumber); - setFieldValue(modal, 'city', city); - setFieldValue(modal, 'zip', postalCode); - - // Set country and state via Many2one simulation - if (countryCode && globalOrm) { - try { - const countries = await globalOrm.searchRead('res.country', [['code', '=', countryCode]], ['id', 'display_name'], { limit: 1 }); - if (countries.length) { - await simulateMany2OneSelection(modal, 'country_id', countries[0].id, countries[0].display_name); - - if (province) { - await new Promise(r => setTimeout(r, 500)); - const states = await globalOrm.searchRead('res.country.state', [['code', '=', province], ['country_id', '=', countries[0].id]], ['id', 'display_name'], { limit: 1 }); - if (states.length) { - await simulateMany2OneSelection(modal, 'state_id', states[0].id, states[0].display_name); - } - } - } - } catch (err) { - console.error('[GooglePlaces Dialog] Country/state lookup failed:', err); - } - } - }); - - autocompleteInstances.set(streetInput, autocomplete); - - // Add visual indicator - streetInput.style.backgroundImage = 'url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 24 24\' fill=\'%234CAF50\'%3E%3Cpath d=\'M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\'/%3E%3C/svg%3E")'; - streetInput.style.backgroundRepeat = 'no-repeat'; - streetInput.style.backgroundPosition = 'right 8px center'; - streetInput.style.backgroundSize = '20px'; - streetInput.style.paddingRight = '35px'; - - console.log('[GooglePlaces Dialog] Autocomplete initialized on dialog street field'); -} diff --git a/fusion_claims/fusion_claims/static/src/js/preview_button_widget.js b/fusion_claims/fusion_claims/static/src/js/preview_button_widget.js deleted file mode 100644 index 686ff57..0000000 --- a/fusion_claims/fusion_claims/static/src/js/preview_button_widget.js +++ /dev/null @@ -1,53 +0,0 @@ -/** @odoo-module **/ -// Fusion Claims - Preview Button Widget -// Copyright 2026 Nexa Systems Inc. -// License OPL-1 - -import { registry } from "@web/core/registry"; -import { Component } from "@odoo/owl"; -import { useService } from "@web/core/utils/hooks"; -import { DocumentPreviewDialog } from "./document_preview"; - -class PreviewButtonComponent extends Component { - static template = "fusion_claims.PreviewButtonWidget"; - static props = { "*": true }; - - setup() { - this.dialog = useService("dialog"); - this.notification = useService("notification"); - } - - onClick() { - const record = this.props.record; - if (!record || !record.data) { - this.notification.add("No document to preview.", { type: "warning" }); - return; - } - - const attField = record.data.attachment_id; - let attachmentId = null; - if (Array.isArray(attField)) { - attachmentId = attField[0]; - } else if (attField && typeof attField === "object" && attField.id) { - attachmentId = attField.id; - } else if (typeof attField === "number") { - attachmentId = attField; - } - - const fileName = record.data.file_name || "Document Preview"; - - if (!attachmentId) { - this.notification.add("No document to preview.", { type: "warning" }); - return; - } - - this.dialog.add(DocumentPreviewDialog, { - attachmentId: attachmentId, - title: fileName, - }); - } -} - -registry.category("view_widgets").add("preview_button", { - component: PreviewButtonComponent, -}); diff --git a/fusion_claims/fusion_claims/static/src/js/status_selection_filter.js b/fusion_claims/fusion_claims/static/src/js/status_selection_filter.js deleted file mode 100644 index 14b78ae..0000000 --- a/fusion_claims/fusion_claims/static/src/js/status_selection_filter.js +++ /dev/null @@ -1,63 +0,0 @@ -/** @odoo-module **/ -/** - * Copyright 2024-2025 Nexa Systems Inc. - * License OPL-1 (Odoo Proprietary License v1.0) - * - * Custom Selection Field that filters out wizard-required statuses from dropdown. - * These statuses can only be set via dedicated action buttons that open reason wizards. - */ - -import { registry } from "@web/core/registry"; -import { SelectionField, selectionField } from "@web/views/fields/selection/selection_field"; - -// Statuses that can ONLY be set via buttons/wizards -// These are hidden from the dropdown to enforce workflow integrity -const CONTROLLED_STATUSES = [ - // Early workflow stages - 'assessment_scheduled', // Must use "Schedule Assessment" button - 'assessment_completed', // Must use "Complete Assessment" button - 'application_received', // Must use "Application Received" button - 'ready_submission', // Must use "Ready for Submission" button - // Submission and approval stages - 'submitted', // Must use "Submit Application" button - 'resubmitted', // Must use "Submit Application" button - 'approved', // Must use "Mark as Approved" button - 'approved_deduction', // Must use "Mark as Approved" button - // Billing stages - 'ready_bill', // Must use "Ready to Bill" button - 'billed', // Must use "Mark as Billed" button - 'case_closed', // Must use "Close Case" button - // Special statuses (require reason wizard) - 'on_hold', // Must use "Put On Hold" button - 'withdrawn', // Must use "Withdraw" button - 'denied', // Must use "Denied" button - 'cancelled', // Must use "Cancel" button - 'needs_correction', // Must use "Needs Correction" button -]; - -export class FilteredStatusSelectionField extends SelectionField { - /** - * Override to filter out wizard-required statuses from the options. - * The current status is always kept so the field displays correctly. - */ - get options() { - const allOptions = super.options; - const currentValue = this.props.record.data[this.props.name]; - - // Filter out wizard-required statuses, but keep current value - return allOptions.filter(option => { - const [value] = option; - // Keep the option if it's the current value OR if it's not a controlled status - return value === currentValue || !CONTROLLED_STATUSES.includes(value); - }); - } -} - -FilteredStatusSelectionField.template = "web.SelectionField"; - -export const filteredStatusSelectionField = { - ...selectionField, - component: FilteredStatusSelectionField, -}; - -registry.category("fields").add("filtered_status_selection", filteredStatusSelectionField); diff --git a/fusion_claims/fusion_claims/static/src/js/tax_totals_patch.js b/fusion_claims/fusion_claims/static/src/js/tax_totals_patch.js deleted file mode 100644 index 64569b4..0000000 --- a/fusion_claims/fusion_claims/static/src/js/tax_totals_patch.js +++ /dev/null @@ -1,30 +0,0 @@ -/** @odoo-module **/ - -import { patch } from "@web/core/utils/patch"; -import { TaxTotalsComponent } from "@account/components/tax_totals/tax_totals"; - -/** - * Patch TaxTotalsComponent to handle cases where subtotals is undefined - * This fixes the "Invalid loop expression: 'undefined' is not iterable" error - * that occurs when invoices have no tax configuration. - */ -patch(TaxTotalsComponent.prototype, { - formatData(props) { - // Call the original formatData method - super.formatData(props); - - // If totals exists but subtotals is undefined, set it to empty array - if (this.totals && this.totals.subtotals === undefined) { - this.totals.subtotals = []; - } - - // Also ensure each subtotal has tax_groups array - if (this.totals && this.totals.subtotals) { - for (const subtotal of this.totals.subtotals) { - if (subtotal.tax_groups === undefined) { - subtotal.tax_groups = []; - } - } - } - } -}); diff --git a/fusion_claims/fusion_claims/static/src/pdf/discretionary_benefits_form_template.pdf b/fusion_claims/fusion_claims/static/src/pdf/discretionary_benefits_form_template.pdf deleted file mode 100644 index f83c3a6932565f06833edc855c74e529f50a73ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1084626 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

      Kg2&T|b4EQM=Q+JoZBpH0M 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%0AI2L0dfD| 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

      FeLxqj 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

      W_#h~37 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

      8m#J@i%=K>hd zBIApqUvV#{TW83V;20MkeVHff4GF`E)_@l_bRA3RPVL+!PAHgUe;I_@x*EqLaf1wN zd);FN)exkffT|ODEw2co`yph08GfxK{Y=RXh4t@~*J+FI%|?rVw%ybF-%3hsz3Xw) z{I(ZL9ZVG8j09$*$)FF^3D;suItU7Kweivnzkey@bLSKOsY8Le_gkBUuV7bFysRqk zo{F|riW-cbVQq1eCZUv{$QvQwHUOobePxOV={xwjxbfNx(wsFH$d_KZ|7)DcoXu*` zj*iFw3f1D!^vWgGbCDOlKS~2ks?z7WA-Q1 zwDh}1dDua}FNMBKF)AdW6WSxnO!!syLl8rd@Y-W}oR-Fax0*Lv$8<*4FV~u=-uT2o zdL2`6dr})&_bQ<{Njh^YCD||>$GUWA-wi?|@K;uY4aiQ<{pgCQEZD2P*2LxsNvrYJqBGDZmA8IOZ$_*SQ&>%#vGILLK>&fKFfllO(}P9(jPa(Rpr zuV2ck&Q201P7B@jrsrA&LIO6OE1B0<3H9)PJPYQR*joafW7r#tO$yk=7f7hshbHq^EhY2%{;8kr&S`IQN^x$V#h*aK`Mb~N33F0ks*a^5e6=qdK zr%pxEggs<kmzZ*{k6lszGrcGTJi@zyf;N9eeq$;Xc7Jm*Aw1^z3Rq_AB{ z#3Qv=VUM=rCjKU%@mC02n)&kcrn4kzQR&;bScUxQxYWnU?C2N^za0-4-hbdS^v8hc zPUf(HGKIeMYf{`}Mv5zul~ci^t`>1?Tc%b!OP&gF*PA5sjKu_TJQAfC-d%%h%79OR z_=Pcs34I6C_dTJrEZZRAuz}6?ZF8}E6&aLN3?C&v;X}KeZxyg0M*|Oo-dwy;yHzoo znKe-07CutysbG8) z{y-nIGitwltLzKKCStmAg2&}Yams`FV!piD*N<&D?;6jvS8Az3d#aO!e=-2>TPW~7 z=Wz-lTx7W5vY3Q90wjrHRzXo|c_4Cb5r;i3

      ?Y5WWMpZ6JY66EcKBBp5%!L$iPr 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�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

      ehdhhNRFrA)|Puu+b_ut{t}ag40YGpa>J_ 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�DKqT-NkYqmtlnA5%_h~TVKa2*)H? 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 A?PDbJxy^Dqhj?qxg;Ej& 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

      }jRmv+7>z0#;H?sQ@;`XIEjja4J_8hu@y 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

      i3xC}$Cn1zK#Z2a1wK7Z8*VU&&3ZA8*IP5|`P} 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 F{|9uEtCRo$ diff --git a/fusion_claims/fusion_claims/static/src/pdf/sa_mobility_page2_sample.pdf b/fusion_claims/fusion_claims/static/src/pdf/sa_mobility_page2_sample.pdf deleted file mode 100644 index 6dc74b6b79c4687093260ad152fdd7702e71688d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 241053 zcmd43WmFv7wg!q5+}#>?Z=B%n?(Q1g-5o-LySsaEf(CbY*WeKRk-hi5=gJ=A+Ii!> z{?XK8Rj+B^{MM|h*-fq>B1X^5z>Yw^y)!X`0Lukn0@xW@A@K4t%2<9fHFUJ}G&KP* zGs*y1fXqy6tc>yiW@biF01GQS8!M1e?tMz-eTs>LorzHbpbg;Q00LMzSakXL5KKRr z{9Xz0A72RU9RCm^Vrpz>Vya;1XzTPYQrOPM#rBgEfQ?bX(bUA!*xAkzz|6wO$0%lL z<8124C}v~mZ2IR%7$rrtd4WQ#f*h<&?95E8BCKK}qRgB?F(EN7CJrVRE>0#O3m-3# zLzD~1$;Hkl!UhC#aBvE;3X2K@ML4-cMMSwcImP&N86`iNn7V6o0hn2VzXxV^0M2*) zlo(}9KbbpQ09cqferx0Ur6F0C&jy{+0mkqhxsmWRnX@JwYBAUyIkgdv&M0;=odU{C-G6Qa zygVALO%si-6PfN6Oi~9%@|j{N*q<9&+Y>x|HXD*;N$|7_BLrTi8(9x_ex#dI3X%DW zAN+dd3vvrLGVQMjJ2@LVI=efXnjtVDkduqbi~Z-A|3?h`|7(oE3}pES zB>xU;?I@}o4j3lWzB@<(w?ByF z09Ygrb{_Vx)V&mwMK(^vA(kQLU8Y%u1yOHt64+pz5aK7huU;7)XLkR1E?;ODo@F9Apj0GOHo;akB^pX{8S0PMeMM(I7>KRKIza(2>YVgEgTCyqb={2>Uy^2bR4)<04W z!1{X?B>?LmQUR>2zel=^!j5+KLU!)jzt3T3W&v<;vFI|&zEg+cfBNq`$Gpq>OH(CN zCp#BMW7EG#$IemN-q6_eHv=g%0XY9OR9KlA!1;#`zX|AF)!)-B`b+>W;BVo-kC_2n ze`x;4G1EIM{GsF@Bj)$fzs|9|5B^$|MgN^0nEz1!_j$ng!N1P1y_4Oa#PUAF{yt#) z7eO5FgFk)zKEwG=Rew7Feeefw{c)O#%DV=vf67!*d6&=nS5#Eq#k2nDaTS$!>A*j< zd^bwL(au=e)LEPHeG_0*F?Dxll(c;hr?4)ghP;uLsqt@%C2ik5`^Tbu@2_|EbAG2_ z0Mnnb{vG^(6X<`FL_+`Ke`ZbwPL6lonK^a;j>Uf?>oOZRso z{q2lD-gO!OZN&bq-tR=qsO)0o{F{J(FZLG||Ed2!l2amrW|u`p;($egNr9f~pPc{WodxJ8XZY#sA*G_kjPG7XAe{ zEkh9_!26E+4!6Gx*MHk~y3tx#FlJZm3H{Gx zNmf7@(IX^_FIx0d@{3CXe#UoqmyF#Yya9Nbf8)O2hWwx1$Hx9&dhdUWk4aVzwmP8N z-=Rc6QyCJO9T*mw9@H204eT2T7(9p?5nTP>Sou3?|Ib!3v;5a-@J|Ox2P~K%JjAAN zmXVb0wwWJ8Tcw3LDFg(MsC*5w+y>EV2q`@Hh5#l+EvokRZ=4irHLO4LG2b`Zi`cs0 zz4qe3CA<{P6>njA*SMWlHTPzw6&6Tj$CJ$`rIM=@^5;lujYRl|Vi7Yl(|?Kje=;1(tF;@o7@6+ty*d${=+6pt0i&Mae zTG9fCIg2FP@+IkQ2TfjYu?#?RnXr}r#$&%X#s7=Pfd8-1#2*;=4>a*75^{n|!9L)n z1tBYxq|knb13AHmDgGO?es9D77qi|=hyO2t@V%s7$%*=c{&ME}ugTucm{?-!EH91L8X?=|1w z6zzZ26U;3CEr-2dxxRnDn{#h#hQ7Qiq zRQkJ8gpHYnf%)AyW+os56D!9*C3^o;Q2m?Y;cp--{ba z2k_6jSKi1<+1d6VSg}|?^|E%tZ%(|^PmOap3k`ZIq}ijD|`2y2S5u85AVVO|9nYZ;=)(EzEIyy_{M8C8)DttnMU9M&fL8~`DpA(`_-L3b0kRbqXq`rp=~*+IF4y8{k$yzu_2`^$k5NMCqbCu$uZt(FzML1G z#IzL6A}$?5x$Lf^nJ~pdv2#R=fH@7(9>*?R*ASV88O1H!r8cG7{i~)12=d5IQ%vg# z{wVo_hu5X$iYgyc4z%9dQhJi;*37cDzOZ_peM+_OREy3TaTd?VNe#2ZklHfqcH6B> zo6qAWeGlto#BWm0=QYw-kC9K4?;(`X`}MAWZX~L?`sivxK8x?0ry^Vp%G`FkJijhq zho_ft9FhK-9wXTBt}OHA?Z$Zavw!87i{g`!&%@P=$cP|0=Z6fO9~CBgEWSAG+~!K; zTt9v-9nZ)U9g4o7A96!y(`7TPUL9TUUHdU)cjkRfw8Z+hm+bevc77=QD$^F!b&-A> zl^)@Gm0FmI8^Z&~Ko@;!&WSr!RG%|#^>B8E#KGU8&G_bcd3F0}_VCOxvGCTOtMU4Vf(&*T1f|AS+WOP!6o_d(sqZ|=8NJ{`VKMlZfBpB{Q|ABj%( zqOMQMn@6y)78pNmw72TKIXzq*??3lPvEAP9oUJSzEHv9OOxW2asaIF8SG{$%7wIK) zU?npy+~khDed}n|>?+P1VPjs~J2|=btLPC-;$PL%n-=fn^?UL3(XC77*I`&lPR2T4 z*KgOa+GywXd)sk*Nvc;*R=?TaD?ho$;=lrCEHq;!KQE8mmZy)c-S(dl*(KRAtgmQdbEcC(Z>Qu*SsQmoFIU@FSKg8*>&G+h>ls~s4qiXNrC^ZW4(^`Qv^K8>uSe9U zg{dKAnMTChnUmrQn#I@5y!x~)A4+^4N!JbH`1JXz*8CV^_>%{+-D3FdDzhXr&6N%` z)ekhwuOG(ZMydCUL>>38LReC*wO+WXePtRX-FmG4ThP@u5f;^F$(F>>=IM(jYxfncXEG!^cU0f9 zep+J5MBlNYnku7}4pTh&JYkB|fo1P~iQ_xIZ0avmwk+nJjQwNK)Sn3AJ&*?k@`2+* zZI|XSut}s0VvmqyD6JbDa+N2&1|!jbDg67Hf6n`-d+-tDg3j(v}WzxnmN zhGjkJjLOz~^+Sv1bso3N+tcIq@ncai_N_Ttxl9*A&o${6S@iNUvXt$knd|q=nSHwL zf7qi`a&-7c5t0%@%V40mIi=s_cXiA0)^po(vyy&tI|fJMuPzc(aLCAlTReNUH1@F9 zA0<9IFn6_*ew+SAk!ef%(V$@g>-nF`(=Z9U!U%YJ2;HE^f$Hz*_D&790W*Q@1GFFjklS5xw}Yunh>nOvD#=%1S;H7P6lmawoB~ zX>xN>NW{V%cD4EVJtTE}U5atYST)9i{DE*@-@w*Re=WgPnCR+RhS$?3bML$DP{&MR zhq^BK_-!OMo1An)mJB9a#Y>tJ7)pj0y&l(h-e*>FMv&Ebt{)G=(dZEw@v}GBCDHs_ zOnD_rqxhRk*I}Lc@~;!mS&w{nmCk9dM&C!^xb3O(QngE5Q?Dan?qmNG&Q5{HW(S&z z_S0QObQfXT>qnTP{4WZWNsSzPIyYW5XQEl^ulsjD)2{huJI@ARH3?V`mJ+yJY}@G> zjl)^0>Cd|o2g4fUe9L_@qtbc{`kgY5I-Y;F*dyMOXzK<^KY#S@1e1wds;p>2!%+As zO<3G|!S&q;&PpsuX%9dnsW{bbaHM>+klek6;lqRY!6A-s?p$~}GFYtAVtA2BcJSj> zeDO}W>A=(!i}G`{Mw?S1dBtc}Wnw|;$mtegsouSI>4xi$tJUqXE6%l{cJ!cq68E%D zvnJ2>p8Igy>3XND?Nnvu$6bJM?a7Qy?AWjv1Z~!EB~uuDe!sE0Ws6nTY`u?L1#;0t!^P*aZLPSUcWFW zPdS!j&pw4LEKE_l#lmUK;#du_VCaI*xFx||7D8eF%#DkqGs${$hlzUSK(jF(t`%&D zQk>)1{CWHG8hZs-remNd(+8}^4rDRAPEV#Z=s{LfRxZLKlsas5$tIafb(Pc=BAu28IK=5mJwauW zXvs&hiQ{x2-4k|Z=TK`hAYIVsW)*ua&ty@hBb_eAd!nEfwdevoF*3-Lx+Fszpxw1m zYwI3;k9wtu8X{M#qDqno__`;HjBCpQ+-S#X<-XO-o*kd&gFLy*{eCie_j_}`{gDxI>bN%ttZ}KPl>J4*;uSA)bzqzK}T|jP!zLPsf{IO4F zA@@_Gw+==H|HN*KR_{xTR@hJaQ&!!w@)b3lKA65CDctk^#;9x&N-)c|z96;LM2pp` zQ`_~Ay*>~~MJC}3IMH1V<@cOj-l6qh?`Z6|zp4DHA}i%%JTTADzKJ++i8)@5w%*lD zn)bT(&5q@Hs4{=y>za^!Z7dR_9npMHr?7pNvi?fRPDPv+v>F-xB zO#M{2r&>_*pm+2t(3yJDcCAQKZS6#rO}${e?lZ_|YofnCPlyT;p-pED6;EI89;S1g z{!P#vKWqw*{s+>qOW`tssx`W$jA^x6W$syVK-=jKJElxWmLpo!WzFA}@YNvq}__5F#qbuHKH%LaUDb+FH`qHbT#sX8=icp z-8900q{^bp8-nz^A4EIXT6*Wq;y%msqQLJv4N^{3MfEA}mq;ri&qV9>JLAr$Jkq?B z*vV{Gl&a;{FddQOOu%v*Bq?>T>sFTAEXz-*QP{t26FObEGUgql$V&xbk&X}Qt-`H=zZ+68aS+NkB;-oxYsSW zFeUJN8fEg8fWm>lbHgcWhMx?=K;8+WY@JgUJRRuUSkXDJwJPgCm8)0&>39ymHx-%t zfqIjyl(WUdpnTE>HTzpgq%?#pq;69 z!dG3sOj;VU+JoCqACx<1TzDFs5*yc)I@P01YDR{lvOy$Wjq5NT7T)BbRp36&h;5JSe`mMJ;zoLh}JkkEW)sW`3Q+uMB$@<^&Ou zq8l*&a-%xHBke{%L;z#^#yBj$^J_0g_=V=poQIGBy5&Q7foXOy%=f4?5$6nQ`;d|# z=WaE`dPkELZxbh5P^I*}C#1C!?Pt-ffT1F<}| zU0ex>ZL~U|L2b@=B+_XRmjp?<5L?EcL`euPjCim<{^<{!1Qu3xb)(2uRT#Vin%>y< zdDaTGyS3Bl>*?YHa0MsTM^#XbPJ1{=Qmmlwr!~82Tqd7hm{mu+7?#!2bzrV>Q|tGwu0F7X z(-V1c4A&m2xzDNTK_^BYlwQoi^J^F2OAl-@B>8}+QqWqHlgL@+!MdE1ObiKUr3o9& zj2e0&DGzqY3eTl_7Eqg-NgazEFlYCZpALBm7Ry5qI&_OPTEB|bI+{QC=C-4qx$TKp z%HOa1$Q|guoDZL*-8hhu$Q1D?I{|v}TS|>~@Q`q`kyp$}mV8TYMpC;L!FS_uF+RWL>XM6C-XCVCCXhZsH7@8|)} zqIq@!t&s|%<+c14?8N1pIPLr4ev_d)6d7_hF%C7u0&--U17gZbCM$T3l7;w5q+~g9 zxmwGkLglj4p~fv*c%$iGI&<9evjPy3PzQZ1tH2v7U6M8i%UIV1q*UED|ZsXAI~*vU4_@c26NRa(A04m)Se>K7!Hr6GOi4_nKe{Wn>Ddtj%#X? zrxRcW2umS6`*ny$?9>7%u#^=NdF!RTsp73l6!zj`+(^jRc%b2qETHc(qG(Qn9sf1Swsl!)LV4F3uG9NN5_*iDY8d<}2yv1J!`bYM@i zR+6hIz?3yeqW+#aehDRAZ^K$S18-pf`@%}+#tKu0`sD#39s~_ka8gnyB;l7Ps?a2* zu+sGYa{Uxa1dOPxj6Ls4Yl|K+?V!D36Z*D%^K?tJOENjIl_Ao$>BjzSLMNn;#ddwe-u^>@j2bEX7U060sgnOFyPa zyYF12^)ys(#yMa@w#Gl)Sg*>&Rei{4a;rj@XiNJaFJVC%kp9X|KCrX9IQ4g7qCuan?{j|_NKSf%opwL83fE8B&YOg+E7Cf?#?W4avM9v8iwB$kq+K zG9wGT^7ZCd6u536(Dip|kBql>LwR!{R3R6X*+6Nc{+d&4#~((eyx0gp8?}xE z&Jj_2s)91_1gc61J9v^VXRHpXD#XP(&iwVJFwu?Mi$W$PHL~P*?{twX5{q;zoGg29 zbVLv`&l#iq4)1h)wX>q8sOQ zmP0jd|AuuFxhGmxaNQ7~{|&ZFOA}iJAPFKO0;>^VSeZswtno90I~tw8zHqvocZE?_Uk%|0I^38Kt3 zU|pumad9S+jmqEhFa@SS7>JX+L-x6NG*{Rl62;IE;1X}!N?T1@ciAqvSWG_YN z;ui_SAO?KQ4Yo@JL0?qW0sN4_GV1I5Arsrt77INyA+>j3Is{V6xvOz73o!VwQ8aG& zxjt{u7-NyxVvPpSHv}t;#4cmAIs811!AHjlvjsaYW4~BP;`ptF_`*HA@mo$I$WG*J z3dY9?S7}dMQHjdMr=cmw2EpQN9NI?MSq345Lh86-8E`$TkPpQr1&o5pu&y*#%W(5w zE1=qnHj8S+Nw#BuaiJ_`L-UAk6W!a&;8BykhaHm$L3bfg)q<-pYLK+Al z)x26no6uFfvmXIHz;$CCB5q1>LF-qMF%oKwhEZu!_>M0kY)AtGI(VWQyA5G7FZrdR zCSNw1s+KJ_cM*eh*k&?hjX5vRvVtY^iw>3DxFIU|XDhxW%?b--_904F(xb}7qalCQ zd6a}_^dlWhl!<#?n2^e(qoZG>6Pch;$2l^ z5l9OK1@M#7UWFVS(Frs+Q$5%7O=D^FX%bG z8cl(D&JK}?wLp;ZBBq)W4!%v%Dbp&+EDKGWHXdzgQblPJH1c=M81qMxTL=cZ0GqRplH^9v`lB%sHHRMq$A%$@v19hv# z9Mr;psEQ?b0I5@g}?*pOjgnn|HAy`{q018MGQ<4slP_t!X2G6h@N)EXmr@V z(o<32f)H);Fa&t{BXqZgRAz?7*XYBHGkH_(h4R*>GfnrvQSstcyP|T`;_f7tLwm1Z zA2iY0CldBju0YC8j8TiLDIM{LQ)^;i%yH+pVFvIaJG^^t6JkziXrZpMD2($ zL0wZ1iX^c~%=Gseeyq3pHXknGzioti?YMsZfmkI<_8jj7HHM`Q8qw8a_zFGB<4Xwo zi~~pTlCTRcsbwDO%@2S>jRJxNh_iAIdyXINntL+GM4%qY`rhUc4r zsni>qtgpKwhyYz%Zb&me34?tpQpb!w^g$?^R)14gsW;~UB4iASNa{;@BWi`6gm{5` z&T*L_5(|-d2YVxu@A<4$pAX=$uW}iMI{i)Z$+I-CF}!Rnd zV1ul98Qe?U(IM63F3tpovjEQhBlgv`8cfzQ~c1#sZTEsBt(5?Ifp zKkjjyYxyl>jJr1AOq*4n9=NEV5aalUg_uj zk&CaXWEL|9$}{$;t#kpA&H+U=&{qlZyBhhF^^v?z1suwxu9BuGrU>|4E05TUTr0}#y``qC`Vi}>InF~NQzA{g)HSk-nzxQuis z4@o1L=NW$#quZ#u&?^xbJyl+0??l$5>PfnByxZ>I-k+8{jeE^7Jx@wtq`; z6w2~&*W6)K@P@~aFv^U)}0$wn32Y;9zFFM~c^8PGj zg3cd@Hkcqp1e4Y=h#!p|WdXC}<81R|t3@)MGYK7)g(nf8{^JcjxbBFQ35`zAjcg5W z??g6unSgFRYPBfVWNPIWwm>U@_@i)buCT_9N)+R076xB0w%DDDSu}z5sB>S`1kDGX zwdopsbt(KB>#zG;B!lIme$G18bAnXnrA~2+(zvj()U#aCRFT;Yp@vsRsbq3~txSU= z+Ct0u${BP)Wo{zcRqzGIkJPmw1$(l54z+^>+ZGmjrS}p~8-Y&R^kIn%I*nA@iUN{f z9t%EfB`7ctl~!Iwv7I{YYe0Y#EY>hk#cc|)hpcOUE$+DV2^bWz`JQP&t@W*DxPECptMR!QL#h${b z8#!St61X@7P3LBRj+8x>y$Z`?aTbMIL8`51)d{*8yHkmSZRS+kKG<=YpbY1HIKys( zhO3@CZz!e6Q(e-s0+_mr3P&W;B7(I! zb|YyKk`%#7o21*&>duP4a$BjhpxWKw$qVl62RtbSsi2$;Xr5QQyG%ASO<8sgV@jt&JZQ)5)R~sB ze~LSPpStvgAM@#U=SNj!2lcxf_wT}%>drpdegOn+q8zeB-G_m_uJUf4KWw}{-?SB* zX7RPPdV2s?84YzkR1FRvZV9`6AvIYq4-18(Q=h1YFs zf!qFL#zPyUKuWJQr`XTo-0Ml|VGQoxxui|?vGZ&j3%(;M1-qF76#ys(fqUXK6blCI zm=U#ER8#2Qw=9LOCPl|1bl-N={Xs5q3<-Dr2>OS_LfH@75XQ3E$M+GG&2YjA$inl2 z_rXL(Bz4qDVje$`eZv)6aIJ>6LiZju;OtizjQMP$F0o@R(NE0gckdY5nyYoSovp2r zJYp~ojm52ahp<0|-_Jc7uQ#86M=&4cS$dcXn;ku-l-x*-gE$oeDeUF>vaE3&Pbh@2 zg0c~e-O7bWFJ43JEqNnrg$5m%|A8$>6d5qtD3af%5Nn5G+fm(vT*p5C;5f_br9X*j zLpt3|cF=ZjIj$Jm0zBoJSZ7>&zjrg9U;){EE`X2BIE_-DCVfJJzsZ{dm|zmFDWYbL zBd23s2uGV}u~ua8hl&VMQyfEwbJ^n9{@k;a=k)N4>?@SZ=)7>^60p~~GDYr!uGP_G z%Jc{M7kLU!jAzhh$^Nr`8nL7;jI{6*+^X&y%pSH*r_=&eXgn6Xymk8t3HsonZ&dL? zHP9scf@d#o_=zTt3*TG&@hCR5oiq6 z2&K~KAoG+qfP)((r@+x)R&83;&aN~1eBi^=u#P}lB_p&x9z0!6L9sy)MjMDaS#n>Z zQyb76Y%%ucMZ}B+E(FAvfks(=wcnoUh5A*wB#M02fjTfmNeet4*D&Yz6Ze^?Y^-mP z=j^Tb3b&@)wv;pW`89yEG+u88Nf3*+Pu^4k1s{EXipVg2DQw(I>r&HM`DN`bXPvs` z$k_Acv&uclM(@v&JGzp`nvh!)0*B+{@HFP#T?gyEUp#KdvWd?0*wtXfyXE+A<6ZkpTs6xkHoAdCiu)#4qFb zen+a(9!Yh7QuBL%0HC?TVot~7u0#3>iM!81$dmT`{;1{ax##@(^;5>KzO_|DT~?x> zDt~NcS2)`!T6!|TT9loiN{kl2fXp*LuN3+h|3LCv?n6*t0MhZ5Tv5JR53vM8f;sl&Nx-a5;~AMp0SG~y z-e2BM$Ge2T()d#4q~raz!xl{~$7iCUuGB1K6&i0YvIyKLsysSSK*1gde5INbkF{{` zN*vt7Rv48DhRfwt&O^Qi8(~eRdqe55Me|op2!Xl@iQ8mEXMtnPwnz@@E;6Q!joPPe ze(PT#XRYs4i9()`Va}T8Ew#c|*VeG?WCx?Iz=wi@4#uh9qX4~0O*8x!RAPb6WWX!m zUz>~LE|{NgCHazu2`v@Zk(%1!dG~E(RUMjB_(A0*$<}V<(NiKeCadkGYoqz3FV{Gd+8g~XZGNqlXbO~ANGTg4?3e!$Ixe2 zyOhmA1i|NVBccV~m|{STG^UGUHi8v-^lOeh?5y^`jCYank+9u2V>9oLc^g57;Un9! z*i5CFRP`N(*_ouPFjJ7cmS!`uHMwV1X zH4;cAgN{8nsJH4$URD=lbm6hvKg@jCL_f3^K(rif+3)V!{~-w{XDQ3YW+kfwvjyjaHOf=?o=qKp=BoVu>M&gwAkEnJA#| z_+EnqY?3fBV{QmKfw=d)Uzn?L3jtk62||NP3<66*r=q&iNg}Zgmp;>A$7vG+Kc-fC z=I)VY_P~G&#`3|nFgT}TXegd^aQ%QHmJ`9*xY`E>vZN{Fi6|R^TeO)9(pd=*An@gm zx)7O!a7`Eq!kES`IrK=B&N{k^p~rBsq)|DH%c0Z@`bNF?a2<%#!JCVieoY|UU(EP! znx>`KRbrpx0M*puc9|9SXeg`)4atGr&Zx>s_7lQ{^GJy79y}VYd%y;C&tyyA*|0#G ziDw|0<|PNZI6K=%En0ZOEmG>f`}X1y-%@r7b?;8I5)ojakrPnEy8HX~zmzJH#JMhk z=t!m@@_k0N&qG+%1mDDU)$2X6*D?29kN8}`H%8SC7!x~nA%Vdv^dPcLqeo||8kh?- zu~(*b^Noqzlt7BzS_~_mv-6LzA`*i5{Ydtl5_Aw7@z`V{k1T9b&$$LhZWPsAmIA83 zp#3xW=EzHwxsRdn2)+Z&dFsdGbf&{J^TM89+d6aQpSByD28iG(A*SpBW0QB2`=}NJ zfF7h3Vy63{^e5cto);@V+$u6{=O$*h?$6RJ+E%RNnAfH?D51#7AvK;Uk03GZ54|n`5H-gPoQi|D^p=*s<;=s{&ch@-#Vcwhw8$`DwIJrv?Rt)qWc}s2v$uXo@VpJqdyi z3@Fp512vddGZPt46uTo*fT#od4DU2}yZM>JsGzSg&m5bUDTv8gC= zxNq?|QFTCek7ShyBp4wvAfXU)Y<=uBn6($tz2y3Zy$VIDQS=fo5l5n?%5cEoI}Tzu z<0w-71QE-!Khnbq(!+W4d0hQt-0QRO>x=Ncwq78(ZzkV`2j&Oe7%Miaj$v&Rtim<5wHhdRcUtBzXV0!@p(XIzE?-w9tcZfTF&v*=&3`kHk z{fDWOd|bSXLw|cGrsW%de7BO4G=~%{N+qv9ki_>AP z^I~7x6uHJyG8+{xPYgk$yAV6kGdBo2p!Y0aVZ)6^BC3Zpe3C8=8ElYPF_h3&3YGR| zq*P2EIB8zV6eij6W%35^Yjw3}-xxb!mXB8`ehg1X!Hyyy+cC=x^D zI2t;skTyd_y$M4_{g=y=uGcNR)Z(CUs%B`E#AyfrlH3_kxWYAPgWTsZ!(5HaYv0fi zBYequq|lJ%&mrSp-RyvlT8?#?P^GfWOC(6)v4r@~<_0BM{5P*sodehc5Fi@VR}&01 z>X3W0ZvE3{PM<8nf_9^O4m+RL4N5@U8%AE-;6GbYVh<1Kqhpti%^)(VDD$1*sxql8 zF_L1JRf=bFY{kKcT6q;pzrix8tSPr=^Jt^p4UASUpFKPU=BD|SHB|r6*t0-_b{Y;* zE*5zCyQ}9L%MXIXWW*MYREv{xZ)48Sg?MtM5gIUIriMAilY4g^L{iK#ot7l>c9 zOZxZV!bjd+Z%n%dyt8(E2(`ZKpJ#nVpMt;M}D zJB{w|8m*%UVexG#@~6k&dvP$ahgHykD*MFeD;rqws)Kl6jW522Xdn=!h{Fe28pkIz zbt^Qs2jsTnE?T4o5qB&am4kbf-Q?+!dsbw zuB_U#ff_>fkO3^-EEk9kJ3T--MCq0}nOt1n2wQGRI#`=|DVFdAT$6~*`MEDUd&;Th zSI)4@Q2Vk8%v(n2(fj|t@5Zr@+VSE;K|qf4xXg_#lF%$n zIuQ$|kuHrG(i zm)iFMae*!QuP-?Y{xI`C1{UWFtD3!~>kFDzf_a7ip`)fUrd~z8xsoLuEj&IExc;>y zX%~76RAPlZY*cQ&Cp#yybli4L{K6nbA$%dV=8|L1E0(Aar>J#R4^oad8FnL)Z0=z1 zIoc_T@3Os0Q8(QohId5C)6O?g=!GRmL4p)rYWD-E@If{aY~z2cX(lU^LC<6qP-lv9 z{#n|GmE$mahbi44=@5FaRp~6Y>?{yoBC{P2p3OelXVt90BCKUdc!OvpkuNFA#{&1; zM(q)D^E1`YZ(+1|8JF*s@OV2y=<=5sZeN9a6ztu;_wo4WBK}-*Fcd{C$d%+yFIRqCam6&$L{XY>!Kh>R+2< zr0~0qYbYyNjH;Qm1ERbUQqou4-3-L+OE0((!D`0pXSU)Kf?!C)>%qr;88E{NvzT87 z*bg*Hvh>-EZ#47<20xBJRjD@A#df`P+Mnq{J+;Bl@YJeizIVhpx$fY^N|9uEU!;Fq zH=a}RBF``@Ufo;A8P3NLMnOf^2tP?{^I!=>h4|=}sGj`c6m}jtIZyF=JgTmY&2}06 ziOSV<+NQTZ?-qo z^e_~SUBJ}$-F;^uh)#xJ|G1mb!C-(OEQAIHGtZXnbG!nwSVk&wu0SX7&n_4+C^5Q{ zi{5Y`NCoYW(wZ~!7M2J=F^Q7@FIF2GTMaFmn$BZrg6Eb=jN}~_tExIX67!gj!%l>;3ug zno3=YmO1E+nOsA94w=bEfIkR|Hdpn4*FXHeGlgA&w^ZfN7ki!a6~C9jZhQ26^--kE zkk{_&R){7k!fs@o@ot5oK`fR@i2bZl+9(@lGap?U>{ zE(GnP7X>i8U8B8yk2A{lfn2P(F$LH#0y-CUVbb-<$H!XZsTHl-gQSGBFV#qd=r1Wu zmpLgQ?S7x3Rm1g8=?vh!&ZZK@;ZPal(A@@8{F!sq4VtEGth-C@bt!LNWG0`EUrs!k zi0%!v)GLWTvW+ibKp$r*AS@DxBM=je-UV?2jAXd|U$eLrWO?tcR*M~0akF~@titaM zE0o&C0$4Ei0#r9HzN}a0Qq!AE1mM;g-w9eCpY>=FTXY>=QUF@g$0zX|a?qQqeZId| z@#P8i+xyoC`w-B}7FD4>@341cV%iejKol=#Bv8KLDAKZiwY)W80HGcHb=$!xy}?Um z8UTPZ?}oz`Tz6O56q>S785RYTnW8NO@d;>yEitZkeYCCWFdjAP1D1W3T?<&jF>}X`e%-#$_wG z;xIdI@zoCt5gnqeZ9p`_m=sxNH;_JO%B)kJ0U9xZJlY0=B^PK!5$Y-fe623j|5+#) zo4X+%@hBegv~zAA^fD;&n&0=@yAfv6o$ovzJ(m^qiIu^_f62XrD>T8H$7X32aHr!; zlZv-^qxk;2G(`vgUq z5ot0;HL$W-`+LbGRBNacVOp4Ws4^W|Q|(!41qMcsL-3eZ_TyyI#nrY*@qS)jr|C_O z8En2Xo~`D6s9lFB8W&G#7)V6m$Jf5js&=uF7d!jtuD}Xub;lmN9+f2jxCZ6*> zT`|WD+18~@7ra^BAwsl}!o>sGRsaA#IRBE`R;QRVi~)JxFBF5UW0*(dEK zp*Q};`KvdZ-vi%68UNeEug)LpowmE>&Z3>eXb)wWr22{MwbjUWy&so$c*Y*@{CyJd zPs_^#lw9Y8Nz^_f*YaKTlxXmMJ803kPq)u8g?!_srwuN)&@8X8#PGr;DJ@b325=Ll z=>)k(*xnBPP~`vBg8xgie5i3@j+n&k6Kg|bhm?7SGt z<%B|w8UzM?!f|rX1J3>%AkenkZD%i*m0LN0Zq5qDUvX?UDdMgz(q#^KzI?^v6e<33 z6Vc_DXqn3plA@!jQ_xxy3r}Te$IzwYrb*>G%2bYrq<)JxSD(FkkYifkq;9l&<70S3 z5z1O#1FfBF?y7KWqw)f++u}Zpi{RsA6GZ70q{noGkvB=%QTC#;e; z^o@Le{BlS8+98swP>Mmx09gMA$kciiQeNL3iV5lsIYH(9FKs`1moJN3U!gX=DQN93 zf+ECyc9r8?+;?8shIE3fXc-Q5WG)5P+VHZF9`Vj+zV+iXG2jYKS2G zHt1tTy0dY(lb0TTW-brWorbSc*qZz!LIVf-cYH_az(}MYI$nACHQ}E-!_2BjMYoCwSkywBt>4=mELD{%+ zwF-=YBgqEi25LW}>C%$c_I!=m`!{i1`cIU~y0-aa3SGANmk9SOWiv^-%*5J8A+Y8G zR`I!{NMo^Oo}slMV5&Ch#V~AA@i6nS(}r-CDDb49&kDE7rxvs@xZ3B$e?}azHGMP8 znl_-U#L4)A3Uy$nxCnn!D$T6~a0$E@5fJ$>fCaBLvRI1JBjuoKZegF-huYm%*_nl< z%1B3FAwC<&wuZ;tYy=9d(%%ye_>R#UkzTY_7vPQlQ>g}C-69Fp=nH`rD11SRS>F}7 ztWkbx1S-y~%f}N2-7lU3E$f2oU$`ZZPs$1 ziZj74{8FK=3V4;U>M}7~-BVFU>d5kDh0bZOWBYzYs4Sb|yRe$yOgYE}N`TmFo{|J2 zirq@BIgwLgja_;c0J}lLmn*kUgG6l4Rmc5wqz6~2z)M>J>7*HQIY)q8BMZYh&M_mJ z>IUnAx!%J=>weh0T~nU2BJ&Ol#s7!3cM6hqjn*~GHOsbb+qP}nwyS2@wr$(CZQItY zsx$ZL?%3;euf6+pMBn5^Mn>Lbj5o*lzi&Lx3xSOffDkjoskZt~GoI_2`K$S(i&yh5 zvom)tMNI?)`7WI^s#L+byvc7Y@=KI*dvRM$D#Ur1L%mFMNrnPSW?uLhg&?VD*Y-5o zNhXWtR-Rs>2HY%SLBPNQkkn4Ek)TIbS-2T7AG^bkyFVLG4NrxWOxu^ZD?S=GS1zwJ zREz!yy6Uk80a*s)f^Gsf$OWF4t|wXrl%9eipB=qZkNeF8HHa@q{u z1*wyZp1NKFF?zi#ksl;WNnZzW3h5}8YY;e;pXR?;3A*cfid*ZZ0MT3C^jBQ!RP&<~ zZxnP?>;E_AMeuJr2LriZZ1PD1Bc^-LGtOg7?^R4|Wae?UXHivfme*~CV|5mGiaA$|{9a_eiyV#xv(X6&TQ_HX(@c)^>Ba~BbJ~n&QiI%( zClIDCN;Qim}WnsghLkCE)7wOQ~+`%k)zM5a$QJY!c-1kL#QZD%>2esi&&D8w(A zV6eW{n;bUY+%Se};Afkz7QR<9`t5kx{1)4j`fhfp1zxpDybV&rV9iWTLu(6RF}Lmq z@AC;6l!|SITNLHiigkEph}{&a7r^Fm@Jc;${u1M}#=fhHlSV8}Ef}y_8oXYnRMdhu zQGV5p9>|yomknho>J8*fIe518WNJtyxon|=iY=h{S$awmJdIoQz4Qft z1vrbmkrRu)l2A#h4kf$V2LcYdJO_^DfaEks#~Cr6wxl1FqZCA(NOTQTGnwET0PLai zz$iLE6c@MQ1JNe6cjDw;zrhe_ocP@W^D2Enjx12rtvUo#OB6_&77 z-om+u0;3OvETzTxnDnIE*E{}50iq?*I=6RMpcx4Se4FX(R<3<&FDefJAQc~Dog#31 zz6n5k3E0#3mKW8_Ntr}R1?)RK&KNa$YUSwM>e8|OqcU>LNn4oBvv!Po&A6iO?8?E} z32of;$Lg@5nHVSwrMnqqrcy_golITIur39@9ZLu!^|DP`g_(BLA^kp=Su;UY3h_T) z7R(_=ka~)BX9`K6sgvgu7&R5|Dq|*Hv}^vbXex?Hl~HY)OJLFTI};%prHValEaDg#TQUggPs?T}+ybCb8>Ssa6B z^HCJA0jwQzYM=Wk~l5ngsadY-F6V!WqcRs@>6?cD-J`G5qO zpo}W%`&p#HEuq*;qsz>8w$q3o`%YJ z>>W-e_|9^6Vj%hq5_G!xZc=ohA$2}~dBMwMPAm^9JV9IO+nFC=f_F##mX~RgD2lt6 zE0u(7TLl8NQ4D)qRsNjEwAxnSaqm0g!8Z}6WHk@J5yjpmsEgGH>X|b@A#Yo69D2GQ z6Yqz=6n`ni$+pJ2%1jQ9$m&bM<}X&Lx5h=leh0_<9V@D9HKgWQ(;4Fq*9cWkizZGo zcMAFra<|rp)Tc@W+NA(+B@julio-=F|D-6GeRrkr*4O>m=iu}P5Ah)Xj$JU*vNUhl zQoQkScBM~qh-+D2mUHXf&S3@pK;9iqN3XR&gR=b2ZvXYiUaVzMJp_Sfk0gE?V}JryWADFRwxI*9whyRckpIv3uRXOj6FXY!)Gd#j@~ z?X86dLxoeQfs7ebrWj4R2f|;?;`oFjBwGA^sFMVDx`SZM%<#m(tAGsBtH&%BnSUmW za3ukM4$P6utj6$wSSf-5PQf7Pwv^D*XDy^oPjJs9?6FjWL~&`);2eKf^$wBrUp*q> zOO!w!aad1#L|Wb^HcP{*e8ZnHodt<`^qk3iq+A- zz(EBEtltl#nsfEX@l#QGMs?})E5iTXtO1x!b->WKBZkDsBczoQMJ;xk@)I;tclF4l zgfIg{Y^2&iGHZbk!PlJI1D&+*XM((o&?k@*(7`|XwNDD#CN9Bn;xA6HG)^jV=Wir0 z=>%WN*dOa(WF+rtN(;fha3ricCLx@_P%oRl_WRXvkj5LWN%@5%S!5TC5_uNQB(9KD zI3TaM@*^mtJ|jn<_X=Z38A=)@frJWUKLf@>^4-Q9WrfI_iMhtIB@teoTIl|~=+?Gg z(A^22;Jz!+8+*_m0akpfKf+vT_l83s_Q;0~T%#aEYj>R+X6rzXcA>9?B3yS07HEkv|U1{M#X5 zPJuy}J=FBHO;`Ce4gxN%RHUnLV_G{9N7&rN9l1ab)E#-EB;&)u8-5G?tYC?DB=sSx z(~0acUBo1Aoj?9dUyzvrqV1wU7v<;nJPIn}O z_(cm!99b(w6;e1-bUQcUK-A^|i4=j|wmY?0CJr6|Sf~NH0eOyb6Gf14fitr@e0tyS!v?m=Txe)Y+q*k{2h9p+)#1cfqiV5;C-_zHIts!iFkqO!F}g7k zfFlN2J2!p=p1*wm5n!vB`vLIQP6%kH;BD{|w`Z+(5V%f<<&asg`~7)s&z$HV=;*fl z`-eZHmwpJGYrfED`ny8lwILFx7o)(iJ63%NtZO?!tZQ;>dk|RM20>)jcfVnB>iUsb z-3P$_|9rE@ZcX1g7Qrh7q;ue!0qP#xwziFGP9Lt;rayXiNCTj6g3))t<^m^Y|4GjNKay*Me|$eL(R%+J8C|bW z&bqDfyzZOnbqj_X+wyw9U+iw+FImR*kOBIH%GnG)KP;#Ey`ApreHnG$UE1}0-F)hK ze_d?O*JE^|F>&3kQ+W-A+G8Bs{X8$98nwX;g^K!#rMq_WNs^h(*vNxZ23C@7zf6%^ zx&B7o>MNY)?}W%>%kc%uGGpl+Ty3T^VBmJ$|e%kqJ&Y{L9i=FE3%5p=5Bs%tH3eFvTbsb!tENzb5HpvV#) z{DYn%6RvfvT+BR;MOU=n6+8L1EC`5|>r;{kDs$drGf5!1i75DBVNA%>#>jWfu%G6vF> z($SE3LN{UCruBmxmR4j&V+PmEL1kfYt|-WY-Aqt_tSX2qbrth6;R6oq(Uq1Hl{-Ny z(MY(pUI$mK#kOvhPcQ zpoH2LA2SqeDLlqetxSvCN?~^>bmIRs9{lIzlP>^CNx{?$M;~}t>YUC=_ z_;Sami-0yI%GuAb9*z^`GLiX0GAXfifjP6;&rg#upyn_V&+m6;_cw(2ra}rT;YNKH zZ!h)-hIE#g(DT9499LzrVOCEMlCL}bt}?=%I$%(<;kJhqESz@gcUiX=Z`grbUaEeK zHd$SqxNACVnWuUK{w@n~uWa(&@TpDnePwRy$nE$+Z;Ptj|CummJ(?0ZYm8!IfE52S z=*A0jsz}QPO+~8aO@4Ko{$O`fJ4NZdb+!39Kk#A(ca-FWRAD4}_1tFj_*!FP?KhbP0Cn#akb?-t{E$V+6dQvk>|YkaVLqZ}evUb0 ztJ)m$uOpMRyh%W(it(vrfQ-v2CKM;ye~Nem#wQ2W9Ee9jJg_(=uA2uihKU;7PR@L* zw91luGu4i$_eI~eoQe+1>d72kj>FQ{5YD%R~;2LmENagA7a4@@kaaV7D0yWl~>$g~$HDF)WBu8~~IbYp3L zTzZMV3N3V7AquLhbugLDWMND{uaHtzuUVQD#U315YT>}&WO)Bar>|~m)H5zZDE=v@zr%~Yn=5CZWaV?wG;`>K(#{o&Xk~QJ^m3@>J^1MdKp9 zt3CzlNI3x(h4?0PNal@&WR)o<0$2bHjv&1hiZ=Aq$V6v!rEg|rd z{N2N^V*>{+^y~5c$+YCBh+_l9o2RJmF{HihY_%njRC_XK^^w~Gsj5#`fTuQ z;3UnPptY}6lA|_>(QdthRxcn}8#T43bPH#;6|b~{fbJ9qE4fn1vayE;n~yJ7PlcFE z^NAE>pWx`vA50jO$wq`nt#~%xu+G6_jUwX-M-s=kXooncR*=S7g#!UDZ}jF_W1*X#iEZ)ZIZEXF_qr*#gmi%Qv+FV-u_A$KU5OEL{EdT;PF?=AIHie^4Xx1j z*2?Vc$i&8HY|I~nE9e(Kdh{Hj-i^7rhG!gx-zSesjP19XdBx76nnEPx1?@VZ*!f3M z4rLF+cZ0t%x?#=`&oJcKOr75aH$y9~x948U;xjFmUU@ik?3r+8wK7NiJ?G5lg#Gjs zTFZvIl#91?6)V!1`kt#aWk)ral8gZc`torQu?$vM8Ef}!XjYp}GEo)P z(jangFvuN{rZ|+Cw3EY6xUN`HV_2)r!H`+@)7m1F*DFuy(TEhyfm3Vf?tz z^1XGU5*d;&haaUc9c=hhR;g1;q7_S-^UYsG&zs8;rVcVPm5JcfAq48#5)__?>)%9G z0u6Em_EtfuBp#9(Wn$VpZO$D}u}Ulm)ImcuG^toyJVYzkLqvLNGNjSVR#FN2u@~x2 z0vNUgd8|aS&|JzwLPbhs(QJ30w=x{Kyq!wgLs}L=Jalc$)!1^VRCJ+PTidK%2GDZ> za90sOiEasMUY{()Nk zuLF*qh3%jDmZdgnyG0M(bxQRISYf!7IFGzehgmPq3y#8*e9p1JZ>W$%ix z-c;O@-T2_)yM72iDfN|a@)VuO$K&T2Q3zS*N7-*0k@587Yc#T(&^)%Pwt2BG2h59T zLr#{YXsqd%0lBuj$IlmIKnZ+))EI^6x20TL1_b?`>u|P71z(}R*JB7_J&l=tqZgEH=aDJZ(NYe5uBa|YDG}n9EX0%Fi zZ!BB8F$fJB#Q};-(%zAb?6}G&RZ;UOAzPLF7!s4q1owo@kFB$!Z4A*PL?H^ZF`?x? zg4Ao>3frRQx%@)ztwb{72F!{XC|2g4!o?Ncj`?aD*K8d{T-tC&Xb3sl@u)E!#hV0O zjF1x=PJA;Z58lKka9SNFZwr;q7RVAT&|mi&r^WoJPeqR_kZ>h2^_tI0*=7zEjhoGn zH=VYKX!3DDY!1z(=}fJWAm|+tBLv1f5oGrlbIRTDPjj@*(0j$E{YZCmYJX}Xao#jM z7U-{0pkZpR+qng|3Tekv0y_YQ5Shmjo+vWY z_|E*|01d@GM^q`y3jr=5NzJ%|3_Xxhs+{t+kg)eW)Xh18wKaj*6LWkXs+@@=__f{R_*FgwV=k#TkKbPwI(q!G03D+u)KJSygZ$yqQJZ7h_0878CyVwWuTqAn5^f<7yGU*(gNO>Y>rm;HbRQD39-pu8jB?J zW+eBRFw0=;hpf6V~Qxs6`9`b4VSAwlIWbcQI=H&}X1Lu#bF=V}A)zclMv~!G>et9B+axnpN28J0~pjR!VQ3ypTlM_>s zJHYNGBYVhz4BSRixzg%9A<_i*qD%824;ebiD~R<-cR`?%&$XM3k_bvL#v(zRJ8CW( zOJ$o(1}6>ivbh4GspD881r0C@w#xB*lQhz=G)1_5|9m&I+BOrm&BUSvqQ(b|_>7e^ z?w)^T2B}az$}SFplmLke65)(`Of)f z%DKr4K@M_eVnM-GEedfT2vGof=x0?C5EM$^WsriW=7sOl$BCI`dlm~}^HHw5m?DKK z1+867dI~(*kg<0_)~BSjVRj7mp(*Jkc*7$}V7c=wI3X%(IiY1!3DBoOElrtjjFQKC zWI)IGn5fxX{#{7vuO#qv;I#;-c zng-++_EEKp4)s-dnvY)7?k<`eNJ1S*ZC5{f*Bu;eH@Dcy+uWO8=dau8_Y2R(E-yd( z4FtG6_{Gj!l6{^$T(@j<@smn<*>?0Z$7AgA&9D4seeq=3_0WOLPU~Il1snjK#h1*% z+3n5vOjfP({jmxOvmkmKCv>D4Q>&?AXRF*BTs+vw%y>*rL0%POB$g!g`|GcR^OD}} zs>;HNlR{ng93pC$p2{Y*$mbIgM*jd*ph7Ur-dnWGQb_fcEPAg%Vie-7;p>VMrD%jA zMkYjk-E71}Af(26o!80H&~FonN{*GnTw4wD6Mc%6I71l$8knITw{_pMUY%MWXOl(S zGmA2kmMwCzYtNtwAB zEAS9Va5TaGgr+t~w0|FxqTCs3Klk`Agu2j}6$k(12g%+p7rayT0lcGpLjONQ<$pR= z{!e!Ge-kPUY|Q`bfBvQ|78|nns@k0bt$svksM=rhJJq;Q04hy`2wor|ym7k%pjJ%v zQgCmNQyZFti$ii>U32H(Yf?_>1UAZ#RV9(vB9E`XlltK(?6OY8725Y)TCV<5!_z4} zhRuzV=d%#MMe&k7HFpjvFjS`%bvELfWdw8*hRqbGr;iSw-rqI!&~d!w7pK2kdbPO^ zCX`ecpGA9ObC#SbX1RN^#;ph{&iNes-J3dk*ON$4rEFIQFH|%Rmz?=~GYefx+n_d#sQW(d=)Le%7RW3)pgim`Uqpl^MzAB#Ok4T7-VM z&suu86|lZ(a+P}1ZxDzJ3*0xmTsW|_XHR8JuO6T7;_{|c|9Gj=C(v`ZX(EVia2$=b$oSsX!lm#{#2+9IT&8S5{*{*=wpWZYV%P4 z-Ja6cGKz_#ZUwZcZ_!l%SyWL z+%%Dv^XsG;Ve#B3zjnlHD2*uR34PXnbH^)jf@hrNk5pUV+SVs9Z!j#`bo(GLf(|6c zYr!TYPfUXg%ZF?yYD}1IRy_4UF*|$$YJ1mehA_9FT%0v864xz?VuX`?mHI9o^2{Ao zQ2&9V?I<2W*vIS_w=QtQoP7~s7|0%G?^ck#9NF@49pDcB$n$hDYhcXPw0G{wFFp@z zfVl&YH-;EVg{2eMipTs|6S0cRLI#qs?6WEJng~^pb+OAr=S7T7o;&5^eNlG<^h7~s zw_Ny)+*p)7iz0v{tg9#r?Wm4B{#JaAe? zP95r=Pd5zVu3m!|HNPPM9LpjqMe}x}Yero_toPS)Hyt{RW0kJwFSI=e+1)l?tYe~E zDW%t$gkdeNcCLL|?YeIR72{>R%2J3n>TLQ`0)sXoqmy7g6C>j^5-XLMbf{jYP#^3j zODEJhO*3fiz-SKCL}(`mzJBw*vT36A`Qz0Y9FwT=(SC$Wc5uE(jh;t%1KjT}cu z+)T0}!6;ROf*HSA`hL)UB5l9Sdp>;V<ImXWs!!>zhXRj$1rr6Os^_Mf;}i9f)lX-)Tcd}pAg9Ig z>w%5}+PyOmD#S2J-%t1DXg#lVMu($Q$am)SmvO;hfF7mceJJQLTY3q9iWO%&lO4t^C+T7SEw_3CB#8nCcnWK@fai-`MksgY`L0} z!3EG`yQOovXK=qh`(m`fS%OzqANz6aqD)6YyhJ}=zpD};ip@a7j{L)@q^n&pOzTH@ zaZ8)&LJB#IuEIMyH|1L;Fr&DuN3*#+t?IV8f&KR9S(iQ;pI^t`Yui}0ABFkYil`NQ zn^tCBP;vuOVwU7a1LwNON9XY$t`&Xb?V2_xPI5?Hbi%A>=U>lF+@**z@qA{F6ogR^ zTBPmKZIHwBtfwBTe=w%mL1YH-YaSKR)M z;AxVW>}=hreu>1aSt0u9nCdJUc3;ZClg^yeKear@o_x@cd5CGm6e_qyj-r{Tq7?|< z>GYff=5M^Rx!e=DqH&&Bw<4GFS7q&J9h8LFM5_757jwNI>BV^_@ZVy5lS^TbaT25? zZHE>%3>rk~vx7zFO5`m&7;wNO1k@Qa`Bsnc`gUwhy3o$b2<32h12 zPF0LkUZEhC;JO?ayv)z<7F?BDku=;b*j?Q1MzHj>e5V5f`z=6Pi2%3#&{Tt`6VOyg z#SL7m@wuZsSFV*?JwrT62X$Ho>%|#c?SCI`G{u0QZ!Fe{rAG&7xFQKsVD;wa*RbZ& z)4|!iKYni0<<>c__BXYA8|5Cp*Vy!Ye#%FY{-6mILL*hQIqHa4C8*jRERw9#yNZn71zGJN%OHFhR5x+wF%c}#F6 zuv+*wzv?`zg5NYI97KW?VIyvOKQuMeU?r%<`EoGy+OKwTVT!*hxT+_d_|^UgMIXQ& zK{L}X8m5h%ZSBpecA3`%dxv}Q zwW)nYvsxP|_PHIH+>Pb4)9<39&4H7pz;u=G=2at$dJngDvIR0mSHX`08lnM64Z;wh zw+7VSOAMgj8%A*oNS(a`f^wq&Z5aKVRMGYEx~1L2Pzr3gA1SYYuM^Am{PQK_T;knl zGHOADx&LXZA#99a( zL%Xrv&^4XM6iTIpYbRQp%LVqshrq$#2uf$(nxfKUDG}* zsh#?Ol%l=?DOFA*u z)q*>jBEj|jt$wehX`JufF4G;FQ(T+COpr#dI(<^T>0d3H?q`k!m6#D&Z<~V{p55dY zr;C~15Jlcaiw|sx$Z+e2Y}fh(~zkynp(&&Hlq*eAEgC^I)X)&^u&J8wYGM^{~4 z=q?8x>p)C|WnbEh=$sx@x@hR#lEadGNP(3gHQZQLRcY;3uK%IuIMd$f-U6eA*nF}#0Qv0!%LCoh|vs#?lBuVI%ic(0` z_~)-`ju`mnUj&x_(+~OoKH&Tn#s0Gk_>UuKtiOjge+Qg)e+x%bcVKAX@C+`<7_HInJiT2ZS~m&HVs-(8DwCSAcI+GurXGfoyX%|Q=y_4~>z9eL?On;H zd)A+KQzxS+sF5)z?)s~#&MH{r$C<9lJvJoWdSR1lb63%&8`|9LDm}aNWERTu?aeC+ z=NNT!$0sCLrftk?!t$$S(^(suz~;eI)LiG!$D2wHWC)U^OjtNcT2gW|H5;Ty_N6CkKX;B<5r^ zXeX9{DMuQ?WP`?>ku&q~eqox_{JqG0v^~RiJS<0yn!Yh?dKMLIoT0dT--dbG{ym6z2+s0qDa@yCNM?`EBOH6_EXgW8{Yu#+ z+Q|fUt8uLMZEu3c_tt_bEa~hg15U8RuCNXTuvVgPk1LI1=DP$oLav)w5B0r5lU0TJ zO|Wha)+EY>AhT^aN1E<6RNQ`+;_eK}Af~LOu)E`NMs8spLWDFxb$_`h;{}G4P&P<; z35r+F)3U)^*uUFkXFbYpmFnIUvL%r8{JRKcXvA`$NU|nuZwGP(a(JFfREA5#ZS0oT zn-vVM%apnsIXQR63S8y=@Qjl^UAF>MYIZCxmOMd1`9z!*I9=O1^Mxdx&q($jM{V;* zZ7E6u?DwI!6J5(IkrrWHi{QgI3OS-V+v{o`RnsV~wy&CC^8M*bqbpo^!Fz)1fhMy@ zE!W`|K{f^~Fa|X*Jyo4nStE*a>6@O5*YTqZ28&}yL0IP`9ks1IqE2>%7pK=p1(xEv z*XY^B^GDN+6X6qu>M}{k<9(Y5yTNQSSq1JySOPsE3wH6vtfN1RiH63(Rk{Lct&~w%7-%WAhNPYLZGXg z=2zf?Xa5TLr((Ihs@o+YId7A@0Qr+h>pfSZF{y@Srpc`LizZ_ocB~T=Ghz#+sKLvfqtRc}MXq#^=Vu`cEc^pvG zmC1q#?x618^`UgHd#{^+G^a1(LaVlhJLtkNEuOkn|Qy9sYR%>H6w))r{ z6Ctf(J$q}G=YDALl_W1Hu0y(Q=KG9pi}nI+3D<`lrK#kd;caur%@nyK)Z4VE>{5(+ zz<6M~IMARO{$#Yryj(zL(;gLkDJG4f%6OiPBDt7E#DOLmQVOC)QP6&!BR#g8&h+ob z*#b)U=!}@@fee?V>ujBBL6bT#9k(XRVL?0v;2g>)@U@6brF`@o%)N=9!_w@@=$Kqg zECYiUw4cv4>do1bb!dt!iWg?Cz5{);HQrS>RId({aBo|D$<5ixurZu%Aj{q`OdCr5 zFVF}~jhfJ&8tPcq5$;KhM^KsWhml>L?uEL>3rf-tPR}D<9=JcKZMf>g9k^@uKI8$p zKv-{DVs>4cmO0&vCJu_2vP~-hGczR40z%VWr6=LKc&V~}?|Eo8$=P1t z7jwmnBt{-fMj~i$mFZd-oJ=?M`*?$XA!>uS!F#%XL>Jsc8-+?1|}I?|nbLVIk~xMzGr z%zyOUUwv*JMlpq{Q0K=EaoIxLj)89xv%Lgu(xzMZ9^QM18YI15*Ny;c4tl>Q-<`~Mb7jDLOF|MyVJPH|IKT1O3? z?PlwqLnOo}dBXIBz+d1JM*&d?m++Sd3i(ayDhw)$j6k7ktlS4E7D{L&f(#WDXt)aT z053n%uOKXPyd7l)aa+yuxRdcUs#Zl2pt{}RvoZ!-_#UD>`fSG=}$LLdU~1oNaM>5t-o>SCUvhosng1jUpyh35HT14 zq{uQWw=XH$F;J3H<1hx}56Hw*G6iD@10!laL_rnd;ZUvhOX&$!=XhEw=}|tW#tcRm zb52yJ{7weReqj_yzIGbPo>`$cxJkFNLhZ2G1HIxMx}Q{2CAe%nf)+#>Di|y z=oor5|602g5kL|Rn{@N|>uT)lYmJo?^Y`BMU0h$KFP<^aPnCPptJxfZs2q)5>#Hid zZd8C5V$DpP#-3yqfF>I-{^R{Bxm$dI2T*{fovcUP5Nq9pp#x|#sK~1;YbU^5D_W{E zw$I!^yNTWqj@R_bn@?4)5;VR5A_){G6OrSR(h@1*sVQjK)LG-NSNNa9J`RiN@j>dW z+&;AX;4>A4vm}V$;pUye+yUxww8oIX{g(Ir&{@gAF?_SFkj-860DOWu|bI7lY7GMC|TfWeVhA|ZK%AktpjNLSa$%_!FmIUzxc;~0srmse_`DV3&yDv z10oPu#S<0*m5XG=!4_e)M~lZh907xc<{PA;qmE!4hH6CZ8>$+t7)sJFrx~TGN~4{y zn!+;$yayH=F4vc+lU4D#La-uaM$-(b>c{G9)uq-0uNho%VZ)C0VH{xF`?jHLGupD$ zfV9G`Ms@mM4#Mn{-n(~E?jYX=!u31d8F~}+K>A_(;qJ!bjr5YmL1={I{o$a8)1N1A)rjonJ@(2V@TVOqCRF#pi2UqR5lS=B7_)Ck(eUADL`4ml2C_~ zhqRj@ah%gw%n@CKUstY%I2T`!1TKM3K8c(ZSxypLL~vb}L$aOUgWp4_SP`boc1gV= zts`4gu3Okg(uYngkty{t^>Dm8u`=E&`7+guL@sGH)h$(zHkV9~z)$kKjN+)osLrU^ zN9L3E*~8gQ)>;eQpDv2zcS>7I?_|Pc(`3Np*a~SCyJh6%>^Jjp}BFvW+u;_qk}b z*aTX&Tb0}d<)rA;>GWz9Zu5B+a;tNTdc}IR{3iP5@Hg}$1v2}~@+0zl4RQ<$_l<}u z;w$GV3pES5M%ay793t*{54A|^!m}k3B%;SLg|L3)~dy;)wU+Q8s1vo zmhy7)hVw@ABK5fTRQk}p8GHeKxqfUvuHKz~tbWRYu!B@VoIw_Wh=Qns^FlE~AcDGp z4E6)|cLw6oE$9(zFQEbn{tt|GniXj5_bb$0`yF%%IN8tN2} z9a|U^i;PB!)UXgm^)(u~3{;X%d2Lh&MYbu52f*p>=C zygGn9yrE^%PHDW_aBMy=lhQweqFpA9DuA`aw8wh}IPHGI_Gx2IlyUw0S36o0zyx&Ct7+CJ}iR8Ke5&|ROa z+0&^$o_Z*FXzf(H>QOb&a?ppfh&7IFVk~RumaMfDTQ0pQx(L9G%{b}4@M^uz-Wc6n z?cKHUTLg>-9tP*dMaJ&(8+(xajCL^V9Paz81fapA`!hD;^z) zby?ysqIczMao&7u(|vB=_?2>49n%BqbNZq4Nw@RT;d31GlZ^!&3HEVA+vD}4yTxK|8_nnD4e{r}oz%wk zWcT&=ZIxomoKdX|=9W zBGBcN|J_Wy*H-H5#wPupAO-zB`GY1JE_C+~WS$6I zpQ)XdZB|AuSl%ZHJt41{EFurw9@FR4Vz@xx08%=JZ-M5&}={_42*FYOl>0&52vGQrztHF4Uc&7jRoR``F zm!qru-OQEgUyxj_WZUNa{)o?u6XMOC>tvhO*;s#XqTSKq?WZ1vN{XZU{|G zdpl6mp=i#!k-gu;o8?fITBgvg*M8??i&H(rSQDu$H9ASH&MU$Yob4BHjmv}4{&_Ub zK&uEPB59?+-bq0Uf>$F9v4eR7U!yb^C{4e44mI_KMNQF9qTZJXP>RCEB<>XuCkl@h zI{c9PP7W6AEyM>C7ikHfmhX4fs@gw1t-iVa;6atBY6^Y`4%fEBM|0KOUZH)mCS=Bs zzVJ$J3Sq_l0cLfO#SOnDk;EpG0SpV!i2y|e`k>GKOQQTL5G@U;u7dxLDcv25Nmci2 zZ)Isw5enp`s?rfi62>jUC&xQeW~)@BxHtqdKN9z$M|; zWzc%_yY)FQj+xwZlIdFOnCcy9p6Oat*RQtaxUt>Kbbwu&dL>rQY)AN&tru?^T`Xkn zc@1UGbiT!$#N6aid}i9a8B_53IVhk8QZqoA;Y_pK`n!9oGbAWrAOmeF+?Il?$OjR- z8EyuRkJBqya}DK1;f851FRRWAx)A=wf2b}Sp_G$O5za%@mRn+;Z!hmQ=r4|)Z&r`~ z4*+dIlE1F>wYBy2z1FrQhDQ*K=AEhiD3!jON~NxyJ#iVGO1<-+uh9myX>8+uLOGE7 zh#wQ~1URqAjAAesH?e#15qwh1o?%fIXgJJdaY&EREkTW5pnC#Db2XlRFd&MAx_J7Z zidiKzMxf^_*fb6?0Qa6mdxA6b^GP-5`phec%i}Cyo*@2rj|Q zK|0Zj36j#~jtDYGC_WGi`ut{%hA$!c9Kw$WzCW_^oxc{gu&>T<%RTqZty-Fw*`)4^ z+#uPT0R@z>Wwm~T{#|{a{-&N=#w;_u%`z5*wV>B9JSXTF9`qy=Z!xTmVOYihSZ`o? zW(W^~mV7LF6#-b5+yb`*HjdX{<~Tv|>QxKx!Ls7**9FIPVnj;Y^ z>qyt^AWJH+$z&p^EUa051q|u?{g#L!p1!TJ_l%%vww-cOyzEIvNb zMEIw=_i-P97rmHK{S`oDe+IfClw%aUc6*K`j)xSTiDkVx1|tIANpeN42C75vbW+V1 zCJNQuw?qmju8Y@$M5@Y6i=HB4Qti_0R!_I5$NCHFHT@m^J-0T?>NL*EX0nR7BHbVn zFhc|^S_QksYQ1GN*^E}3(PW6@pDR`xh+^zDVx!Td*wJKAmrX1hQD_z;ry|qv%(dcH zaj$qpWW{!Vhf@`=6M<87ViN55Wg3R_sBF24O2CAUlcXx^H(o@8s0@J8`mL;UfXKyR@@|9AOdELXA|}Z;uf+tfdl_dFFG-=UaVt zA4BQ@*lj$i0)eWJ?I$vwiF%Q9+oq6V-cQ7OI@A*tsT@i)s;r+%voi`3o@EIIo+_^V$r8 z7r}IqK#-~4qSql(1|1?5yF;zsj>%G+xSbGxJH;gVQ@9?ZOcpe`&>~*3FLEuC*H~7{ zP0TueopzIDo!p|`nX^y3Kj)72wq)jI3UPi$6PhYNafn!m=Tj$mI*~8?Wgnd|(0~NvrK{D-Z|^PWC%BtVKV$)QUji%Unb8j0Hq zvM_QUl+fhyN|Vy2tW{V=#@{J2UQX$y1Bc^jfrd^TyaQrdr2$2WWXlGM^obQ?&JYUSF^7pYpnzKLeW z!&@6#3xmTYjIg){T*b1=>Z^k_;x(+qA{1bJgw&Q_HQtV;;ZK$=*zDenz+Hw|YNGp)b+N-5Jl|0tR}3fv=}0{ZUIkv|CVuX1hkl zJnlNe1ScLP5e$t}B5EL!i6S|rg19B(u?qP@t-uI^ovK3!VU6WQ$ykqYR|6Rg1h5nF zWGMlxlqe?<7IRj_jP3sewj1=fZsHrA(qcrYq-;$1|FP=5Ykg~}qPrK;%EqYEWX(TE zp6Q>@ES8t33;Z4GYR_hMlV_LQr5;zml+Sywd2_xe@0C+BGbZ|wkq%>x^8@dlKCjUm z@ze@USkQ9ulIWwlH2u5rP2~5X1Z4sCOZQ6HwgTJ}-MA&BJ2phpBwE@QKlzPVrH#no z-8z+_IF($6k_{uOG>#r!7RJnmcM6DYlZZ75p^SG2mM=}otD2{;t}937$CmWmMy7YR z4zBF@*Nde{d4{B>u)k; z&-I+xy&32YoY@Qewb?Mwt)N@yv?6aln#kqmd1ypSqQ^>cO2}(Q`5JMUUObY`S;Tib z$r-F)4on-fnx7|niG%Tu*q3VrY7&fCmz&+h$@C6i?qByuz-;e0$N2S7)zjSl(XKvHg$h z_1~hz_I)K))xTU^lhQvh^f~gTJ*b~P@rtf@HJ7H!OR6rseExdO16l6}omdZbG*er& zxY6L@xUI0=Gf@nSYe{jY-Cl6VG_6`#^LN%sv!p#dG2FewdZt{LGUdv`+LT?)?9ly+|dV4K&o3n5k3^4157wrZY}dq3RV@(_RjFv2Nzow@{5G|_Ib_~mJYtdx>|fB z&>q~tY_xRp8?9T!^?@gXJNRd<&pJHmaj6yhLN<3uHHV@oL{U-I#+H_ZsCfW8U%0~E z>89O5nJ@H&gD7Z_4H(aC42Qu}X!dwyhVU>B^C=0($XgQTm69kLO#gv#3kC$Hhe}zUQ~zXqNQjXGQ!k3q~#RiCGpa5 z#}Al8R1`&VTL}VPAH}!E%W7YH>T<(p2eZaXl&u5qls_=l|v)?EI@OE)$c`mCw0LoX!mM}M95 zSjUE2drs9E6uXt%*+glH{ey~p1^z^zpwWCHYii|z-=p(1w zmtVk4Erx#WgMKwpof>bTJy39vW21pJ_tNc$y)0sT5jtx0BD#n{48%teX-N<-%|hCe z8|lf*nfdkiOmp7OG^0*5jKcqs>)CntD1&l>5)UNLiz&N1-ge6~w(ef)7e!yg#_ zg3V>eQ4y+wF4PLlygBCL)mW5|#S(nEqryEVHYJwild*+-Yiw@uMt(zdm;9XC#XBNc zp|P-pakefTz3e&=>2V#4oN%3veCX(paFb-@!EBOnsx}*;J0bmOyk)4zQNEJzj2Fbp z5^SPi3j2eC8C*krKGzz5H2Y`S?`GfNZ^WgFG6At-QJ_pI_1T?G(Y7cZ%`Fnf3tNTf zg<-+)yl_zXCpf=sTx$W-7?)lk2168$^#bvzf)RUIuxJeIBo6dApRwoWnkamcN`R;e zXO-qMmT0rsOc@DAL0`P?*MU35^58fSVF*_q$gRJRM8gtJSr1 z?>*l+-#PTNmb=KJ3Z=r_!jXk7h4utS7ZF)R^!){VEz5=+jOmOoMVG>|bO0oh1? zdTan9iT+4W4<>1M1WYDLQIF@RGg4GRWC#a&krEX~I?2 z2c}aiD1;E=rZfH%CNYU+ryE+%Onz}n*_y7EC|0$5+m>Lfe{JWU-N$Mrhn9cF(3YHE zw`kN0t5^N5Fu0?>`n{bqw$D)9LLd}&u6=6Ug0w%qx5ipLb;Ra7-|rk(j;<9OQt|YX zDXC{?j{7lG^e(7q6F4hTLDXa&Kz5fHvX|Mb?Dk5t)uc@`--sC#jrHb!lO5|#s0lFt z(*nt?q%dDhs?P-)vYr=KiEGuhfp+tASC`hM|HJ!@_Kp5k@P;{P>bdq3u|yeZuM{o& zG_lsc!rm3UZ+jrQB%j;H(p0v=a>(g3+`K>3$s>uk_!Qs7+cG|wCpF3w2h3wJ#o+PS z*&TuiulU~q#J558lSU_AK^NRCmY_$V6@j2IK9>2?H~-i%t&9b_|6C7OvCge3(R zEesx7L0n#llnRpYew_&fgF=TyTLR_R6%|b1JWHMz5z-FJ@xxjjVG40q^*Iw ze>}5>j@SQk)A4sUZaQvn>%af%%vV2sap3mA)wj^=XY2P~`fKNfOQ5W^gEyI8(5nDi zmDL)(b z7vdu(LKFm8ivVO1bfyqY0tAz13}2{&Lnc?r(VUz3U?-l$5qafGv*YI<^$EHa1+|k$S!4 zWPk4Qjho&%`jgFX@A~b&?++bB%+Km3(C!D-wCCcdf4x#=g$6oX_&%E=aZw18Wu@1r7XKvzvW=be~_MR3r+TR;#Ae^(vzp;(n=Fq9w_eZ8$lqjXs7e_OY6^ z0~_GnC1A&EUSN-A3D9+kp%OANk;Q{s1QY?!cN7hew+cuInDFjoxG;{d)&$&UO=PMu zDa2W!;qk{vHXahnj(=t;$lgl1fLt}Cgg%hl};es zLor-9M3D~K_?Tjuc&TuCD#i=t6_O^(Jl7We_Vm{Sw~_MY734+_Z#qBNxpZHD7hUHn zpS$PfchOw!&?#hs*t<~iz~2Y{E9JJdtwOKunzZT&sE8LJY=VTPA;HQ~97xnl^pU!y zuh$Q_ej~gqWCes`p;d3!Z8|=W;(!?sW(kZ-G@QssM-;D(VJYW91u27G%cg~G6hr?C zVPD&Rva~#ouU5n`+t*g?Qd#;(7Biaj57cw|n7d2?TSO}u)Z=PhS-YRSHbD}WIb2kMwxz=#}bI9g|=c;2o=`LHsLuToe? zP!C4=LM2*I!H-s^^3}>*Za%+?f8f0DbB`#97L6|$Uo@>~f3!Kujm{fAtTI~7SLam? zo0B(Z*lKQR-qK;IXj8PS=w{xx1-FZ2O=W$b&?in68(xld5-As=2<{_IR6ErPapV(v zt2N4Q7^1T(-*7oqUo0GRhW-9d4N01%rL-o^7KJ0H>!U>0G$L!-53;5aS<_VV8K9Ao zH9U*O?=!NdVN);_7rnMYL}4o544oA_#OvaqXfwr1aV9i6!Wc1tu@&?2w}}S+CXr~H zNVHAVBhd|cSl%KthREB!Ug`f7uD`nvQciC-=1(`iCNN{t(3CVy)iMUM2v|dBbWSUa z$s_?5dWVSJiWYvlb&{e)jV-FCAI_Mf0C-{rbq(myf>x(&nS{19jn1 z%NCAl-HQ^}-au&I8%+-zzU$ch9y9#2_OlnyT{wrc-%lxuxd~lML5ojQDipp?i!(U3 z5PKcAl`&OJn_wfi#%g+8%aUEP!q^cd8g@?MovyIMij9sBI#9aKf%C}GaR(AH2#|=-U}U(jC;?sI_w$fju}udq zhO_gs1NxZGcItilfIg{XoeicaUu~5a33DPgZL)q2k{tY8EoMpvWKzbmDy+Ty}V(XH!Q(jF;zBP zQ8o-F9CC(%L=xl>w+RnsubX5KWUOVBwg~u#lJD+n2+VB?xky$H7mG!F`}*~}A)LPZ zSE$S9$k%-O&L5oT=nHco%kw{%rQ7UWXFGe2vyG?d)=rV~^>H!o1UJm#736D-bH%t$ z?f^H*VNx9u>v9SPR-%OyB1(CJL4(A$venh|$yD{!R#gwpLRsI1vbZ}bAi*RR6y{zo zm^OTWE+82&ib6Ul>${!9P#Mn^xwk%jyv#{HO*A-xe)lHhA;S_ZFI*@GgcX0bm&=}P z3Xk9s@%`|J7WW=EZn0s(N{B|(5?!uDT@4=siE<-85iwP1D1~}ceJM5-4oAGHUJYrO zIzWTEKVYX!9bgb%lI(wEhv7vvmij=2`am9tq5-ceZm{f%P{CG=RBseT>2lF~%SGvO zWdCDZgXN->bx~^M$`?_4Ci|b!g`=>Z&ah316dGa>%oJ>lX<=57T7YXDG*sGg z>8Qsj6cfG7=+7!W_l_N;)OMhtdd8T^)CIKX+_cteovzG#rID%;urOLZ4wl*$Z&`GU z%zDs_NhvQUMs-vRH$y>Jh_3_#>7b%Tk>3-l5Wj4N2)?0t)U?8vLx0+rtA*fX;0>`%6D$Q|o19cRz(*|YM;KPdgB zqT#nlz36D49pGGifc=?zLH)q>kHDB~Jirrfj@b)H!F)qSFR4SuO=Hr)mJsv?bwAN? z#Oof(<5j##gX*?HHC(3ZEmQTD@2R&;Ng&7R8IWPB-ZE8hvj1-fP?@T?4C+p&HJLUD z8Ih0NW&r6TpybAw!FC#b#(*(sV8g{Wg>=fz@uH?V%=_O0E}j~Q_Q)s(KBPfP2R?XE4{7HPX8g=?@|Ba#tJ zMyZ#I(lT&^YocDtO@~9bT0S~fq$2|abY6e}aG(L5BLIXzGL@a}MvPl^TV(Ki^EAzaf3^?H7h8 zM&CT!^ZeO!hkDMk0hBqid*c1lwcFo9b;xt|%GKXrx^kI3P|w6xJdGgeXX?-<`-q}G ztbSfyrs5WBz+z+8LrS8yG1OSQu(s3cwS-(a7hM`&8eJo-Q}W?_v|ZSyY*jnL+oFTk zyTKdAjmW!oBf*ino7SYICvbz>5Soi~>f?B+x>o&AzFj+^%9@u9lQp37dW~0Ryk>Gp zLaJm-8>IshwkU)ag;OFkh%EzcOLs=5Y;&QDph#c@J^~$?0yIvhD^L+tJrrcYAZIjJ6?#4Wxuah>Jk-8xc<{9TQB~XEgew{ce+PNejq!*D zrTaLupqoh2p;sQ=+Olr_qYD>4vOZXc(W* z|E73E{C4tG;Pn~5ae2gW#0bw`HsgF=Y^6$34u6eDHNhuPJSm_X! zXVykw=!}~)Ao($~#av--FwdCRP2Ok5%&(clCXSgenymRY!6roN;xz^lRD*E3ifqKH zXb77!sq8^$D zEJFjhf&~9O4;R%(=&hz@>a!ag2OHUz#siIPqlyqpGKS-T&kHy7DYSXThZzJ0j%Ca_pxK1*g|6jg(vOmVm2A4(XfuXG zT@A~t+}9{^U2sy%XqUfvmgAv`JkSj(cJd)LA9nh*oq4z}!3AfeHPx>MR2LujSpOlr z+GC?Q?(odqzGn70d&}MV?rfiJ&OUq;)B0@V#;KPAg2V-vM=2(_MQsCeLVz??c*Hay zkr)t3o92&z+KM!l3P@3d@dF!@g48r>T3JCAp$QU|rCJR_aTP@lRZH#bZ|00k+PmA? znc3Ufo!{g8zF!K_oSwq!7oe#KU|8kUq)>H@Z5az#3g_x5)AC9RReI%u(eobgf2qOZ z@%8ybhYq3p07_IY-O-j<32N$U>lTrwLUT(AiXg`%>j!aA0r3h_qLteA^X}1SdiOSE zUw-Fg=h7whFRefD)@FXrda9@Qu~@7jb@=it8++b4@ZN{`!Sv(be{}hSHHqw(9y+vU z<-S~He$_ME6YI9DYpF?>N7?+wrM+7=pZezOB2VWRKPC0*NfbvPj3NdxSW{b|!m~@E zbFd7mKg(t~f?^)cy9`JoV!B>6s>ZgTwQx~4R?rn&_1*eG{l~h3fTLg4&*@k6tGcEO zS`b*JmuNwDJ{=U8rI(cdY)3d>FKM+B`wNzVo;E82O8P~=NFGB8+}ywIf65^M`bkh? z-o#X!plav}kmrq!-n*he%IC9jVZYiYUenabTL8&wcpywqyyVx~zO!TD;ll$%L(zP$ z;uoj9uRQu1`R;M7@0fYv`1H%G7bayT30O9+)WXv{M^O@NL!m|_nP{xwinnd_gF-%v z=Nr+Og`+VOz?_4bP-85chzsGGl&Ux`^>Ex528hc7M_3>(;X6L3gyT{P#|6AgB^;Nf zOq9pmW4Q z<&!BBPo-jg$rn_rU`k}2xTfrL#U~`!F2*iO7^>Ozx>Q8jO60^e=kN}-@B7@{G7bOUh4vuF6n2O+JfDxe%R zQsL0*Yyriffzgfdhq*-sl!3;z7N8uhWv!@*twJl=M!b=98Jp-fyp8l2J#;VHgZGeq z#$LLI_2EA9eB`Kp#5hKOj!w{**z4#u_7=LJ_p^7=@7N9WKKmH`mEA>CY$0riB~Xmz zP%Ud=ohW2f4gFX_g-|KW&Hr+klolHzlbPK5=)JA)ofXjAB-9B|uzVE=> zeTx#})CB@0p9k%Ie|d$vyQ*+wG!}1ei8f;V>zN(DnaEZq@*j`R>{M!}4{zVK;c0RN zf&-#MLrA><(cvrQrRW$%J{UpPqPixDN}E-)*9I+HQtYkJ6g{4?N*AsSI-a}$)GB&B zlw-yt7+Ii(u;zj_Y)cafWpPXtrf?<({2tJ8V4bls@A{Z`Ek7orPZ(G*&MYm6WJo~< z2Dn~Xz{tb=5&j~N@Qn1|NO4?3pmMLn1?~TBxr!I?QG6O8&6_h`Y{zT>qZ2 z-QTC}*MDG)Y8TyM|1<3_&6zxha(11QbL;$uUTW4(8}d`| z6Ju{ed`s*Pzf>4RR22YAS1DtLX<5wU9PqtkKt(=imWRS^%ylxq<+_p4x$oyyJy2EM z0Y7JLC$MeDfGRi7i~w#&>RhHEf^}apTy8nGd_5m<+%R-qq>k^pj)Pcm$FuQPd$)bi zj@TpkbjUKD4DVvkGQvj4H$vLU@h<)>CtQq7PsLl+-H==nNUqaE_)hfBHYth9R!?v%TnxNQ4Y-=A=wKS5OXIo{j48O5vp`eH06s@8X$Yh1fo&W`u%nbNEe zvlVg{78(XA2x|jcT|KWa7Au}dOUT92ljatmyDu*9%eKhXt_}OG zXdxVs;Qi57*iqNLGEqQ@(27tENzVsM*%6nth+d;biI>56-)7>kCN*osTeakX6u>eYYY0{9soF?fJ(mv#ZEy7@gYzWPE zKlI7B{mVY_NAOpNU0jV;q?ouQtrcdh#a5>k`MOoKhz0)`XmG(cq4l&N<4r#a zr2vo#bSD$u)I^y#(f#CPGT}|i9!dyNC?a1li*W!VScTwrpo3s15YBCF21K+2k(7W) zx`eFaEo2sN;rrt#DE?)*rIl5;v^xJ`x7>rGzOFd_J@?+B$fVTkWI3nDXn4;s;_U7``@n|bt;#&Y*5%y)vlVF@@%FNm8x+ZPNLmPKXvmgStS3m>kq4=g$c0iuFZ7 z-Nt%-Q0MW8J!pi9G^DZ&V66}(aB`XtH_90==Aa^wlgnQo*8Oh>=eq(WQut2}%2-Sk za9%Oj_o6EB<>b`KrDyTGh)d?M?&7-svaUcG2jdO2SHxvza_T`T=eaTcKNyR@)$%}# zE%nCnmy5sry_*=znj`Sl(sMcI_6@XP2HGwOjMc<6{;KA`-oR-6rBfQswA9oAW?_lb z%y*Z&y>lv@X0F>);r2MZE_Zo~nNwC~7PyK_yj5m_v&!k2+m|ca(Pi-x5sqzACEcB zU0v?=xSUlf|J9Y9h)EcVQT#9YE9>kpS((PHaCmUp076*+) z<5yh7gfb4IGZSNMM`x9YXu!J0T=%Cwmv!C$-=B)lx%~bhKm*<+7v98gaFlLytz9^P zCLBX2w*E%cU;~zMc>&=HZ$tvhjzqNzsa zaw}V`-PSu?sw<}O`qbkfWzcXDXH2&8trO_Teaz-o>#zs=SoY&E&QrK?+uCZ~MrZWK z_jo={I7vsO@4-UfV78dSR_cX;{Kt)718&sn@ZFlgjpXEKV z8ar@@+S33ULqDJrs-b1{BGu6eIz`t-jwlqR;+8CtmGZC}!ZKD>sl~=p<0rQ3zKOnf zd>{DkSZUT$jA4IR$fJJ=n|Nji(2R2|7jcCQ3Zn=Xlj3L`&1IQStLbOdK#kPIy_}*e z^cnq){!aG^DZXVS#xsGM8 zysTnWv$ELEX-2K_n$ckFFpe6xZQ=GsAqaW@{+0(x4=(uNTkfm%?eR5Pml4Hl7{gYG z#ULKNgJlM$s-)R$$rq@ewgtw%lMb*LnYN|2{kFf_zhlp`kG7AoPqDAH@3Vgx z@8i6hDNeFKPeqZ;7woB`ftHJT)Fcv&*|toPNh5Jv zC9mI2okg#tn6d=XR1?o^1=K`Qnx>9D4|2AouyM zOjXJ9IL^z9WLKN<2Ng=4=!V!XN3$0kR$0bG#L11=DJ%KjvR6C>gx(8T#eO`J-r%@U zNNMz?v>?Su_M-msDi)(uoW%{^$IJ0kDpJK*gLJCFHN4KdqL)!_OR`1L?}SUO6dkAu zLN)U222uh^BN8vr6j^V(CC+ioZC0VUAb-xIZx%aczPfD`PzmpVd02`{Ya!+s6V+)d zhNSW6!GU%IYGj&<<8%Q>mB}2__VMmM$Z;S?=5tOodrltv#W;=-^(-%QoKWmRF5cr4 zIEtM_ldVwfN3jvXcQ=l=>bS1}&seXc&MHQ^wH|#q9xStJxWxv1inVB)~{3_^EouwT4nv7y}Ktz*gE_O zPvcKK%bVQ82zdnQzLDY=)-YMY^Sy{M)^;nFLQ!Is@p*a(+w2A$_GDh;-E^AgI~Pt- zV0op}=VCjoWh-Q}wW>M(tjNwCSD2GMIP1wlncp2apnt{_>1q8^`=<2iot)IG=i`Yz z61vC7nX!*`>)Iuzb9ASUQIQ?mw`}grQK8Waxl|8Qvm) zY&trPolyp7(6M8xjx*W{%vfo)(5Be|zpd_nv#tJ@7{2fuAgK{VY10%MuH)_~Y%81$Vr+TeeDvIGU zvx_2TWLHsj6=jNMqc|HSdx5z>BQ4k;f`c~~KB!{wd6C4x^wywa#TM={xN2DghJB_XF}*d!zsV%VfUR5+ zPg!wHJ&YjMHyM~sKAcS0(qT+#@Je`9x%KTbW2{N-HSAgDCbQSto5I$VTQ)U56S`bp z9-eUCpz@euH7CrFy)kGeJEI@ZJVaLGGe0g18)Y+Fs;e@Axw*h*K33uuiswu(?8>)^ zlIYH*`o?@@CHBbN0z%kEw*gNQCe~ELKf7wk>aIaIe3BBZ>>ljM9(z_KWd&+k&-S)f z5ikww4uJvYJ8#d_bh;Y7B5;Se$UMnY4eegpuB^0ItYC`xBG^;-xIxrESzYy1RyNK3 z0RsZzqaBECXR>w`!XFCp1`lP!)P;(jZb;IHws1?@Yss6Z zOfdP1_ybvL`EZv-yerpU-(=P|v?q+1m2zWS-#nw1Yp=<-xg~pk zB%uUlw0v(2fr$5vyLQ7D*w~ri>{KHe|xmU{iZyB7lDfgUyM{vLr`Ro06F&XiH2OL}8(o zS<6bU7+j%x35&ce`$hlYM3^WoT2-MC_3o@hLg)8%5_MmOnq$)pqyNy)OpHUo8F|Ny0+d z`8M3&PLTlJy>$0rfLwk4Gp9{=Rs4o=VavaxFQ^Bo6xiZhMBmU_DIpC|yL^GZ$xs$i zSiMMJMc)gkKMwga+oFF9@MoY7Xa&k$-8P^TXyQ8hPOvS;*w5n#d4Ssei|I+N)wzfH zj%!zGH*gx|G4%$W*VofN)X&216_w~Q?gN|S`UN@x{flVthVC?E0`*apJ7BlkEzk0e z;C~<_phLeL;|#g$eN_1weM&vxyot3WG3Hj_2S`mH;7OnS7Df%MZ~{AXj1iZMk&=SE-lRoL>|C zcYXROaz55i2j=`KV9M*ATadG+`BsSj0&G#%Q5v!j2m%fAb=s$XmL$aM1??6o3^0%5 z^e5mmY7cEkU4oxY+7&v%d46#M`;w5y0Ad=s3_t>LuT&s@%o zx?}M?A^jrtxd`!?oG;8-_>%F)=A2^AcvA4YPw@WlyiVp+ULyC@+w=tcAaW4g@+9XS zeCB*OF1OGij zoGE8$v-&l>>%U7~>bn$GmeWdYHFQ`H`r7hsYV_mHkG=dH>Ms!;u zDf$6o`W1Cbeng#;G;Q2@OC#x;HZDIa${&%1kS23&EE&_={#X6~1Nn7r9B1aZ^EYkE zaj>56aZdPdORE9Hlh9uV(!dITrF6pICuMyt6wry@2cA^JRI7#QF?ACAQ;KsQxd45O z_9nfejL=ba%K3wornEdoM|`E!iT`FLJeT}B^)q;U$ozRRh_ zkUH}3S1xY4_yD*A9@T@BWqddA`7G`SoYBCM9ABNgd467_mmr5ceirbwuYjM$g}f}3 z;%>qD?&T@`IO?sR&qqGv_>AOpj?Wpdf1#XaZ^;+HV?KwkQ@fkjkGR+hAOGU!KF(q6 zcbntrap#r^~&&G^eN8-aV?VqkZmqc2=A> z@6q?gJ=!Y#o26f(=d=&8?>Ga6zh~SWL_FblpPE9w(DrFxGy$R8+^YebhuMlvQBHGG5t2JRakI*tQQ(D#XIqO+IjTJNoc=qrxUk^W1ox z6|oTZc#ANHITjdGFQrEDp14gv)LN(wIW+1^)2QBpoGYdC7~>__wXiR+D;M|mG5S36 zYY=DCAkG{T{BL(YRK~HMr*W!Zcq`i+2DC zANZYu`IWb5RM|>{;PK=BV~E3H!i!YmN8=}eH93g-vo3~n5V}B4N+Bgc-(tPIj$XqI zvxywOLnqWjv`1~FwaOag?p&%?e}i28C!JDCXs7y1I;Cc5nCt3%TBhK2uUx^~lJ&o) z9jupML;VD`t97s+q%W&G>41^}_kK%7>Tc{c?6hx#Cre=e9>#Sc-S{{6>F2j+&&|zAZmv-KPw&iUzGwIDp53#r-*;t} zQ^(#~%JZk;RxM}Rcs!h`xD(`5Q!fwG*O)|~)06nB8s?P#>T{d^($`!+<34uKKl7dX zUg~KX_kKBxaoP_jMw*?LzDFK`jp;wgInEThA+;rJVqB{eOvq2WBU6iDm^)IQgj;z& z1^qQV7NzlSBjt~92k(9c-LCfnC0!+>RLR=_YvJYizkIZvj`H*I`i4zy(mRMXkUA7L zDarDT^C;RI<$f(}Qdo;MioaOOgX^T+8BG2O)JvqjzU-$RQsGGW?_z!G41TBOjpNw- zZ;a;yJ^l-@KTij$+SqW^eLGs1-^Fl|8Q*_M&u9(FajDnB{b*h4H7Rqx#~K9Er;_dw zk7qnjm$OKbcO>Yq4~CyUfWaUI)4Luu9HW+%c4gWIFSroUQn~`EPgo zwEJ)oX35FUI_(o{aB%yyf1V6h(iQZzkJe$&K`#9&X9Q?jQ@^W>S9I?x>BqURLGJ&N za;}m$uA_8ZopsUw@%+T|lAIsqpEctvmY~~!Aj=oMF(K~w*bmh4l zd6%INh%_JO`5N-~MTBX$uWYowvNw58*t!|}zS^jM^9v%M9fHTA`pu1S1<(Hi;(7C* z&}Y!Kl>dNwx1+y}{%@H>`a0N2`a{wS-~ygkpgqx3pa*oP{u)L7NV|LJm#!V(Kfb8q zS?1Bt0caDtD0zqY!Wz$K5l!AT;`uM8p1n)7*JvELGrf)P+m?U#>FkaZEAyGn$DI+j z;33pR?Yp*_*mK%DUX%@l&F7I@2vh6)%Q2}p6SmF`Zd?|%f^lTvo&={ zHb5ElwR$CGK1~k}_j2}>vc3;Ilo61cmZr&ag~WlCk(mDHgkrI+hoR(fM)uzfH$+KBnYs8KDGY z!zLx^OWXN?BI#m2_ej%8-*Lq0gfEHHN!tCNTzj#f=_7q|B=+5rqIU~-N2~Xb`;gqn zx&3C-jM2IIa1IQyF?18>1^z$m55%Z&6?r#jK9>=hM`Z-*9YEa7{vEB?|InYL?h#3U z61I@OjdYp&iYa@6rM}pDPOe+^=f)p0X677Rq5YTPa3*wzU&6w8uJsN{+i#|cx_Zxb zXN8B|y^!#LMRlZn2OcF|O1hM@xZLl?xjj}M=6NaF1?|H5J`Lt`mY?tK30wRdO_>`0 zt9GxI37qp+x%+tMf$%xb^o4F#N`qsif!Mi(7&?Ie*HCvE>7Hn>V4yt2d!C~Ha*YB0 zN5sLI#KRJe9kg2~8{kUHp67lf_d3VOINnp?9*}aYr+LltO^sLnFe%fRN8U;35Tgg= zba%FlgE74CER8kJBdn2ksZ0Dxm&;CPs_b;P$~C-iTbD-JP_johWa_0lvsl*njk3mB zFH6W0n~#qLtDW1Q?u+!o`~QpgL%-h}6wFhS?pAkstEm03#>GrafBd`;9j^SZK! zOLhLkr*(V`*Hb<%z1@Sr8q$6$tgqfMGyNvzH?T*qVz00U-PL%eM!DTW*>JO|x4_gJ z=hwm*`Zb?=jo~}3$Q`YO@3=GME(7DG^Or6UpGL1qzf4=BrPPeycj?pJGTohv9}?-q zIO=!za)*$w>vK9V|8N8Bo#T&Y(buNC+-2LgZQHIc+qP}H%eHOXwr%Sv*YsqP$-J32 zncp8U$@#QC?z7HG_TKlpu5+lzYqe>Om||T@0N0loPYSb4@DI~W`b8}UyB3?fQbkaG z)v8g^#wH!=OzS;;?|#+g=+-hrZE?ephnAfEY`ljYd%3#O^8U_J7=@gUq@Tcd=9$z2 zEEDxthxU~FHZb%aT~Fuw9g;548ojy}o$5kNdF|a#?mqTQyWf+{j=9GGLT{lW+o@pt zosGHNuJop=Qm$_#8`}cTyf9wZLx8{fCbW)8yGC_b~lKlw-GKx9->%#%iCB15_1lrpq4A1Z%Fh z-!yGS>P56EH%)I#t_@2rw4;o+I`d0)sinUqeH(At&I84VFo6$mCu)P)=5l>A7%tG| z$ZybE{m%itAtyI!yIY;~LtWCtEb_bILry!3!LJ1EvfC9WE#5GvQkj59 z)=&pqOPZ{q^v$_rheN#y3gw&clET$+zfr^}`mU z+GB7fxt^JIxz6vs$9#tMr}XcGL2Wk*Uzl0rgJ;ob$?o%6m6+U{*&`$A zB=^Pv)2_{+o8u9BS2z3w-4SktPDiYNowefGI<{REVIZl8{85%wdN+kL8@@T_17C5^ z4ER!e{0zl(d$8KdVOqKz-{^O1Qr;}hE49wQdRUtU?<^v-pPOdd)uU?OK^Z9yTLPbz z0_b-=Dfyv+j;zuyVO;w}qF1L#ot)rw?)JiW{2kfk^`(8Q9b7TzzxZD8Ze$;~`eXK3 z>o0m&edhN?uZ_doiW9wK_pODJVrPIK>c(ts@m!eNN;Ji5tluNg>dW%5V#9iRIsINv zR{{C+N5TcZQOxt`)BcKl^V0I^fg@(tD~h)xvIC?)&c|7avJ*Vc(Wz(zyW)H5Lf)mi zd{x?VMjd@l=$mzRRP2LhWlViHVJ@m#ZREQn?c~!98&)`zkM49e$|5@%W7mSUE$k5i z9;N0%qbi2L%sXt&V^cZFPVq>@_Km^W4 z&^vA$iGjflN%Y%7T8exQSk5R0gn25Nr^Gov0V@i((i~FrtSlg4oxvfA0ohuL1rdlg zUs*szt9eX6D^-nX>=LjAU<1uRhRNyd#%^_@~_$4-3x&sf!6^QVnyLUxXC)_Xb5g+3i0iW$_qO}@9f z@R@h%&!L@&J-_-|**KrLu9|%Kt?-YWyJr^5a37BM30hzow!n9-es$vdWqz%RTmREQ z^!D=A24AcGy~kIl`1=K}9_-ls(-6rPr0oLqe20DqA6I^ia?CBf4Z92V4etq2IoP36`8PEC7HQ*1GuQ?A3i;gUq93>K+ROQ8K2`^3a#zVpe^fq+kUkIhV(yj^ zZ_vkorBSa4L9wke4;^~WHQ>3$6TD$zpXrtIq%%!zT$V+*x~Pr^&W{}V)(`w5VK(3? zuz1g-E|u&8pq@vr_iz4|E;&x1qZ}^yIB!r5y9OOqg?zINj?V#iq;d24l8+6q0@-hA zw?Y{e1OA$Xh!iYN$b`!S{=zT9SLaTEA*W40uJ{tkMyaONL9eL2oZ6zs3}wyGrL9mc zj6TxtFh#3tBCUnI_t2#uSK+__L=rc_P8<3JEh0S zO*!X!)B(l?w$kL@L*w^md?X)q7IW9H_b1@X)I;ck%4YGNL5FHq(byI)V^*-Np54Yn zB`c6u*t9r@TyY%cY{b7+rRfI8a3`5`ooox+HRJkd4~@2TM*M?t>{r!h*wd!k$L6C; z3iTT^KG)qnI_t`!qR})%>|(nGTj6cCw1&br*lj+4@bb7Zs_jJC|K7_37=(X({{1hV zp-G->Bual)f7msyh-Zhp7mhuKFT~$e@2u8Vb)utapk1zGds{?f`qq6>7|(d9nrt|% zjX=Qkdx2}J=XhVgUffxrTFL`$h_60Xdx*0>?3hQo2YkyX0=~?&!1d-aa}SH8Zf1S? zu6B4@d~PJ0!fj|bRea3)(2qG_UrJ(aqOOXWJeFGo3-pAoqg1%8#lcQA@{4CC4M$5< z6e4K`dwEO>yVPo1B#CV@i+>*uujlN4H(#sfVA*WadknM)KG1BCw1M*FGt3MKV)r=J zbXVP$&|7nt+Ynx{oN~H49FWuJ3a&++U4N2}wpzbMUdfDYzJmO^qPk?g({CeeBG+jTzYEbiwk0k@sU3 z(Emj8>I_^mp}?~u$F1M+1wCKnCm(%KtS%aSP)`(z51CdNFtnOscJ1;HQ721>V=mwo z`7Ox2YFClWnyZUa(X$PP4=v+X zW2PI}IrH483l?+15>-Qd2%y{dbAkWMe>Nee>EoXPj|M=LQs!9&<>CE1v(henNajal z@t!A2iRx)jD^xdG{8i^4XqOaIYpRS|1}2+_>F&(!s|=4Ni2f?GDx%_Qt%Z4#gX^Uo zwXzH!;^NS*^Z5<$T>so(-12z?tTmHv#-3@*p2;!p>!Th*8+FrUGLlv|&csUVO_5RD zaF_Ha?R8KhEPdl-GSP0; zFq0O`jbI!aH}qZ`Gc^o2yvbSHg9gZ#@7Fu16AUe4So#CZ^nXt!3+ zie{RD#=Nt8;+knuaUPCJfaV-1PlGht&_y&1%z~uP-5LyL;iKkvfUZo*m?bgNI~)qb zn56kT%~3oHM5ZtklIQy$6i!IqdRR_5q0APdQAzVJu_F#h-X^qv1((W%LlPC`C>-+q z3W#`Nq`%y{v@}d5D%FVnW$HD9RMr3MA^xj93J=@iZaX_18C7q%Nlbbe3EL=~1`*=X z%bU2ugBh;lf4B(XDh?DT#6CwVDv|~;4A|R>-*Qi5Y^BO_hi|g38{gO z3eZ^nzwXY?VSY(I&!7O#BT~4MY7P>wMwI=@^-jbeynXc|YL!^uLf8o^fYk)#@~ddv z&oR%(&m9t0UOYCAXBR0*Gl+8IW$pW5--?Jc4TC(yw0V%BU9je5?zP-y=eQVSgbZPh zR4nI?$B*PqIU_#9VPFtr-_Q#)+0i-{&k%^))iW8-emWg?@c)i|5AIrgl47_;q|L{% z)7p$c{-71M{zIa(LkK$n%_AX-0VPb1EVe$iZt*Y)XBT-$48^Du^ zbPvB3ViY6pPhS0uMX(r5GZk<2Ui3yLPsw8lA`hAMJEM9dmk1DtNTFpfEjKZ=G#SI& zv=VRfDVDAj;3x>|TgjmDV$hQ^MszdW&-CV=ShSMBuZJ7`Li~iD=cs+`T>CQ?ijYlr z?tF67*_o&68W*MMokz*2$4Qy0+WLEbRXfAGQXW-$e?J`Lmow=;2;Yhc{ zcSGIARCSYBrqGgOU7hPSal{nfURrm^Z;S6iyv#$l%3mvOByw%>uZKG4yJ6{o#-NU= zU%;r0rw-Q;xw;If+=YUZ+K3+_|_J4Fy$d41vB$&G@PX z5MGZp9LJIog6etTA!RcG+qVu20DVBXjW^K+W#FG4Vu;uWLqxVz8=JGDM18q_j9^A zH6AZ_HJf{`*g(o&-6TFC(WS0v)ss0(_(C)MdfB^e{BNkW90Uvm|4&yH6VrbYd~3(g zS`IS6jNJM{;cf~$V6ABVj!qSX`w(8_^*5qUH%N#%zJ zd)H8g{uZhh-~Q)9FH^Ov{%=<5KXRe}|CO?YWnuV_dg{MImizkq`pyl8`hFfhApL)V z{6gRbS^U3W0?U8oS7l^nU}FE@kY#2T7G}o(6S5qw=H;w%jQBGR@Nr|O9}6Wp3UT}^ zEu@butcVw?ZrsQj@QYNyISHA!Gah|{I0OM%O0bxBBjlm1ls5&KC@wFA*o{zM0Mw?r z*|8uTZ&DcA)89~4g(_@eVrOPMSmJYV@#DJN?Ibguo4GgrZHA3jS2N0;2Rve*KSz}T zSZ5Wn2gE5e^NB7M{Fi24O}(!m`mM&y=jQXH)@34p_Kqjs$ydfU13_hJ_FgayN6YVmcEO3xOKg2L=0|+G-z_Yz<9=L8`0oRIfg8;9 zs+d#s;3__c2OG9;6N@;)*umbBE5gFjEsCAkZc1uTI;6Xz*=Oj55$<6~LPJn4cn)ZD z2hGa$*JkpM7c%E7ts7nm5NEchpd0F-T&_1+ch*@)en@#T*3a2h{*9}Qoz zQ;jui4P!)?$oG(!_-8$K`))8+b@(=21NI3*u$uK5t5&b%LTjP0OR=OHp|~==GPU7i zDh{X%bK(339FmuyFMDQ75O7a}dh-z<_5GUSqrMG2>~mma!J-qwnA|N;N0VGyO3{Q--tE8d2Bo zQ7aLe^(t5Kc9y6sVo}{|7{m~yX``CbcNA=nczQ}Wq>EP0iY1k@36%-hD{wR3zi;|| z?hGi+9=T!5-V%7o zd)107M0Fg8wA$6um-U-9W;I8v;xHEj#)ehCO9n> z!t60__i^|}RJBWcSOP~DI4TO?mW1dRfIK61@{*b=ISk)edq*!QWF7qfbtX zQYMQ9Sx_7+1H}|zs>rFT$jdHC$u9xlV}-NY7@FK z=ZqeE6u0?CP^ll6=T>H0)_RKjl-QczZ)jdyT)Sb8DJ*>DZXQRe&om9!dD6O|Uc3+gJgi&(3FO4kW8zfd^eDTC~@;*01^s`5jIht5KhG*#pN}fI@81po4u+%6E7! zQ4rytc6vl+vzjsF)Fh*e2HBQt8|lQNW+jw87&2U~w0YAQ`e_I&swFXIU%pjn=N0sRV>?c z0gP4Q(yzipPM2^g{hfY)>#rwuAqbyGd*;lB4T=J$ z=`uJBKHKU;0I`_74>_IUpXToUI&U612EtBZN5=4M;O)-=Zaa(w)Xc=Z)qa*zj=d!6 zhP!-__YU=pa$zH?q(^VjiT<`HpfV{&$*CusU5H09dp6iW%BR(dJ6t7r;T7lItWg?` zH(nW{IvJw88Al7F2HL(kH_XnBjcaq0y$qv(*7NbWPie>XC2p7CV3la8lAO zP(G$$3fJKJlh=FnV>k=9ZmDM+JEY}T)8x= z!ya{EtIzEXJ*|4E_ z%QLkmzgnfYUm6<{d;436I!O?y3|6hIQ5K;&5V*a$Q)-GVVRO5Y-8I;aVkE_c&-Q3+LP|h*CN#8sS)RoXP_Io0> zMTBxUBR25 zIRdHZYwWA*6oz5K(&6mO=$*E2);KW$JhFA&QrXc__}eLs5uY01cF%QUd@ZaPP`ZEu zr1fw?D`^=*>v5G@G|HoI|Is4;!&jWa$jRF)qW)v7C!8<&1OBx&m{AnJdG;TFV>uV)tSSn4YiQF=xMf)6DfZe+*Yut##$uC3oWu!?cjRov$^0kGeY~;W$twjv`wp6-wkKDfPY+ISLiy zQ=-D2pSHS}g32l;|LN9h&l<1WF5TpfE*%Xux`qZFwAIR044H(2OgVk>pP-El4KpNj zW5aMwBWAE>IaaJJHsvC}R|&2bA~HJjf{3H}^p?eR(~P2YmbV~tQ!W;ppxE*o+g>k0 z?nU0MN6;7F-rZa7T>$P{GWE?ijd+>2eqa^}Is6mff>YeQw!?$|dHYIk4Fqw{P?SJ5 zC@p5vy~1f)XqcMKSw>!b3taULmpsFtjYi`y4X`X1Spm3O%+90lnx4or>L#3^g<0ez z2NkY-!lqRYlNeZ|Zql%Xdb5t!u=!M+^v%K%Ja0?H`SH^{!73z$4~+i5_P9s2z!rRQ z9Bg5ibPQueXGyD!n)(NvUs(j;^tkM9y~pZj)y{m~i8CeK4;IM*oZZkm!rdfNhNR9I z^=G!h?Vjp~bGRr5wL%E=c(l$)DId%Yg=(@}rv2jAh2~2$Yvtn>9kfSx(+-BcF^=wP zjq7R`5eiuhBmz$E%Nm(_e{qCa@R>5yy5f~t^)fS zV1i^?)N%QDPSw%o{v6E~mG77WWy^SiNA)D9Nx`mA26dK#Uw%&5autWqs6hFGm-|F! zW?->+29!XYs|a^TW9u*xGin$XsCL!Gk8iyKv?d>Vzqn`i=#>*G=LcoKOHp&FtO=qV zZcFK}|H&#{Kw3}xg&^IK3hIyAxWI5V= zoNyPO)&~3J0cbRK!B;ZpYnzQR!q%0L7sp86h}s7mv&LcKmIpGXA5$N)K(C;~4T{rd zOkvUmBEJrkNBb_g?d)+((%pW`u<}nTJw9?fcb*E?o&C0EM_~9h7jQN<7&s%R?2|Sl zN8D!sm(awF3L$Yr80c~k;=B>h&PQA`3&jJB@!tCXa3@f13Mi@|_T3 z2QHQIEX}k8M+F-**1r8<`QE(QGTL_?qnWBzoD_!Hjwr%lz+Wdg4bv1Qo$)9jLwSav z=%)sQLY?vxfQVLseuT|=qmJV4Vxmv_Wu_J|R$F^8Apr69x5xi2OH|4;KGO{CyN@9s z5pXzS6~cd!0qRbNYIo6aZvS!seHZxg|(Fny_})>Jm4p=lePF?*>D0M^M))X<6B`(jWcwk-8E znKJ!=Q8e90bupMRHic&tM`}p7+kYrSL89oxCKFP%U-OhgKm50rM@7klVNCeN|H-K;;F+aE~KA-`LgJoTMx zc$P2-&-8Y_D!-Wof#)jv{PSRQT5he?3XFn7x3h-_@sc@Dj$8(gL5H|(nQg!?V~vC8BJ~#_XkrvqPe3a7QmKL97qu|Injl|KHjVw zT5H2}cuHu@lb52RDxUQ$cVPd*6~QcyHL5kW4BNp&bEgV>`&SjhGw?kzb#zIhj!)vC zpC7FEH&Z_jCr8e^J|$>#rakZUiCGF}Uk$uaOg_55tjzE^OEy||Pjc*1mh)5pGR@R^ zv1E1R1?@%=SyBvmWMH1!azH5P&f&{@Gx|g<(7!>!DC}OEw-BvFOTn~ z#b?QK_q#dZ>^)2iPqj9tsJHP&0x|ou<&N&Vve98WKUUA$gJgN3k>_P@mL1SN-}o40 z+csGtL;|kfMPUkXEpyA+?1j9nng3HQ008F#tqp zDH)7eSv$Euyo1wI5^{jZm*FfTR2DVS&6E&DDC=B7AtEdvmNsY7fIJo_RO@x{T(#gp z%`M!IZN~k;u-HF6b=0^R^ujgFM?aqYeb%v5pA&|iS98?Q32U91ggOnr;mAp^a;|at zT+;VzjF0mIn7u{Vm{B_|AKS0-_$*{5*IF}rwaM#(Y4+)ctcP@y&4y$7(eU)4G3XLd>$q`cat)gvIRt2QKAIX?*5g4MYAnZ0O9;N!=g&0yFhD^|-7@=lPndGtJ)#Cm9 zHvm++seBXo*O{pwDipr+cLJlMQS@Gpn2adL6m$(n!|NbiCFj8uC?nKJQ2L(VdCm74 zSq=C1&ev1+^<$&Y{kr7TdcBd%)wBT8R$aU{fq<42NHL>WHMW>PTM;G4oY0?uCWHy7 z5TzJGO&7@Un&M>%FiA)PtTZScifHQ!E*HOG*~w6rfHVcbtogt{u(`k-i*yg*W_x(z z!<+y1@y#1M(hmJ`cvuC@S_0S#99KMXb34uqgKvDPTXV@jgTNzSWo_wUsRB|H?jYL& z0`rGj)xl7Ti&OqI(`mK=p-#SrdSqO~6qBt|IK{~MC}8fCRk$)RT8Q66x-=FJT-pMD zqhBbWEXsDi3aG5?4@Ewn{H>MrwZ}o9dX(;Zhmo2zAZ}vg4x8WRLi5XWF|u%+@-uz@ z7W*Q!*W)8sM>eAQI;gGHcy&ikyUpR09?tiUschV{Zv(`ePRI+UJ<>)om!6BlUY80p zX6TP1>8&f%ELwB?YLWUlAvAp%o=YSPL}_}HsC{q>sTxjBWNM*X9}nW`LUn=sX%z)- zpRyp&Pq90&VbNNG7?dK0Nx)A6*r7*K11gc(Ne`N_*w|V4Ibk}6wcaH2B5KJdI8h0&&GJB<=FM+Sgsalt@>yJ;#217uJ{Gv&Q{cAJ5=YUutUM`P>dY+xbRac0i=%3dHiZ zwiMPMCjD4%b2|ZApMtA_crNlT_*4RCa>WGu1c3#ferfZdq_BvJhNoV=+`KsG?tTi1 ziTLzH@v#kzRAWQ$(i|c9prfJ^t%PL5@k1eZ;V}P3?)puJqdS0#I+A_c*3r+Ztu4?R zfyDp8~Qop_Ei8PBR*Z!$ZbtPR^1s9-FoTMQ*|% zR=$u^Yzm|ebRV}x9z_Knf}?ED0Fl~9_fEs)`msfgp35ISA3*=l6KWs!;o(%`Ml;0| zBSP0~|LB=`^%i#kN94DHlf`>@I=l9Tb@2AFN6?(*cASi^`KH zb^}Y*86be-U_(I>&y&NF$RRO+1glk+tLVjge#x81mN||~MaDuF+c)iQj1%CLgb_Dj zDh~QJS51SO>TvF+njn}!zPvp5krqHAO&r0UOe4R-AV52>f>f^!Q=bkk{weNk_x66$ zz8N&TqC%#6Yw~jpedXl^XR5yP=676eZM*w8XgQHLQD3|Tr>_7>HTu0sk;tvM`0jM* zJdv+iv9`Em0rPJcjzwHagqz}RVQopOd_hH9Cc4Z8F@n3w^5;eLTCsK(J(1O33^oi= zL<`)tca@@*+*$QWjFqrr(?k%!-K9HzDlL77mq%)`$x>wnSuNaI;vkD9wpaco^N+C& zg%D1^8f{2cM;{)9E?J~DA~E79szTgAraqQH=AWVx6gxWhCWH0^()D<2%+m4(=d66a z1_7M&_ny#+fiR3z54dAi%LB7CVuVH0x9iYbnNUyD5y>{^Agu%vL2=5IhI3zpeDY7o z`20$>We!9|4Fj`0BWdws4$r$e(S>K{<(*sZ&elVi_3P?x=tl3&701_9OrWII9pm7z^VIZF0kiMRM&95;_gm?=%LYxY#2+l&n(1nuFMUr>H-&r0BVb&oHRfJ>5 zIvH^oAxyPnK_**u4~%hQd=50?Ksrk#FJ=(wF7rDN-M20X`v7C6j*F`8FRgxVR%%7M zer`R@bx0ra2ZzyqoYgdck|l9-mZGxdPPR6}cr}%apoVIpeE`{{_fc*Jb`)~E;$$yX z`IG98@#9S}y#{vX>mMOT#}|H0br6S;J07-SzeF`#lCX zE6bH`+uBDrx%tfk%)hjHBd*it+p5e!SEKDzaUxmYimHEFn-loTV#93f2McfH&pFKAC+58Vkxi>CqKTPMTD3IM(vG)} zC>AMiN~V6K5z6{LgmqQwm!mXFYha2bfs3b#m-)5CZ=oasUk22H(AR-y-= zLn&?aK!8wUsF3z+UiF})hz)VvufMNMlO88T+Lp`Vg_Nwsa?nh>i*P^~9x_re1lx2c ztds#6H7T+lW?F(^|F{4XuGw1zWj&tz)@@+$k#o?exUz$3IvXrXp3TkG^5cESWwu85 z(}C>CaFE5gbBaeg@{gs~beHA&(dQ7SKIdhZA*M4`mADZ{fC-#Y@-9oZ(y>m@rx>hKtl9L#0vk@|d`o zz~Xv6Io|=i0d2$cpg4JJ&Kv#uGBC=rOXzHSTzBnux0`|6dgt#C z1T;_-qBt;VXIR4_2&xfSq2Fb%0>~bef{;+mHhm&N;qcZ|Wf7{<(T7ptWN0oK1JM>n z+}R~^qh#4fZ(LIfw(mB7T|2<}!6id%G7^=Nr+~xqqpb2y>!J$G7 zmIaCNk@ODR1)3!y>`ico%93M`8mYo0=?r=_%D5BAEYC&dDdic)j>~(4UuD5(ri6`# z)3c(hy4G~kt`F7fJ8X| zgqiA(1OWqR1guGX16-R1Y6S=fR!AAtD0<9iWT+%N{h>Dtko2yqIhY;DuSJvKUoulQ zzn3tKe#yeDFbv7W%x^s2BRbCufTfo5F}`tBnb&aJo;XkkA;*OorgbkM1d5lYc4;Lx zy8C+C9^30;9=2~UBs))hjqXXz$=9`G9K?cq73bf+7o%WWW(UmW(g{c-S5yd@_3qbQ z)@9ljw3b5@eR+xz!JU%?qiLe2vqEt37w$IT{*}W>YkyKJS1wR~f}{f+Y4aW~Nju{Z zpf);g-^;qb!5RmhkX9 zkXMGU{ssSfSxP+omPB3%DL)I#)*jE02bzQIO>-)v&@&Za*7T8?iHsEFCry{e?CtOh znBpw4nVh^V9ckT}xUa>zz%aKP#V$UOb*eNiEiGy)Q?@*{>2-h0>#3OG_vskTQBG~X zY98)BK0eOVH#*B*(tSZ`D3sHi@b;+QB5@n*9ub}=4{1!Qk$v}K5r8U5pem%GoGyZJ zE+O?;0_CvRUB__&gHU8a_3GEAI)f-%dkmdkAXlN`u%bcglTZ@E;;1BYhHPRGaM1~$ z?$(zkeg0=BWvqjETa}V1!!t{75(;;hCn`Np&psvY<*~Gjr(>>}9*FBpU&tKzXuJ^iW-+ z_Zjjb@il5UI|S85@U8G0Y{}iE_Z9e28YPd=)k0n+v0bsNKVPu#NHn8jVnka8-!oU8 zR_hzUz3Zr^0uoPUf5iM1%VYWn@4iBHFCQuqH@Rp-WF^O1)k7_UvKeVD$)>nbrK&7y zS*lshWC^I^S%^l2LvTvc(+oVyu3oRckS2R(#*k7i#=uCUGtG-P@jFs-jt&bGoAC8_ zOlVv@5+o@eP%vm>K`{q#e9;^s%dnWxLRm01?wEVT{>BLOCx`W97EYP_o+VQ?99%1o zbL(?2uIkh0zzx=4)|!f+TJqX255Ptspqw=Tb#n0$`os?4wL8QfAYt@`#}HkuuZ-Az zsfCat!u{+dn(G_kOTJ3kbnX`*AO5$l$mq}f1W81DI4T%nlG!xRY@jVqN<;!CMQGn+ zutc~7iWFk)9g4;v@KM211oIt5iIoF-iM>QeAiCnT#A9Y?-(VzSfioZDFG+6iU^tOB z8y~QumZ&Za)T9t)^|rGqbA3Hs{Z9As^v2@`Rx3(fUJQ;2ci_JjwyU?ruIBG~drBp! zPmG1SyG*65!Vl*@D{u*@Pl-TM8jPY7tY_}J3>Yyu1868Q9-3;&GBf5U9EJT9j!-sx zCWVS9V7T-PGv;GUk%)t{6sb_JP|fIn7<_EeDIC~+NN|-v?%(Us6g^6K#-KJX7j^MG zQWW;+xv%P-{{0C3q5DMWQaS`_v4p_L%21}@n<1{uJKP6{vkcFQpukTa)Ke`|1(Lz0x>daP>ZC4PZe}; z+4jR2og(CgT2q)c03YO^R?m&x2ls?6v_;v61MGzc zBpqbdJop7Q9+n~QEJ1eU9>Eh0KE%C^AN`&4?i1L?m$)L7_XasLKz8ii&``R~Ht5^S zK9(2;3M>zvAuh3e(VW;sELWjanBM<;bkH*hp*7i(5rx{Qm<$&6ZHOgY|4%cDM}zc&t;WBKO)CKM9`xm){@yM}o>o>gZgzRscaU5E#3N zNU8<`3>T0=9_YH%u)jnW5GaxODGYOIhIq9@pTgef zS%>M}mop8_uK10q0mP*|%K#vKRdl+neT{xEd4~5E{?ePBc(-l~^<5dg%9eb4>P>Sv z2_o%xO#hu4K>FDzejD{(wSgH|-BZkm-1vOE{{Vd0wCqwLf2?tvGd8w`JJf2p;#JyH zd*z(!I$;~oq?)Vh7xf1)yfN#u#GP=MWW~C++UJ-O9q!%DbK*|#_*sUs`K3!)NeTZf zCLQrn=L~3(N>55b_2r&%Y)h}Qa(bBrNq;VIXkdQ^gUqRwP%jRByF6y@%vF8h;F+j& zta+%I1D%}G)lf;)_X=sD|&Qq<-l2S$+9|kZbOh303-cn}j*&X?mG0aVy^p zu0A63A*BGPX{=dtVisDuQgR#56)-k0a4Td+`NTc>jCV0qDUX9-A@+g$4TpI-lMJ`x z`=(lvrLB-sky|4Vmqz~gLR+qxr)cheKf%M-IdYcNhw@}iFR6-=|ABJyViqe%-mEeE zgInGyXv8cNKYSi-MQ_@N^Jj~O^lrM|FXy7PglU!^p5dGH-`HitH0==JHRobGe6{vo z(I{&~BF0JXV`=&RN0M)yU$u|-kN)8uHWNX|rXR4A0Of9m(W&^>W(3w`+U0g$Yce?Y zu`R%n5)zzY7wFAIfdEzmVAh_+wT2V^aPHzjx9oH95x^1mUQKFrxPGZ*eK>u&Fma-2 zz4(bqlbW$dBq{C#f5F@2W}oc5>U0-6!DH95KFO71uczN@0f;oI_##`F=QZBBlTvs- z5^;--5j5G+Zk*f>xwY8sHx2%Y&W?9k(%5fdSB{Z zMh$*anih7dVGVn%RUhr}8n?V9?REOsY%@9Jei%K2^C9ts@hS5%hT-h0eB?%W>yu+NY1j_^E^z0!CUw{C90oA8qeFLv`&A)jU5$r@=jj889ZZ4|PZ#PFQq zCF>i-xDch^jZ+V(K}U62yJ&|lnwf&$CwD>`hI9xm+?uQEuI;3f zmK+|7A7eR>rpe=6ShTv&AJPEOl=iuQPq*BrPhX=ezdrw*)s~zXy>zp?|4G=0@IxC% z?!PT!Kcrv!>5~}g)!5%Q=4<(S(6@<6s9Qg$tlrWp>fVrUU!{C8w3?YYKO<7sBZW~)w!jvBYh`hoWyPjw2c{nB z{YA;aFCxqP8mEtx2J86?@@*(ApZA2#oyjH|@T~ogQ>ZK80mK0Z7bvO^?&Es*HJV5M ze7|S=e7)#A4VW>TG22aje9+*&+0QYSdtbrHJ>}#`?>uuWR< zoldBE8nosO!dOu_ViFUB6=%Z}xpv{tKzFl<11wJrhqtUzbsw+siFI!e#lyCchrQ=e zud`KOdgTQ$DVRg_7`h0sc?ch|(u!?Y%9&cEa|7qS;>WEr#j{!6jp<@s+O*ItQ*(%$ zyj^U*`lzGzQbf9hueO>YW-lz3z0^R55Feu+zFK5!?!Rh%E0!o(DAjPH^YB5=Fhzem zk^G1yxs7*QU1uMmerSoA<@B*;p+{AynZ)xR#yOm~W$#ojVzU`^@%E8#>kcoRG---e z&(zS3axu|>Z{wv98JtaQX-X+J+ounC+2)|*)4MsiXEw)LHW!qu6t$9jFKL#a(qo-H zn#Bf8KJCfCNBvziJ8d&k?6JeX4>DVE@VJdBy3Kz7#yEgwS-vrT6q2)o^KYj{o5v%! zi8wvL*vPt;8*vMMaK2iXxsK_n-q6?zp^fD^ z#7&l5A|E!|*Nf?co%yK1p3dAucy3}>)ht966FG~7U#j;>4bC8HLvpVB&JEB zJWJ^R2vMuN3ryAjoENcODV=r*?7Xg%zvA$oF22hru4cyU;fHmb z22gsQ-^4^XzghCUqxonDQCV*_2scCZ_QHqxMJr(RVnz4Cg2C6X8!fWCEB7T5Z1$i4 z!I2l(YSG+9m7NV{{&s3`B8WdN9q1=5lqTiQTqY(xE1hSB^rZSNiPS{RE=^?FO9Q!) z(n%ud^_O|gq2*`BbaZ_qlU&g2@wWe;y=RjIawF3_$cHy6ulv-k?$G*Ui{)R%Hwd>o zF|S*F0q)@CRUytqwX!y{=|iZEFFKXoPEjl@!g9)UpZ|sbsbC3gyTA9mw&Rh057|E4 z4-b?ch(%qk`9QZ0*%=(x+zzJjxS=*++n=*hZ%!BLlKmfq%l{;gW}w*M2kYGo0*FP= z74rFwfs0KGX}a`_|5wP;eAkn|Nk{@+6v?)EHsZ~9bn?r@`-7hKV z{Lv(_A*K_{sWhY7qunwoCWPB09y_f&XFq!dk=7@t>ILsFePE2KdR=m>M0uI39%Sni z9c!ivwMO?H;%#pX(>DKzJK(;hO9v_ocR}a$jw%iMtH4A3)T#8|Cu39GWC)RrExYslB7*_?+$uz7h`9}VOs2$eEN%Wd-33obso%VjKex<%~dn6&%r9 zq(*qsiA--7YhBxx73)@OSw@XpXZq`-yt#DgWLAS3FLiqd-&m-l9_0<%W3Wc3v8o=+ z5!~rH;^Y(m!vq9-*kSm-RnM)(;S~x2siy^$0>cnr3`ID<1*GVt(jQ2@t=N7KM33WU z??eMOoRui>VVcXB zG`eM#C(bOUrWmnIO$%)yEoOUHlc6Vzu9%=X7;J|U+@i_x4ziL$B$kl53WsZKFMJI? z{=-|lb?zrIR8;EgIRlWpovP`iYF4sS;j>27sa=*8{29xP6Z7EecqN=KhyTIYIRuFk zZ0ovh?Y8aSZQHhu-L`Gpwr$(CZQFLg9=*8t#u=Q7sK}}s)Fjs+BXfQKx77avI-eJq z+V}5{5#iVaQo|~*j4Z*@zxw1wwmu@^UibxT;*J#tPaSz>fS%hegxR{!#%B0_)=jZU zHQy)ZY%MifrnyvelwLm`$8w$g!q$4ewhMC}YdYNWbJk`Q@C*qW;)dP_1*%!sVGN@dt>45nlc znge#pHDBin;H68X0W`DU17vg3pZ9MXHn4fr*;6hlr(Aa9CFa!;&fYql8LN`vM1Cdk zbRtJAQ^}^GD4nZ#+Stn17unblZ%s(N8|$dT_5e z8H(=VE|y0PwSwbjBnk1s-t)Io-0x**&rnDiFRNU`$0X0*cl0CgE$d&hEArX_+&#b? znklpwU7VO6gtH`6Y6)tncd%Z!YxEDD|28#GooeUoke*4Ipr6SWt?Es?Qt;G2RMPhI zR{BI1xozg$L+~z{s-Y^md?H}pxp!Zo--lg%Pc}&vhPRGK!n}8Vu(DzX?zNr>N>CE6 zdfgk6SEoHXn_i@4qzg!bg|vBOlhq4^k?zl)~-Z~+POz{&dCZ@+(fwH`-0EmbfFxqHZI`7~vBE!}{e0kTjokO{Rn z!crkrE*p-!*)l(Xc2sDwew46Hb54-gLpFSIJA2#3-eOVBN=o_G1dset<*epJJd$`7 z+L)roj|4|=fEbc009P4z|GuJ~I~L$kWyEd6i_GODQkE|{wu5C|fX|Gh)rMr{W4?hi z0Ukw-50KttzwTpeIG_mXO8(t3TzKEQcGsPa92`@{Fwp#tUNgTnK${S#~%2rjnY zB*y4S1b~Vf;p9(Wi`YA;^)Am(N|;YwzMX+i@ylQxIj5YH_X_3*ppP(#9^ z$^l7Z2MCPf1;kw%u_lKlLHc<=Pl!!oPu|uhsb&*;`g&g-kp)A5)6T)Y8)knULQYC$ zimh=AzDi%)KPJEL+q*58oF{TltL!R~j(JcEY|^PYGzao-R#UB47Efx`Eh$}b(;9^h z0R#1q-jbeyod$K|#=I?nmWoGa`&F_xt(NI)eedOcaXS_!j6bI@P5V;#2bEkidRtB6 zU)6TX;ziQ;8;y90ltiW3U&7@DCxsjbm>*G|anXG)#=b?UjD;?>f5E(fd2Z7?q3BWO zbJb`Vfo`krQd0z87b9}{d87|^$*OLvfD(_$4{Ajdn?wOd1ni08?Y0ytneUJ#yHK!d(XQsPqu0obY4ARq-tzZZ^>w|q zl_%!xDixPlqpVpjP9ZFnA_U0v2X!46$^(uGV30-r`AB>nV-R|FsdnaI+bog5IZUJ% zau%evdrone`j&wW(!4IY#8qcM-H8HaZw)W}%{*_5f|0~NGuQl8ps7A=T6`n-rWvxU zBO-1@5g7N2SOGuX4l zE)v#%b7goC{wea7!kZJKB#kmWmr-x@72EzhLx|#&U+svl8ua>7*lNEnPWIa{`x%uK ztY#L3n~17mhGLeJY&2#Ts|*E=amB`#Xc z41C^3-7Hd+HGJuT84qpl0w6d?^pZ+H1arbxSDV)O^0re^=cbak)ziO}xfcgi>U{B>MU-+R7 zbkr^GVB0A@BvJElGW)AFgG6Iic%w+al7m{X8m8zUy+(DG8{dp`oBiWk5w4d?FCIjV z?$sO_xPJvOzsoAtt;zWtPma#1wmc@>Sx|N?S?jW5JiCK^-(#6D(L;bvi_KzV?Z%0= zvrmhV#!Ikc3ocx{Bv-{|Uy{4t8+XS_mp6B0J*cmshjbAkW?JoQfoZxL6yE*BpaT`%9#7rt%gbbn`o+&Og>L4} zdy^*u7GL(Jt>b5ECutkOe3uK$MuE&UZfN1lWcBC`!O8-3E=D78l2+?9ScISd$VH6x z$@`Ni8Z^?|^5&(qrOEU->RTt!LNT}A`XXepQ`DaO2chDMowqKrhkx1(y47(AjPT3W zkr%o_N2~JyGxVW9RBrx*SKK!6c#1ONpR>NRZhO&E<2il6UofrS_>+d&{2n#+fVXrgb&zggs;GZ50 zs*F{ZaPsIGO{^KVXw8u*L{XLdL}^WNay44)kBfqE+)0c(Ko7>3o=W?@raK;-KQ9?>1zBrb zqPL?{^@MbRQhyjAtp8{Q(hw6Y@dV`v$J$es)LPQ){aq7(_=`$GxEAuv{x=Tgl0(J! z*hri%RWBjo5ppIPlGUGc=gWcd>t%{bQbf*bqh?xWYKRs`#3P>c`jr*{hyE%mNh38meYCSJ?x_i%~&YhtVmiL2SXXmVc}r2heeLDCW*k96n1~ zkn0TaJ!IzL z76d-#VRmm%kt_4~fRKt|KNKB>NFX#Y6k3pu9{0&bJ7g|9ij0Ahcz=B4$!l0HJM-NG z6CdUsX4HUw<~E)A_OOd;(qkgAhouTagr;(wtP*pya-=h&Dbus>j&NHy4rL_4^G&)3 z^wx~8oQWsgSNoADRbk#($2jGa=IVU$xT-V!Yf6*9mvp=0xO^?B4sB-fXFwa*{UrA& zb0odxlRw3I?I-zQBC}okJh&XI+}c{hdym=cZORefWJ%hGDLWiZXUZ_(yugfNukn=!kW%bn4`MCiA~v zsd=yV&>AHIYukh|6DwnzN2tY9rAU{Nx`)FP(*o8c$qBQ+m>3|lKn;{RNZ;&e8gL<# z(D;X#x@veIU;r?w)iu4D^4Od1)m8cdQ+0Vm{bdVC1*l{Sm>uE6wg2|Z<6^(+8}0|i zGovKCA9kHNgVB;&Q@R7ggDn?5B@(e6gYXQBJ=U8}W?yo#sJINgV$slizQo*_av2dZ z9!{}6mP3#yd~+wju+cN2>xYp`9G+q|`Vz5Bl<8@uh;>mzr* z^)PPgBy*uJ58yhf{Z2%KIxkyYNzxE}?x^WE!c5W9SwtX{sAPd4INrV|=Bq59Ul`fy zz+w77aIg&j4Pwj4%=|yOSFQMoUu+ve_~jdlIz#wYG6p1)fDP7l4&3PjFq%mQw#m}a zWUr?tA4{RMH#oqU$s{$b;$3aS``=v$mXjd#g}Vjz)WMROzDfHdiv**wd)Fq#=hLi= z{AEIhla6Vr6|0DF-#)w#JFT^mEI4Df8Pbr=bnL}d5Vx1|RPfN0Q@Xb)en;(Zw$Fm**hnN+4uL$jMTnHaV|hQwJK)+r=UZU0bUNTvsc|Af z@Pv7=c>-stG)QV%ez95##r|0t0vW#9vBc?AR|X|wX|BMO>8%89%;J&`-42hIjvw!s zEhnohr%=%vA}G)TXdq#7udYo2fvfOnr|htIqrlanCu-QKgQutk1pR7ermC8fXJk)) z%xQe3V9bl;9>;>84^9ZHd~wazIHpLSp0doq&EaDwZKNlSK!GJ`3)R0PEohozy7RnB z8=ajMMxS3{Y>?T^6B!rX+>*4yrd7}c?d3&P*F85#5aKz6Folz`cw^bZGq?k}rmJkx zqsD`?P(hA=s{rgxnIrwn7m>jKZZJv%I@9vP2G&jv4zFdJ%t4R%~H7)aUlZC zoyLV=x)L*<65P)MLjb@cbgEHdK21ffIuVhn|b2dEr#BY?pC zEGkVmevDz)jU$IEkxuY2BqgDM8|)M(IIeCvkIu#lkrB#42B7^$TF6CBu z%I&(-7UxI%0pleNKg>A>XXC&C*gktqL;q$8%G#heG>V}N!{bjvQs_J%X9G3l_8tz$ zOOL1KQeeWj%9FgAa2-1GT4nsGxqW>cadNQL8m0gkyp zN_erq*)~&@VW=@b^uQi56cdT-NFKRB?t58C9^L78o(%%k{BFY!(u1O|wqSclE`$3# z{(vFnM%K*Rp*zI2^LDBBju^mF*tFbbN9cU+a9$A5kjB0S^}YD((jKQoOwyc=C3*00 zxpwd4RLVaket1zNVQg}f7fDQ(SkJWB8Wo_;nk^f(s$}?>mc|t;)S>R$*!D(V zN&xDs6ngvs7TC3xjv2tlmMZ+LFUAZAA?F8#W2u#qbc#ahXWO28q27EkPwo||u2WqL zT{~ZXAC(z)JBCPeTBA+{~5*NV+pEn-@8BW^3JMcJ=$|@2ZkO5)-mCA@gTdlo!^X8*a5+G*|k= z*`GS&$1T4X-g~;%=^i6+k0xYk$>H@PTI{Bdla*@>H}h4Nxms?E*3C4ZY1cLzt!|Gd z88yL@Y<`!xDF|AEQnceh^4a;!u8&2<>cvna8~vQYxC^krCh?P`HHil6`h<@DxeFJd z3BHNruuEozcn z$+^PKa>;C;I?ZD7nlPbk_#%U)Vqxbc`5Y;0rcARUalYPbVD+$;GA#sfI%~v^{b>^r zhK+b$d|KD3OpZ|A36_O{8sUB8{&-*Avx}+ z4z=_LhJ-_J`8tz3KrY{-$AhqzX?1luJE3C=ucb8K_e1zqd2q$yPilMk26lj=5h&VTgIr$|Q$8<}d1m6bVHJ?s8 zCr5rIYKO6VVDXa3pIB%?hj&>~XXC6CxKZ~^8Wax7O z@UPotZ?);3Nvw!y8Vj_LLH1nbGLC5OhDNT(qzi5N+x5DKwG7Uj>jvu83q4KCc_Ooy zXGD0HYVuS~$KcZD(sr_Th%TG(kl(Mqrnkkt-ntgv14=T<$ksTfG^aGFx859Ma38rr zC{+7&6z(0&*<&c>QgA6kQFr|pT*2-Ce1)obh(}yFq4DejrAQj2SB8fZ<$#h+B-|ac zZ4*F~62#+74X>HsST+rn{o91BUdRc>>^uEyPh2|P8Mq|>`tvPq(^Mx$d5pF&{X}N) z&189AKuN-~r@e^z@X>byorK_r5Mw?sQ{+(puteH$R2Rv#2tQ6&;x<&3M@3X&&e~aA zSnXAR)PhrzEPS#;lcB17ajB)W&}=O)h+{HpET$*T8)}Z zSsPAQ(uwazTk-(?q`vnNO}Xha5y4T7-e3nNt=nAJ8m?o26th zf@*ATWw0(E0ADEH7@eN3G$j?eBwqEKj?knrHOPPiEcw%b#(3s23g9cu7srw4l%?J3SXgZoiT@K-hdsHM#W z7HBhmL{TOG_=&$NJq!TDzYudt2os4Z4ei!9_+uL*#qbAV?gEf{a!7_oF{_hBFGlBO z@bhVVxq8PdZ0PO6wbAQs+lDqy80&c2TwR{kguNO^TXTW?m5YT&cSPr7<(bkWt?LAR zYPI_}%rT|8Nf330zvB&S!inq3l`0F>K$ya~osADt-rg>7gl!MJ@xg|pS~h*99uPo+ zwZD}S* ziL#;5%;=clwwf*F_;~fcbP;Vqn6!ASxr5S_O03Rp)?!)4z@8E}3-HY80JuEvcQ#5S zvl|s+Gpm+jo!jDqurwi4$5UHPNo(Fapca!D3W$N4ItB0Q!>+Z!wPCf9ET!FF2J>E6 zcBDRGA)+;q_)MHA#t~)_ya^oOGjJ(1z-eG%`SekbIYT@pVklwoj0w`=20Q&G(|d?{ zl%t23oG#ZD?*$%nQELMn-ChImyXOdAUW1>q=IO3?lMkM?^{?A1n~>V(37p$OW12P7 zo4Ox8A8VJ)S9F{28E!3Jbc-}~#F?oyrLV1YH(s~-pT3tCoe^$yzmMO*12d16qdn;7 z-NgMQ*6pv8GR}<@cL#06=_G9PuSo(@|>dwuC7_-$Z*%9 z3Y4aJC5=Z-rZ;iWi7VixAieTlHh(3$gmOak2wRdM2jPXP+ft}4vw%JM;%q^3 zW%S!qtBI=8K*r#>Vu(%3pbzG==Wj^ zqAz)+v5UAivyR3%`=>+DReZMC3!BLsChZldWCj%9D(16N*F$d02HkcX(%mQ7A=d;a z%6sTciHr1Glrk!eOQ{lhP0r7SHkDuF>XY}rDkScMv%se%IVhv*I!wgqAj6qdf2jzK zC@~=mL0zj0f!G`nC{@B3d(3ir41R{TqgM=&$i9x(TEE0!RV#en`tUkbZ^+JMw|>CA zF=z)TZe=@AaWcE@FRVWDygsI7!q!#*8l-*I;Vq+B)R7(lf_I>p8jR6q;1fZN3#r94 z(}yL25*9e;T^_Q)W*(3Agg(174P#I-9r!Ro#UkmXFp`dJV)n(D!1}MBgyja29uRJ| zc(22xO1%tMLdMIvVXc5cqh$j2#}q}@z&^&w)f7z>%SLrokUjj~QSj&5+6?R)bchO~ znXRv_uvHri-6s}2LU{V!R=m}i4D8g`9GXx>U3EpSDL#&ah&0=C%Eo65OTft5ydI`6 zcYGYfW~k}sAqW12CgvZF{0WJP&LB;}%Sk$zR56n1724cq?#y~|$R5LbgYwR4aHe^o zK{gB28G^tO`U=fXT#eNngWrqJGqMy|5o1>!N5F9)hLzut;H%%%aNg(IezE279I1fd z_qY_KL2QHxI5uwsGtz5t580rOqaRu%Qk0OMtG9m2_?&%5xB z@8cp=oFUxN`y*f45?fTM-gs^?s?n@^xe^n~ZNIzj4R zG5HeJ79|NyF+^TTJRLLyGru!c0v!V7wZc;CzVpz(nv*=Cin(|xK{%O2Yof8mzc1(u zvA}bUOvXGDuw+@E_Ji(ZATdwSr%1L;rf$v0Z_Se zn#QJ2$%#F$ekcz@q24X{0h;!{1x17;bOIdM)F}8stzZGrBMasM06=wydO~PQ_FJwx zo|!)sKWgwj`Q0z}9H0ABu#O;8-Eq`1K~oW5{f|(U<^-5>>GAMU>m%GfMM$os1F21@ z@CftmlqKbrqs#+KmH4{xRTIZT(;`!ck|Jh7eY;df8O$R^0;=iOVdt$fnZyP|F=9>V z?-kfJuh%sc2kVH3#PQP#yJ#Gk1w2d<`8*-)^$w@^LLH$=Af}`57+go?fJE!LA2osG z@`Mr5+1;eX7TKym;6@J)rWLP5qr^2j=*J){xwy6$&HwE(MGcn;uQ|T!)>rV7hhIeB zc>L~Fw6t`*SlHa0^lx2%`Eq(gdhCKOO3Nej&z1*Dat#oJ1}*|ci_iz;O9L!?;xDI~ zTN$k{E}jY%E&&+mGnHA*^EQ&ssb$a?OF3R5Fk+aLM`3$;fQxfE=G+|60NV=?<<4EyFkMdxQu>4s zz3(C3R9!*016fBsX3>M$4;Ad8+4*pT0*8^X@*8L^QK2CJMu7wZGkpTR>Jilz(a7S6 z0*sFEe#)YFpMMKP4d{wc+|rzPLq6zbEaB(j9gJkY>T{be>COvQkc`@6AJc>XiAbZ9 zc;#J2tsf$+6Td|E5biQ%d7I}BJcD!pNonmlvWjY2Sm&MCI*lRxH-8^Kyjc%TXf%(F zwSSe;r`-ExyKxcIrLgk-owkGRQEz`0zZ&bUb?f6^>C-r+pVMB+nPE=pdf9h$p@#Wo ztMASo7qqw;ja?>wb%ylu^-=fr3ApDQu&RG;XZidz=e6nU=DTy02Qi1>=;0do(%~=5 z)~vrM0z*9NRNA<8eO+n2({M;LLF1BRgV(mxx?-QoMUja_1DVVqTTm2bSBli!Rd}%eoU7BKq$tOs*@@##duV3KcZkKk3(QFscU;RImL{&EYRl zCF4?~`O+hb@S>PvA>%w2MmR$EsOlf|F*tbo-a$h~VVG&t`<#xeEt?}B6?n2@Ifg;h z&9un$5`|F(;Hb;S)%>?pnnS?ZBp4_-L=+Ua6AV^g^;j)1ldU@K1`wk>+qB%AhHe+H zqVX%5l4l?2X`|vnXTSmrI5&X`beQu7H)mRl7q< zs^&Wz0le~5JKmH}Q(t9^kBwcMKCNnknDsF4iV$YblQCP$F2mAG#UZ242AmJ=d(75i zJY!z^xsc(xIEj2I_R3mGVTF@m&@*?W+gjsE>8Kejc3a2rW(TMPs4EHkzW;ic$PmH& zSm{WuNm{}@(l-Xak{29!lK0e;>FJ%92|%ojahdJ}xenbXPgZ;*@vTP4Wg1%lMKU+U zevKmG5(bC4ghB^KpWY<;$8j*7ApW)({qLswSK=}_Gk3i@C)%?4&r@al$`Tb;fv&JaRedQze^*$f0Y@tb6 z?Y*fZ-$Q&mg7tp)4)6SZUGHMO6SsJx*B2M)a}J<`X8PGTFN)rEte7nGi^XB)@xp7# zokXdN3?;Ci+&hleuE+gr;w+eYKhBIAM0GZpMmdh3BtBi*G^Ze_G0>>2`fko#?)5e}k@_CgxBkVe678ts%Ya-4s_3VhKG;aY+#wa`Tp zZCO^y9cxwdG|%d12w#{V9%IJ2uzv~u)JHhi`3p%fOr84{^p&-HN`xRevcYrYIbgFG z;0{Jaa%NuvW_#j}Bm+c|S8VYVL6qvTn*s&sLBIsK0DyKcmR+~1gFC+c33zyJ1ZGpp z5VTv2-HYu2$ijG_yN_YsZ6;aZQ~e&oU@2E$bH!FXAx$>h5)4D0nuAUEx(?qK7a?PK z2tEbj;KN|3(h3+95O}%`eURs-nVkH=t{Wmz!ez=^`XExVa^h!JKd79+ELlhq-{>f_ zhgmoH4eaZ%ygPl-4a0aa@bUHbjS{C<8ZmEHD36Dq3n9UjBsGS$mYc=)z$9JgEKW>L zes#p)ltpy@_0P?Z&Ubz*>^k6G`rH+{HI1*PNPlhE;DK@3#+J!ia&vQ*Lq8n*?>%H> zXAH}fSQpXw$#&7gI@ZXQb1(bf2Vb*t>{z|M12o?I4&SlgjC@OB*<=siqA}7 z%QX)IKra5mXA!WPov-UaUNi*QrBz}bH**RJVnaJYoSI04u>z7>7yko8I7nE8GU}Dd zMwpQfn*y0%Ro{MD3^dm1K6JdiHwK6fLz;Mw3?XeVlYJq+x)5xN4k%y5oQ;<4)69#& zkRocPe!f1k5kPwFsdWx3%^@I$c@M z>a2=S{h)tcn8cXqvs3RUd$5{Sv0#Q<@q*exURjw47@k-60QS9;3N@*OMk69?FZ@1u zUrs$2BdHTF@1N}YoNJwK)W7Akj&p2-&dG*V;3`-l;4OS6Hl%Hz1R*Ka>EsRlY~gmy z=HceihLBB@Tnso+mdU7ex_mOXDm0dYxxhI%-lOYDAoXLd&=9Etd{rYpvgHc;h*o^X zo9b|*1Vt3xMS_xqJ9e>=juVM_4EHfdyiYagRrRh8YB)LT8 zV7a4x#^@o!q_7)j-pAT zVLWa?o-OUZ8C}!J%o9dMmFc1r830io`Ky1f!W9}!H#j95ri2{>T;i7XuF-~Kq0!*^ zVVO!hW&PyD_5x+24g8UX`Qx}jIO+TTs>}QMgkXt2gxaY`=N9E60#Mm=uFy19xHZ~R zuc=iw*YY!SQ^TZx`{eakPH$zrL?o3syx608==LACrklI|dzwyJ@wO6uDgWD?tMOj@ zCOFQ!d^e4@jOX_8xF=Y<<5sH+U5h9%^hy>m3hy?5TDC!p8|!n(JB*t&9d2^u7m6Qv zD{wAfEpHx;$ z{sAY()U>v8T;LfjQSRQOZg|ibKAIZOu+aoha?ip}ViTpm!T~jF2H%SO_HV6;rfS>K zTN7?|Qt?bVYgmE&nww`{aIRybq)&0b4{TIBxdIM}QvQzs)M=zeHbk|cqzJSD{jzk? zr>Run{%_}a#XKX!k9kOKnl+6Fvv|RE<58TCk`*U4ji=NTJqo%pcW8>>a4%OKU}|E= zJfm3`o=ybc!_b;&e_fMrg8?CL;b)^bFl~#aO>CJJk7=O|(`W)vQXjyI&HyP3&jEGi z_`P)zhdMe~2*Spf3uZS#Q@LdLDy8tztD zrvv!}aUe@|gqvbEvIU|vHmblqYFIn2T>U&Jn;bwNPnUh27Hm#glWuo@9T}nAyj>*I zbh9|8drwY%Z7LK`DI-vH4!W5;j71|#JdNWpZyZ%)7Q+bA^2rXFQA%^V0yg>T6d4Mx zjUR;_A(WdWcKCJhJN+(!OjL{T!2VRyR-3!NM!RtRy$Vjhx*N|nud#f4tYr~?_LpL$ z6a#x~!`KDdLbK(!A3vDdC_ncEN>n|zipr7&k*BhU_Mwu5C{d~ly%Sdq9pJ{aN!4=d zM~XoYbQD^M6nb9V#mvnG6csoNPc@h6n&BY={l0_$7_pH;t+-YFg&C*SX`O#V9zO9|2zqP7F?l)seru_-va)cw(Rz7o7O^NsjXGmK zlI?ctw3)%H0~huFeqSx<;dpp@@7v-r-)HL$i!*U*_Sg8MhNeef?4Re0Sty9C5~?U^s*_k4OL_+3R@jQqVTAGw`A0TX z4TM!t>@kG$vP&d}-wE9X=DgVt_BW_BT~d>-S#-dKsWNR(YWr?hHum~YD#Wx1v?|R{ z0;xT^C#LgJ(k`V=DVPwx5Cv?mWyeu8QOWC8)`^M>Yto^0GIiEMD^FIywC!htAT+1* zHO7wU61KMbMy z?SSqnz?23{=b z21ho}`)iVUseM@iV!=v9M8lAWB*XW%gY`F6A|v*;X{iqE zBFL+C0{^N8hGOVvoz+@H2Ww1ov7PUg)>=-aF^|Zo<7uo=Yt%_p(L{)-q%kk0*P>5U zzI%KbA|;g!8fH^nh~{kzieqlA3QQWFzi&NG!2q+jZ$f-;CK4M#k_FI5J&OKok%YRi zrqp~+-j zn3+f1Ox`b67Epjj$_z$af+vSWEe{kd818Fq`Zdy$Qc5qB%Oe#E=$6`>`}^w?oBIdO zd^yh`h$UuUrs25R9NuKueDD0cj8%Cou9#$0it1a)-fI$q6ZK{qJAJuy$X zs2G=+9-dNRX=t)G@-EY{ZHTPv>Zq-(Zsd>)gYE*-H1UvwvO{mWwH?tecAPU!(gNS;L#CoM)l=2cev`0ILo`BsUGgFD@J2lmGE_byuUt-nAN4C7_NIRGUCH`5miqLGI zF@`oh9Bd15cJ|p=Y;xMwjS(zln4R{Wa|M-MvvId}KXbDWB9ZWgy)B$-nroO_ImW{e z*v$3f!#tpk?WyxQp%qiSM0OE&&T8(F{vPf6_meev-M~BIw1Ls09F%WdELOzAYy|Bb z_#7-Y`bXqtPaN*vzW7V#<-nz_IlyG+sASdBi|s(190B#d9KdxbF5csPvwfg}tolIc zxe8u)a+@m>`s3yD>|&##BlUqofj)MJ2JPDtCY zMl{pFpAVhY?xVGUm>V__(T#fMkC{tLXHpOPEshUBMxOVB6cO1R4oJ|o00c#gAs$O1 zaJ5O!TX$#9ju@lzMCs_P=q@M}*AgZCIHLJXq4Of+Ffjwe9(m&ielNyAr2J5qJ3DV$ z*|*(=aq*x=Dp{%;iW_nzyF3Wv%2!Bs-w?V!K$kDJ>4~)2X^(L?QY5v6hP+tF((6Uw zHYLaW;y+ei3u5+H$I>;>@PC830;|%yEyUPaaT%!I^R{4dtYWG^`{$jMnHXw22;O#r zCT0w41S9QAP0$9_eqm)PTkGmko$|J(e10Q29P%rw6DxBKl5yH2yOFos4`I9sMh;cd zmhp{49y>nvsu;=UBViFcLBo)4=J|rhQt+o6)Q6@x6fF%cYF5sLJ#eQC9WBhVr1-tU z?7tGI8*F|~5C3|!D9_q;45^l*!fPb8&s#co{%)vxk8WstZ~l%lysE@_y`qgLUnAqX z6nJI3jkPlnXe6E@I{f*)AwQtWJ?psE6zmED5->mhLgKakO5m_cEk!^hRJO{X)uZqu z+N;V@1ExA@RTw&BPb50Q-N+Z1jEde^i>TP}T~-{| zw`$hQBgZr`$7mTB69u3{ZBF>6RZ$3Bm&tZf*~{QZc&9e!H)mREDTWdOrrQez<_lXf z=1EVkxByj6I`MQS27r$|fd{L-)Tz$9z^<5#5FL6;eq~R^Bj7grmX-X-EemE6lL($* zmRA+aFsrJJdWutG%cM+1%?QEq4Cs2gB`Ud17P6*F7O-%jjFgi--S@P)k@Oa-+GUDZl40tmV6r;0C zD?^Dv)#%;u?xz%Y>czZ}Rn^GhaI2G--j;BxU6gVNjRGjH_=qF?Ml%PxRn+ob74rXg>@nU8{+c@`p#3#f}`raW#nL2y*(IrGb!j^1MiM zi7GZ-?h0PgMjVU4=Pyexi)Kl}<&xA&2b9XdebsrK#`$K2sE+y+r-N(?C#0w?M-VR} z#nVm$gj%txa$2rVh?apJ?%B4C=(Z|N_T_2f5quI`!ei%#VHsTP1j)xq)z3C>(*v@_ zLf>g7wy`2KCahdo6VTd}H98&o@_645M=m~zUU2sh+;VA8OhDhefqC5L+k4k07}?Oa zPKDE3Lg|}|gT`?&8R0y{uFA^0>@k>k?r{{ca5+bap004$pFehxonO`5wFhRL%|1K; zM;enQoBX7ihm~{*da#wX7Uq+p$8jV*+f5&n18j1&)!la%M{KtBP7^89j|q8|KljZ= zQy-*vAo!qz6#nq*Fm~Z=hOTR-wUqxD!Kbk=j{$t|R^(HuQz>9*#IZ|K4TL(hV}p+qsARC1)`8{Rgryi?lb?SAJwe<>AfiY(xB~` zQmcE;A7Tpc5z0&aD26sC?C#gqtBXt{raGt0F(z}b8YF&(+AeIe8e_%yN&QcxJd>A* z6Kujl;;&pPXsV7Y0;~gxeQtmAPn|AHuQG}%_D{}M*UizxQ3L=jNGAwPqG$p_e~K^h zV4fT#7!aG^FhMN18^V461TYGxVPvC{WEF%4RTGZfc#0m3*;}P2a-#w=Myx_P%K;xK zB_jo162({t_e=N4Z`6L>l_SU1^Y*&xE03&5x6X{CfBWw0*(EEeQ zpe7vVL)5FNa9j+!sH-VMLFb3rNTgY``pWtsiC+G)uFXrw@+Q5{VgM%s4 zpteMbJoz-Pj$wW;&xSK6X2ei;Jq>NibN89O)YStuWKz*~Yj4SW`DbaD+e{(*jze_U zR<;t)J7Kd+`L&Jsk(@Vt$h}HZxR(m}%~bS?5oOe2#r)d=Q>Elk_F(Z>-Cx?V`fAKZIkYx$nhgd&#|o>e6tr*N0g+BSH%wMSgL zD#gpHbWRqstAN8{iNWf2pLnFsBol@!AHl>C*YvhtlPgJVZZr}4Xdyeap;LhUHtl{4 zeEORR@%`s)dU=Ipz%qw!Ur8TXu$HM#GKm+E+z~2YR=88;388PNcVa-7yN_cpKHcRG zUHaLau_-XH)y_XgyC}O`^a6sYne*Yf){!Gb>@E6RP zGGRuE{8z&#Edac;J*Cwj=&Z%$t<@0{fk#Y{FN1m^Oyyz2q5CWrnq<6)F>9qcb8B(R z?dt@Z5krCK($Fy=+&U&w$!Z@$QmSOuAw#qYn<2wxQLSN>RB|D}9U}GgXpL8PT0w*- zDfF29zA}myiW>yzaPwyM2klE2`u+8tKC zW{OjRS>NWZQ~J|_YJ*PvlRvDEbskkN?vdTB0g`|;YXupldS&Yr!lKnD>z*ax3uhh6 zb4!CH-8rES#$}K)4Dg+}YcRzjD zYB5S#2R>EQbgJ`WS5c%*`#(Lm#E~!leT2 zoNV%-AGFnQSR3>-_)ck^w0=%({E%sU?$Gd(iHtJt1HcSo&|(S#o})}1QB0zp*#(O^ zQvK5{#|fwubS+HWsUrd{PDx7NtTJ=LEFn@fEB(+hrv_6`9_k}qSsjs7+*PaCRwe89ShxU1E$)AHbvq0jPQSQxbDD>V3t#v~We)(v9+o(WpjI zYfZ(v=OoiP@z(Y%V3QH2`oeAJ6FIpMBxM7RjB`)#9qTw}pJs+uhN6dwO&c6T79#^+C-=^9yLLJ#8MX)|Z7)0f zf}WN&c-KBmQ~4pTi6ZZCRRuVXkuq~A+5eBRcZ|`biyC%&+O~Vzn6_=(wr$(C?P=S# zZQHi*cAt5loaCG@d4GJlvXlL5r?OUISEbgqNVB=bqR|2OWdcZsTr5$|hPZLQiMN0u zkNdx`g>4jY8N^|eq>e$>30_BD4+xYh#}(Wx!aVt=6j3}%=HAm~^evd1F~p)_R?(Fs z%X=M1wyw3&T=OhtmxYi-%?YVvw7Q)RU5TlUq`uKHT{oL+5Tok_w+$oLZT-4q1wG9E z&v+szXTFq$5a&2YrKXx9vkNdyxvUGaxxZ!w+BDqq$dS+rG+&1$>m|MAn(n*hx@cx1 zoen6ic7$G%csYb+6C01LHD;Y4C(#^9wOnJi$mAv#A5c6bbWLiX<$abEo3+2>ZB%V8 zk{Q<3rvRdd`3__3CeGM7wEGi|CY=vDFgjY=_?kaJEfd1#+Oxv+_9&9*|vvjyxtK$~53EK{lp8~534P#|E&ht`~?TO0?w8||?p^(25XQc)AwSvRi zBB|M<>2VwK=jUgnQu51}_v$ce?JJa*R&EsLa8xMsGjGduhu!u182JHx#g zXR}oZE^Qb6zP|HzMAC!KImh)xEuhczB{#|lb2dMA|7$qO5q)LqSyKQ;dp0vLP?@)bOhP<0L-d{J}9Rib&Cql)dp)%NME?~ zEx|grPhj{~{ki~i;t+=cqo!ODdl0_SOAns6qg|q%$Mhu2HSHIpDww~5rSsMm%C+>s8wU3_yCHq>OvC~9Q{EPGAgo3gft z-|>5meVy9s`EQRcugpmy%)J_&PEq>^Z*@8(#M_l#oePs&s1mb4S-)ncmfeKaZ=lIA zDOUB+62=n13a5a#PuU(_@LT(mqdu<-CtzaDdA-F@A7h4H2qRA}xhPX<~W9307Dv*=05`VAHMfW0%_gY*nWF z>2%~t3G!rSl&qdcl=RVC4AQQi2LjK=KQo}cvJ_I}cTS~*c-CzL?2iZ;S+6{~ zb_k?JA+~8Mr~zNn?^}nh)#75sArRmD+KcP zrWX_&i-JqTx1+d1VyK4PH8Q-+ls%<)_m}t)c{StKS|BRXi9TsDdiQ$D!Z_*a0nDI= zMlqbwa!F_MpQ7Y=n;j(*h3P#+Gt9^M+-QcP9OkM18N4kcDhuo?Yy_Pl>|60jzVQ13iHu$1XtLP z2{nnCqY)w=&X5xmI*}Mha~3K}pP({+PKa-HXKtrDe7s&yuP?jdzQNz4@;DT0dgFeb zEXSVQ-_PD~jWZxPEdrr?P4|8DM@D!)a9VhKd$%SXJRH$gj-z8pq&UDTD)$I;CF^GX zTG}vElJDlPzEZLbvZdNfF+1G6MrASjUc>|h_K>S+0vLM1*nd%jtpE@Ak?9-#j_E^D zcS6D(!pnN&4b=UM_W{Wh+X%@H-2_5cPV>a*%-5u%2$6PJ6|^P<;RpM$Y8~W^`3dwS zz^f+T(-YDI+>P@YWf^6%{xJ@Z70`?DMxE^!ya}rr{pgjVYX$2K^`Z;%k2Oc}`kCQ;-?Msp1~qGB9=D z+iuGa*>^CmNUlzA?P+&@>RJlS`oLEQMAUz`c#Re9D`_sOHKq9AyKPpZ&(R{-5-|Dpu1IRZAM7isf)-|35l1r_^%pB;Dl)ssuj^UWyChc|)erC>gQ{f%yh=d0G zTS8<(hO!P#f#U$9?;9t8_Ug?l0l~mF$OXkY)-eUTP7U&`e;otG;h?_Xo#lqbzdi3h zl3yDDydB;TbO&dPKchEh6zkPHs!6spuodSZiwiN6O$@Ya1dx<7`chhpif}RnAQl2W z@r0kx`s)Gr9o2AKRf}(WvtQ`Ar zYtQ2@RXmfrpl7ki8EPM^20eBO^Ko;Cyv4O$q{D2vm%mREq%R+ zT@A;%#7An6)s~(UrcQj~@dWc~S%W8*vy<(t!_^922d69D%^^)4SPZkl0` zhOtk(tb18QM1O_)~2~Ss!&Fajwz-1CayG`g_q~ zBBA0#@AwCy2(X;=MDluhQD)MgN8Ckr#kNMoFC{-F2jb;Q_H$ z<6b8DEZ@#3O_lQ7TLTeIV8>dE^!}`gQxSMlcrych>W^^vN_7YI;J{KB$%o_ahdvAOWS-BLTDzjo z$Va!}Fo#d_;3S!wDm^auvDB3<`PLZnueGJMK+ZtyckoXa-vi#L7s;*D=XzQ?UrI@p zA6ECFTmeFyyj52X22hlL$l4*sJ+Gr|tfrfM;ZL1T%gk5SM*~7lMH}#|$L&og00~zh z3R6&kB76ucw8S3`EeP@&6@oBSeCa?LNq8fmKh@GqcybJpfKwhRfnTzo=(v!7ekE}E zl_4ZRuvfog#erGfQf65(U*)0xE2kR}dJ0FlH_GS3)XUN71vtFwX*|t_t7+Km)^Y9p zN!LM~stJJcA-kg4B6!j^{5Xo@$?(pRs)H>=(%NS&w zL{-#{s!C}5;x~PxyTI%mZN`P{wa_{d^+4^UVtqU=&7ffv_@UYs`}fQ${^4=!A@J(0 zf(6B?NjpBl^r|t6#&~h8ibRqQIR%$#;BYtiqlOrjveQO z+F8~wZ<3AV5&FxI8esZp?D0bMxu`$^c}HqnP2(ukvXs;5aQ}`7DEx(kL#L8a^FnO) zgH!b!>kx+BrUy-7aH4&lYY~rqqnN^#Cr`WdamX^(Zb^JqyLF5LxAuy{xTr_B?2GH# znx|fu_fs9vEuB=WsB68lDf%933_ss&fq(jd5~Ec7g5aqa$T^N6sgcK95j6RuzWRal z&P%QGnz+9X?y=R&4~~q-VsQng2k-Fwq0g!u*49G%SNhpB)~lJvr}IiUswrINT!)_T z@Md|;{#Ig~DQO&kCxzqOFyl0)|7M5S)ZMXmMJC}1u#+^u6GrE!Gitn-EFCGSIVdQsWYa)EX3PV}|K>!Lf-&g+-5pS^f#Z$Pd!QjDMc zTu1qZ?cts?B}>!1$-b%p)sw5m)~KXHj~<;t(>(TT%*}wW%HM3?he`c}5dbq*{Z1>t zFuUIw@9hWd3t~64>p1TsyObNnVcvSY@=v^!kw`mGisAE_b*V=cG`0P@AK;pGFrCOf z%qImMRE1h{X;G`MU66ZD7ngbdM1xXGoFfa~8^Cd@p4mD2`or(a1*SWjfKhhj3pe-r zY4P+ya`&?Xp|tf@n<$kH*DWNAx0a?jJ2AAB^@91mr8dxk+V)tL(s=k2@j|(p`}$Lt zLg;xi?mD4H?!fcb>#A(FQ{F!0iinadUT(OP&qs1O6r?z;hC^kkWvA21Ghu>w$~=)= zDCM)+u`3dp@&tP^`RXfAtEhQ-tXO8Q7t(lLXuq?5Z{mX znxLFgP^}PJL0N#=L(KG1Mcm`e1`R?avswgm55a;njBhyRR#QUDeewq(f&j0LQi5>d z2ph%h-X`xFNToDFJJ$qNrxHF^tc@dGs!Bh&-= z7aLOzvIP7bGXzKYyLum9=C`;HCL$m!bbt?tCrjKYGZIS=rjZ$+qo3=kG3C08PgbSi zFy~Gt&8fid0nTB9@tcn;e!Nxm^T&^LFrm|HQLk;!HC9jU#)_9Tw zS`u~SdWIgbn}qcAhVuRiv%8q_>Y2Rdm_W2|XBfUMb9E6t>%;q8#S^(D)cvQvO6m8a z;qJ!BXiJPmp4FGL(b1pq@>LOO8N^n(SaDyv*w@6w=;2Z+vHA~`(Fa#UXWQ)Wrf2q< zQDe7jbEi2*>}rWnCFvbflBEQOY$k< zW4y;Jp!|-;`{i{Ce)G!C#mDwUtKCCpWbgEk8Fz*){2JWrlNQq(H;d^+9J8xn-`Xf9 zSDqt+@#!9j#soJG)=&J1KS3V5yZXq-U@?Xb3=8}q$@|X8`cAs9l;{5G?5UP73B;>g z1N{92oioD;^+pGlfgXf0xpF3Zq6O z38-u@;p_6`)y0;}p~E^-whY$CF5zSu-3@uGL9Ubm(C>ht@n>dMFP`gM`H3%u=)48& zN2(*7DW-VG1g=fZ_94`c=hO~$nW>rVac(ot?QN_-E)lB-+L@b^AqQKaqMV%^1WrpM zWe9;a3R>-xFrkyppL(kTzNWcHSzwB(x@LN|*FrNzuEsB%SvvWil$Lt*(>P?SMXQct zdMP!QL8f`!Q+~{BhODj~qO&W^;?0W=JYC_qS`>#>@OWXJ%aJ_hD~+iG9_749ET-9w zvo{GgFZB2m=8Y@sQyf>lNsBHFXY12_qG7^YA$*6j!wWeoAg4Y2HBMe6r4K7ct=VyE zQob(ywvivEwTTbz#@yeZ(b`mxNk)ZO9A5 z4&K0`g3*XntBHm&Z^L0y0Gg79o)waOuHd}Isv&P$l%`(S%Exy|?_&Fuh4 zJfkH9KhlfvUQ1=}xb2ooS$vTzZ$)hdbR)9i`AVlcS7l=_xC(vUevA3Ne1==?p}!-> zUGo`$MRUd0n9RbB4qdKUB>%*GYPO}u+N|T%T!*h%YoMIJQyn>RxGd*1Yh4UJZ*82- zH_%KOT{*sgX1*WKcgTf$wq}QY+BW3|dpRHGa>pLOYkayl-dw*Qmfg@~QT&ihWoYI` z%s9HV*)rVnIY58Y%Ne<_(iABAR6n*W6nyQE9;)dyc^M6`pnIe2ZJ6UO~ z6Mlg|^}afnlX4Vao( zk#xC(-sQm(>B2^89ktW)t7*<4;vi04{}DH-%X)z*k}KhVKlAL@$C}O1!LG$U)%-E) z-U=$LxMBa^^m4tGQGD1-Knyn(YL=Eq?4nmfi_)lz&PN*t-T0fbqFQ>UjHTeb1g%v4 z5N}ouVlEsmT`dr@jYUbos_Cs?S!SbY1%|6IZ&@kBsT7sCIeWX+XaE=gsbF^6x%$JVc{PZk*XJf+^R2gjj|V5e2eqr^ zN%_b}_pFgcMe=CiOqFaqG4i(Sj=0Q5v@qgJ7XMU4OK+2@;b$Pe{`>MOLwZFog1vr<<6uF9zA{BnpHC@OO4Wwtg1efHa#?wFof81i01w#Do4nv~v7o<1 zrlmtP%R56nZVBWGO*xG@mJ;>ezWGeu!tA=v<*NBkzrAg@{oHaep6GP%zn&tyQ1(>a z-q>81pBAX~@ya-*?bzQUvtKAbsXsb)-T+=j5vQX60y0`~;d8DoJNN7^3V-KB5wVemvo&j~4n-DNEs6`2|iEs@3)T^z+Hpy-Rr6MO6iH*p?@Dk0^<(Ipl_)$< z%9FqPq1;A~)FS7-;?Sf23`FH=(i8qGB=6?Np{)!&IPEN_;fo$ZU{)4!Z#J!Z;ac zciwjnGq{p6a%Aba_t!SO|8=cdIEz{lam9ffAN7@Vd~l=%^kex&!A@P1ks_k4wO3o`dvWm3DYe6ll9yr)~XY}ZwXG*Q*DZm)Ec7Q<&w7a_$`x!tNj ze=@DFP_3nqD|R%EL{dH3-s5(fyJp~e=q3Z<%*WvvC*O#cHL<1Mt+fC6lx)aa21^^0 z6v%`?w1MvC1KeUe2b~h5js==&O2L}HOqEFaLV9ni4e)yin`>@8^r739ulJQl zy7|x=#QJa~U_py!RpWR5l9&A`K8$~~|9f%M8i~hqa?X9sKDi5NgcG!oCjl(V&XXTX z<8XE*@Y(@#093|J16fkO(+m$Lj6~##NG-R~J&!w^jQ{G=8%G!8W|)3JMF4Jq1UA69 zL}XXD%jVO4&kz4ovZeWRVShws>_$IRXcMqjY?&9X7Pe^TW|v%Bqa7kXZ<6!X;C&cG zU1wNd>B{#_^r%ptA6#BoZppNE3{pkFa%+K3t-Owzc)j z4yyodOAmV9gr;jH`m$T*vj8c2&pXz$K!jWoX!twUt=>^BF(37dROZWx6HaPUPxw1U zeV!t|vFV~2t4Ww)o{3M%J8O5?E7c+pE$NRNgm*ju9(F3}p0f);dPG|l`d9JZTCub~ z%EuG^v)tcow9Y{jaG(F20`-=g1A>2gHPhN5y6g7t>dx+2zjvMHH>tw0S#i2~LkLeR zX_E${)8!Xf-}xI)`K&|9>xkE#5B8LLkv84(zZ_Yn%o*X6nnumts zzJ--`DjB&9A4K^<4+0NJ6npAKTOOO08y*4Em_y6OvMncV?Bq(r$mXrAb1+0MT{VNo zh{AT7)xyE5W`Aq$VeOtFj(6L!g}eqHJmh>zz9R-aH@S0(xemArq8E%8#xjLX05sZT z%z8>zmT7=Ho_ z9PQJMAIR2B?+VGKiEhUG^@MphCE7@+l~6O5OfZWMG+UMA7-*0=zj{P@^-sm0f&h!d zh<1|Zh;(Nh^_JT7E6zY|-X_JJnU9a_!nrf#^i*ROtHk<|0j5w4alaK znXOJTtd~Y>XZNL(gUeJqdrU<+45J=~O>#inwk9=+#KtznY9D{#&p=uRzC^i>nNUp^ zk@lGP>D=dUB?{uQ8N@81S8XO`OY6qVMw5H)RkKSusJ8=&k_}c0wqizjT1Ej@>DB9@ zr1KNH2{b>E)mCyX1*{uJKDGeZf@MKXIN7w@fxH;-chZ>lg9Uq&l01teCY<$DW-IBs zNwv*@ni)pcSdBTH#O5B>Ch~vK{@f(Yv$g%Zq>_tX+A>MYN+;w zhB_K0Ycl!HVd_($)Xj0Vlh8aQNz=CSKe|gy9yuEPmH{m9q(!OrmQw8Hq}fZz=*^&) zD2?fv!%bK*B{@;4I#4S~s*M#>4SzRn4vyaKJFyHa*3%<%tW5$J{S(yQ_VI64 zajw=e*w#`%lm zR8T&xTGDE~aI_r1n0Tjqr@JEa@O{>N>EPuxPW2P_^Z;XX*>U*FAr@J4HPmv2y&83x zV@0JFSxk}2(Oa;rZbuc5TK2*Jp1@FSO)V?14NqUMWdx6sKq?~x0zRaoiuGj~tN z^*!2h%c|b^RjluqxD)x?z;9H)wxKtXWeKx$vPA;1PfuNDCeUa2f&_NA{}g}V^6qx< zR^3SN4!cstApIjubvB+`qs8X!4;PxPGo@UdGbM=7B2v&-tdD4{emLJ?+yI{u93%X0 zAi^LHwOo(?u4$t&{C8IDPp-`b%?z&z&Jk#r4l+qz%M5uyuOsgdF1Y8%rKJXd3gs z;WI+9=qFq9kzhe5S-0mvJjLlQkuW*~aK^9)0cqWFjKa>L+aMY82|A5egh+2}GZMKN z#8l)`6{!LlDlCBu&t(7{6_`d9Zl9V0Rb#0+#wK8$eqz6bZn$ocZkX;;%?J5knnT+p zFhu`DWjOVJR1q~$di_ci2LBIHBrL@L5E*+jtHo9OWO4P8S}{n6R6s zP@18t1mmoI|AD$GzgY<+q3VxF01EjR@|WPhNiY%UzX^E(=zkQ2BmYMtk)-7zI)Q}u zhs;|w9bBiNlI-V70~+UF?+kAF9%0wyUNOpvT~d?d+xW_fT{6PssG-8&hZM6YH$~_O z&my7rFzg`R(A`kg0+(~>MdcejXLfV6SuCU1J{wpzGFq!GO(2(=Qbs_N{lxYgQ!FR-gj8&EftU+B&ZL>26cA?YhUwW4aK2N!Ewr^)0 zalU(n3A8WV&6Qj^vVyQEr4*0xr_8$nf_S$UTN$?2-0qoLxn}M$wkRIpX_tD%$HSRsg-$vc-o9nFW4=eNu1zi z>RYU}(o_Irobx=~L5iHn6Kl;D&1=W-ZQ;jZ%h$$%n*kdQFNoLh174U;U6XGm%~$rYp5U5Blw99u>MC)ekGOHZTVTnUPuu+8*cPUC8eRyT)>jFvYZ6_L z{qi8tr6+j)1sfIVGlQIxt0nHS-V?rk1pglpn5gUf6y3(b8!VRh#Pw-55I!;cV66mO zthn7U$Js{1f3vm#L3TNrU@J&zNn-yaOukvB!W9?oqwH zv{#Pr$N<+Uy`wD0OcEKTs}*oL!#?~yYS<_~yQL-6yhFYNGQdO9dx^H5V*!sXc^!os zkX<3=2cWKpw~!3*8ub_Zn$2f}O;e#WU!<91x;n;ccUiPq;M9Nd_{s&((e+rrC5Fg^ey$*m((GvF6P&AZ2t&|V(sJ>Fnn z^L{k2@5L%I#1lk3DmV<}m05J23XkO>YCZ^72%g6pH1e*X#4T&oHaS<=&NlSCa;)3Vjx0cS)(+HVc_E2*Eg+smBkP3j`y!_pw25A` zBiIkcNC;`WA>5a-%eloxHY#DMtSdZ8M6obsx>u17tGvVb{$|tx9|8X;MzWXOo9-Akp(lQ;A&SD}vyq#uvZuzQA`JmTc!!wb>**vRXdZbU0LG^pRl#8fy zkWo$eByvpKfT_xHcsKroH=}}Gg8A!exJ7Nf-}Y*MYD}Gz^JpSB6{mxjjkSx}aa8t9 z#&IqWJ#0&19%Q_Rp9C>M=QVe{Mwc1j(h-_=G9r32mz6_{k@>N$(9qf>3{E<9wH}O_ z<;OwV8c9!g?KkcCAiq6G@+}Jc^O~(Tu$z=X(t4Y)drOWA&7pz%$sve5z?O$Nn>{Se z3|G!r&%6syo5E<-M)<;rc@Y~kwSVW zr>C90y=R}`6el*aTP&SRvW{O_oK$ zlTZ@6fSOeDkbhQq9YrAl@?ft2!s{z36V6@DSA*U!a3C@6aQ*)!x~%_K(Pd=&KcXAo|IY^x8+z*tjk_sS zpQR(D?+oj>rkQ&E>$jE!T$DBHX?$zmK?poqoxt~x+-GV}6CF(m?EA>POS%E%5!Pv2 zozR&BY|#wb>)yjo%BBn}1&w{{3|47sXxRn!Q&_mu2^#z??~A+g`ve}x9AsFnlpE+a z4TaBPaB@HYqW`D>c=!5~?H^E`I;Bey1P>ml$J1AB6hW2uM>|Xmo|$n@V=3Z_4RIFv zUP%_{@t;Mv3jD2YM+d%$&GZRWz;};I9K|8cUfqWRoji*-KKG{3t)YgCgG5~3_cm`tY96dbs~M(9w&f<@;jdkaS6 z)={{=k;bz!1*|cfPMy||K(u%aNxByKBid3q;ihbEa5iS}q4O z3-R|Mv?Y&PQylKc9~Hy8%BqM<}rzHk-(*9AI5rYSZd%Lpq+{*OK8{VR|wp_*_<#uQnp z)Zn->Yea=U^){FiGMqZd%Dp~)!MqONvYVRG9PYp4LnInwbqw*%Zudt$8iZ-4jb&Z8 zoNj)LIT`U@A!V;GIzFRmo*?^x;3C7lQp2}8dWN_hZorw)~IoUhA&mBJ32i*&X^`c(Sq2md-v9* zlVR#MPGikuhlbXs4ZaNDHl?CgR*6KEb>-y28>WT^o+S+1rjp<-xgkRR1{a)}b_4y#ACp~bTcUU0x3igFn zsJB4p%gb57dV%49G+{~I>RaU8EU97%Dnj>BZZ`(o7#ou%q_bM4{l zA)ogV`umiP-G97K;;V}n@P7NW>Pjo>Uj!a+&OzdmSs9L+p(P&W0WluG`XIyohmhSS zF#syS*C`#|i7h=RFkqymXoR0B8TV6<{$>21*x|2XLv^14(bAHJ5}5~vowu3T$-YJH zB@;rA&*j6!r8_?Dw=i9o%Qyaeo$n}rgCbunz>sYzsDhX~Z8TG+yG>qcO{Wbxcr{|M zBp&Q79$$ozZ%c5JQVlebJO_JfV59u+K6MLOJWB$3#0Cf$d@2jt@F7~io*`f;B~E3k zoOFB5=OjaB@{6iVZi->0azy8dq5-0zRT)OOJ`}3PUptkY53ShT5}NpUr64|QXVbKb zC0$lRuTeugExOhQ?2$9SR9>8lAZ1K?;3p)tCyv!hpC)2t@2h%^ z=jBD*^$6MnvVi}uq)f=(D$;}iBp5091!RvXH>?X>PXkMs5jzXBPDe&yFZh0(MLUV* z0E6^?F~*Z#dxo7IS9In)5DRhMxzHPsQ6;NQO#5bb|A)-SoAfus_bm6SzD;5lH(U?8 zRpr)&#k~VmqW+<`b``P9mGU^p|L-r_**2jPFQwji?&5?6%5=Xp2e@bfJ;Y-?XD#8^E zz9y(n(+rSti-NRDVuNS8^vQ|AJHvn=m9>kf`3^WQIBK$scb#(nk@slNA{o;vYGZ#} z)Y|^C$fFzk{5lWXGN2^2+Ge@Mf=7D<-7bVD3BL&E+-jB9Fxe@!eY;)j$XX;>p+}>j zR(`omb1_O;itUhq3uZ!@02*ZpnT`p)#4l=pi8uuLoVbfeq+a)Q08Vp;5(!3xS&!m* z1-nZ(*@j2p<(=wl!Qz0i1G8sO8#rz}G4^O(WQ5pKE#5(F(M(#$f-bT8*>=yaDE1Do zi2@!Pl)5D{nTE{#hZJ)LTFr_m(MrayuE^B2Fm;s5HiX<&deeZfnRHK@4QnEuweg-r zQ4~BLql1%CUPEI&m}?;)!-~MR638YwEhLB__5NPIN;y=Ut)AJcAf!`dA=hpB|7FATWLg!~Yow>;4FYza_FXqzC%)e9iqA#qL_;59%5rQe%^JT z;$tPvNbyiW7#omBAq$2G3l$PQ?`~BvM6@W>r-#I)l7-EGIaD}HUW8$c)*)aKB;wwP zGQ(ly<8cG%8>RXJc_BqkUL5~$L^_cMkDCgHFD`|d9VDh#*wp|F(SX=o4!{f5gsaM} z5GqF+Vp58{M;0Fn>?67K8d0;RV$osN;$Wfvq3OE}yGjjnnvO@GT8kbpIkOuNrR(f$ z=F-HN!7lJ+>e|!WU`Y)8DUaxDd+TfCF2Q{Xtcqnx-x>in>39G+tz5V)Q9U+7sZFPe z9L=s_rmBmrBLRYrT;CGfSQ1V$X2~ECsq3h>)mG-%frGi#dg8=3QcDCC{c55thUNf9 zawdYlR?YD)U|~3F0k5t|X?WQKsX!yj$tF(v%|R_@EV;r*dFeNq7_VP|Vw`W(i(Bbx z?N*%WStq7a1n%91Z-90!qSGN!qJ1&Ei?5T!$zca9VFdBsk!-XHEc=S@)a;qU0bdQ3 zKOFaleR$Cto@w$+yZv(u3KA1qH-Q14E81$}gtewpOU=uP?T!0=xeW{^&cO4H_WBcY z;BsWCYOT4m_*etMqm0KrzHqzU)%f&0E+EPY=-zs-0JpfXby?#1z)~pc@A7)TGbX2u zow}#Y_DL&E=@bS{V$3+3ToMjSTs+_8m+B2>2V~k}x)Zr$B2H>5ya6%1l6gS$)PDX1tTo1piQY3~j9uzk}&#n%qtl z-MZH@&|aC*MX+$8CU}Jb855Zfzet1xIxK2G?a<0-TfK9jt616lP1p0o0}lkgC4lZ* z`O>r++cg#!A##g52^w)JZ%+$54dxU-^M4^j$=`aEu|Vf<2^qaR+jhDI|$lOmt!* z(hE20mvcgxUXNr%X(#Z)Uqv3|VS{rimMSO_^68Ee^2yPKs8#Ch48-4 zx4z=Ktf`2dVhYeF^0&;eHvJnqws+Ls2u%1@E2ieDi|pbnyg;(5v0EkA^mY&v`~uXt zP}n0yp^RRlHa7#XWD~3>g%TsTe=|l-&qct+MOs3uQma(Y z(MEmC7w69{<<7?}@mH~~TySOT+0 zyn_Gmll=PAM#c_N27b$5;Pm;^AwaFG5>~kE%W(qo-EZj!%lh?aBuC*7e`Up&Z+1oo z#sq$|oX_pzxrN3%#Uu)9K`#3UDW9(Mu-VXB_yS|x4L7Ur=GXu;ol8Y=%*4aC#BTQ z=quyQBt8EGgS&N%lho|AGfPFk5lgW#$cVkR2&8e1Iml)R;)p-tzGuqVHxCZH2NIGF z-jjcWAc0ZQ+G&@L{CV=Ybx8c;d-n#tI|HZk_YrvzB#_a`KexzW4=tt%wPHyPsW^AS zo__Z710X(P*zTcTPpsPMlEJX@vRF}^If2zkms8u}=*A6GvDIl@&Z%0>T6x7Pj&JJe z{w&O#kn!L1K+@&SXY{$kgDsI%AU0YP(%k8w5?YhFG6{sz>x9BU7wK6-h=^vg;v$`6Rdn=SSTkpi@ zadMF7%6GB4p{w)f8!`&}*Ttc>yV6Hq!$kA(@iZrW z^FD4-&sGm*$7^UutX`6wc7cTIJhtAy3=ru0_UDw)>TupYH;bB%|19+Wr3pA6pg zX8+O`B3onrW0*+6Dg?Z?HO~9v5Op-Xy=8yRoAE%vo&og)_~|1Q$B3YEUvSKGSuS-+ zD*Ys^R7kG^6q7onHg^eVZYc+z5!*pNzazEWqHSn1Bdiso@@hJTAT?*(NH8efU-DFN zTwFC7YB9{rkum+IO`SQq3uOj0UkK?oC~OOaarrl8Jcu{4+&do@v zqzI2zgVfIj>KmT)C5IQ~#mkVcX+UV6V$A)Q?(o$+>g=1OhO)v(h5FfE)X5_`%5%&k zU27L-5+&NmKfW5ZxM92J4QxGl1S-kuIaa zmIXZU+vuC*Q`CL%S*!WUqpsra`q=Gu16*%o57}>GgC=Ph|3CtdIxq{+TPGK!R78_} zN0QfLS1&3Uh?3^OCuZhLXP2J~_e=k-iI{N~M@_&^I5W3NS~11moS$D?O2v|4iDmsx zs8Fyw2VCQ#E4Hr#T-{vpcJcFWPe0yLhosVVkpo8dGm4}+XT6&xY`^+_v+P3C)8B28jle?zI7Mk-Jfw8RF$GWgI0#EmehFsfQ0R{l~6YYRsr zWP3-&wt`|UqfCSW(Ph@ac}se<_q4q*aNNOTKArp6OtV#=Z?8O8%Q{Wh%Y^^uNbMiM zr>)3idam_p;L>F-oOeH#GiGnIzKvwTM?KD4>$otE3L-p4c_i46GF|TJlQ?KwAGwx! zG^M6Oby|}uTpf3G)P)wui1Enjnp`}-PVuz%+rzj6yXH#|^Y|wyVHjo_?u@WL$O)c@ zy?8Wv^;VK6gh$cje@V3UMfa;p!1my^p8`%Ji4%9rcNZR8{9>?D`$Z@8pg4F+r<%TK z-(fWKj%Lwd-XL1Sm&!_lftj>5Oey=Z(Jue4*$@jYobOZ95zw2+?u1ezSu$XL2iD?)iGrlOoHMZ=dtEV_t+$k(1Z+SEa`#9S=)tkk2 zlsCb!et)T=@EFw>Fn#OuKKgpXoBVZHHN^6Asf33jO@2;En+_B#oxQKVkL~joBKdw~Hh^R|J^N zzo1qAPW`b`XnI(#m)mV~;w$3Ou|Fk`hsR6Ah>r?DGgz$K( z5W3WBf7HhZzvs#oI{FG+#uI{jxkzWkS(INn)aC{;fw%}i6L()7iWsY$yGkN@X4@a8SuRV@mqZbxiT(Fn;k{5_tm*b+rJ zQd9)<`>M8n8e&D=-=Iz8mrj(qc$RtZJIO~@1vh+Yx&>eQkfpuXG~aUGAMr+Jy$z$iM`Z=n^lYI(JZn_=<9v{EEvsje_toS$X9FY z`{uF>grbzrIU!ukRYEcJUxAMLg76wx1f}%%n^TK|EYHtd5T)=_xBVm!|hHe<%Kl0On`u1;-k4i z{4ErZprZf+yws~PJ9F&ZDKabdfb3twaJfu0B^QeohTi7R#`MiNA5M~cG}Np!OO>Cg z&^pp8O!Bb@2ZSsLGAhox6*U4@Da+nD9bnBAA0Bz0$q1EhZy?K?l~)Jd7k@shJfVDQ zw2#u3FV8|BNPEjUTkcq0a5l=V54o0g!f97j3tc9#dsMfhbrsBMD%31Jx;w&Y4x&^p z)TDA4m}MgFDVs+m7#gTpXO^W=<-N1XHan35`OCA{C}K9UU&xz`Fhr{YI1Dq@sp)bu ziAP|~e5Fxfx;#hiBXD927=9B}NJ;}$mvC-hS4zM9khMRxTn^aW6M308O^}EF6j1#? z0Ea+$zl`%JRy-IhNK@4)MsSPZ7;IM%va6txC<{4d=aB3eg#M@uqh~Bwz1Wn5ldtjl z7>QDYZe=n%xfQZ-Qqwg%8bZ$)ZorWNA4&#%Bt=6)2*5E8Q5mjpV3;U!RsY*n9msMe zS`sbQ0ly2R54><)YY|%5Dig4Fq83W&o{UDQ8#X#Jpy@*7G+BQZ4vVCs76BVs7L_6c z8NVri1iF^WC(PUC74xe350E;3eB(i#^7Du7;sQ+d02ky5o{~Q^oE+O&7WOg44b=eA zl?L5fji^iEw%CnA@CZjK^H9n#Lx^Gy@q$=kMR=?TkCmwH9Oyp58CizbpfziFqt>CJ zxOQ4YNp532b*R`4XJccGM<=j|I*vs^76Olq5eYn5^(Pcgr3BaZ65%{VD2XG%DkBC5 zR4_e>k<-VxK#e6H1-q0*W?El$e5h5h4z0p+Yv^msiA)QErLy5yMd$jUinu)KdX(x(%LN z5<}0!Vtrlrlnzg@Fhr>zVIQ4}@@W++r}L0Om!XA}dr&r=i@s0arti~F(PeZ4U8mn7 zEgu!oIkb)LpdTQc;Gou`u|H`H3QHsl34%l9^d4D9i{%XSQeprAP>jz%sKX~7)e1GS z1a#PS&|zs(w)C#?LO1DVJ@y`_!er`XY1E(ZZ{u6sbW3_$W~b7{y6m0K*WF#79hp0P zJN%siJ9PsR0-5fBC*aQv(2QaS&nl+ao8Pa>lIl`*6{|vL=#iiiYz}S=b_C-=n;yIq zL_t@6T$0m3#zd@~?;Ol&|J`GWWoeEkOLJILEC9U)bSn&bFu|3lgq0+F+#slu^W2h| z(SvKc2IX4$b+g?(X&yJ*<+6Vb3|zf(?AQppFw(Q}NYONNz4^Ae&)fj=YVEh?=;-L9 z`wvANgx0tZRUqQ9#R%KTanEr-o<-y}K-(2vtI6PJ`TW^>8P=NkS?chv_)ai8Je``h1s-tB$BeXw^D?{47^K?LoA zoS)ljRm3mqCt5Pt44@`fuv*0w#Y}=9O{-Q1Kc~`Zsg!c5U`-2}(k?oEr#wvOQrf_j&(1BCR4&B`!gVH3gcUX$ox> zx45?iT0?uqeYQ6D5%GlY17EMtJum*l0o z6N#IhowshiVI&q-&;D8WjA4KD=;Djx;is?!>S0@|F}3&X_U{`L&c2v>^f-w`^NtQ5 z8DTQb^j_#)urgut(0D1~EO*Wqm)Vxte=Q$&wCg7vS7k+z1jR4;lv2ke$0VmHxn#G; z;cy zsUG%zmCupk&pqX{)ujXJ)RL{IR@9o$IGd{-&93*sJ&;C;RRg5@2#e_$K>e9vZWz^d zxBDsIF?6oD^Kr|&=W3dlb)I6bz`o7yll+ODLKEr&3Df{|I)9n3@U3qn)(}z zKUx(|9^hu=Ecn*cMRwlwNmKhjWnUoshr&f;>?wCw_KCa?hBAzhUW}05tb$s;HgA=% zR$Y~M&EBiqtCYEpxsfV;iM=kPKD;!qe(0L)*6g;hJwrFW)H8$Q=4#Yxfp}%4Qa=|t zr?bXLqrNe+QNIE3#lk*1;^A)lF+j5cRNp{>o_L53b^M^7f>tw zXkZ#u%wF&oG0Li@o7J1)dVp)eN;A+l7Tm8c=u59F3;M8u(xPG+_6Xt;%pQk$TpU>c z{&r>}g7DyiS0BEeVP0J{oEZrv##q4sCB4Kbe5Cr~j(7S6511lh9hTT{apVivvMqCc6N1|rk zc0!&lbK8&Bw*(-sc;nS$A6;AT$wqtf>6x;H%j?^YaRrZ4sfT}Rt6IE&?)nFadVfDo z&N=vg0ysJd2NLE1WSbQW<^)E?d!%0IrPtUso;M@NT7EaQ(Y0-jL5s}(9 z1{+ulyTNWU#=5{}C>yvI?gn=g;~4g8C;kNnf^M)8N*5b)F#u@dvjcN;dQ!su&$4m+k3rrCn?%8rV4)bE+*1Ye^X?0Q7ueFg-s|Tk<}96MldKG%EQo zzWdR8Y%E4nWCm{hY(&lmqm5s+l*U2f!=lK~$`QdEzVFR(`82$6>TcH6_G~l!>yecvUI-YGly|5f|F=N>otVf%1oNl=Bz!5?bse&a zj|)3fbM;})OfNW5(!6s$=reUXBVp>ZKj9uoof1kmu36Rz`j0W2B-i_9Ka&D0S(@RJ z`jWR{5mdoa&)0UquU zjqQBFYKiG-0kX!N`SZ=@k8$4sox1=lF7cQC<1w96dH-i@7#l})G6EWnC1OAt#Ao{g zQ-f0mmFHe}-EhmL+9Yj$v`(v!{+H=$4Q}GP!h2WJO8Z`|c2~QSB`hqzkcqLi#uy8< zfH4FEHVyGuP{oi2gPIQ5q#YnL6b6WaX~QeDDZ~^rg+P;ZLd*a*gu*Zlz~fkGtA?&;8DKzOT3Ji19|??Z8m*cHrY6M^U`0QHEAd zRjMgt3)xG)Od=I;odt#5Y0Iu zM1-W!`Ou?~GZd;qal(ST*uRj(^AW4an~YdN2@ZO|j0}=LzUXvwJX3{rEj+U$Jhmf@ zsDcrerLf_eGEXI4!KbEhCpmHohbB41S%PMAfmRclYoK}$VETwxMmqiIpMKQp@APl- zJN!mGGq0e3Hv`;zM$*fr^ut*G>YmNQ0AR>y76R_*wl0h1aX(NULOrRG$0QS-ym2`g zGFL`lijwJA3J4|!pl}FMzUB0!aS@b5qs5}lp=kbyt)D5Na@>FGXV&MXGs4bARj_`B zn{{a2WbDo-9}c!Sf~C2ySjp{Jd^&ylTKii^K3dwgsbwX4VdhuS`i`ch3*!>RwNjI#1rTaqp(y-I?BXBRB3Ujo7jnoCX~$QyC<=1B%AnhIXJmIWJhqn zv;751FX*t?E~<;^(z^6akt>}7wg$25h1AL5H6UT-st+3C6W6*I8M_8<=5pDg)gM^0 z`Rumz?mg?*^}4QPM~~+2=N{!obAMl*>LaI}Y3)Aw?xj;FFrPmUYfnNY7{tG=6&+$q zPH7v&jGWQ7>)VVs$v3%M(k=Zj(p`O+8ukqPhShP(H_JCmT_P{hn)MWy;oP(3daYh} zY;kQ7_quw;{l+=@tTrTH(rCd(XwVewMy8lToX2;Ju*nzv8-E2k2?lZ|ds)JQp@aqF zi1;DE=@n?APIy%8cO!fkMTlx1pYV}ZkQafVJE9nYj(Jb(KD}%t28Iok=UDn4AT~P| zi$TmYFXYr#c6n6ItaoA1Vb=ywbk^h^2tR1eY~S&6TbGKI*w`P3a}SU)Pj5 z9)9Oq-|9`(zrP7I?L=-=dKR?cxRZL?J&97 zs%b27G;vGRCgT`QD>htMj2cT|-GT^P!T2i$z6@cch$0a~DlNI(n%p=C8 zH;k5o3j(b087jkMtEX2w>pK&!3_w=I7&(r-R~^jc;@uwQzv1)^I*N@fE9%(LcbXzB&d^Sw&56k zod2bC&UKc#N?+v%10Iip7L$vpW~McKj=w}*3fyKs=I%0o<;LCL@_dn4q*}lbswH?$ zQN6ByqB>L?4dJ961wTacbqg%0+$O9MNI{peYq?|uO%#_2JSJ3Z+Hq=SKE|f!qh4f3 zO9VRY$7)4_X?Mypr1^rAm35r%DC;I7s9Mc~s5;yk-V{C=c80}>$Kpj35?)}#7|wVa zgK7+la|BF_rRY|LlGLrR2nV2G9dota-IH0{)W|Ri7$M`yz#zFm)i@439tt#T`xN^H z0v^Z>c+vxY9L`^$nYs4myht*Jl|$+tX3(_#dBK7#3HYM|{=8s8vhwPpIsxPi)+&L# zaa%0|TObVaVi3p}B7NrY`?&|NWsvfx5hPPt%duV)Ua|cPv=&3g!(R3gAoV${I0f)y{OHY0hG)*qd_h z)LkCub)8f-FR93ySMZ61B=`^^kqYe*S=7l+vLuT)f}xOC)X=1cG<+GB;D1NquPL9x z(D9_F)zjv2cq*i7Z>N{^4kD+;3%)W^=_LBK8ycx$OwgRE8UC$9WQNG^8Bpp3_?w9| z7#`yup+lLZdlFgrCE?Ieiv?Su5BcJ@?d1aDO)giPTie5 zx%++2vbNqm&qeBaKMedykt{ zc5Jha<=Er?PuP>QKRy7PW5X9=El2=}8}JWnz(R}bv3X0(D4Ejrm0ht+HHEvJ-=+B< z_x(DcumXVnb>RQN^A&?o@F`EZY#W;A301UjtS|NPKfQ5x`-=!&|7a(2&+Wc?F!!I& zCw8w{e_-E+b-SC(XQ|tlQg0s&9Eif)Tnt#@7Kw0eN-pE(UDFlWtwW!7L4sz(Wr`4 z!=KD2zGrhRu`HVaCW5nvg)5u?u_GCQoce8fw6+ zYYpY@7q6JpyfL1;53=BklZ(6e9n2mkYtF8!YuewN{Tdbx*nR^F@jWwxk+jRx;gax*@*?qnbXR*&6!#t9-@bQm_a1wXy%!v}z%Iw3&~S)E zB5OP^0%JrG^-u~)lt@feY_;j6Q6?e2aN=l-AZm1MMoH^LBI-cenb@XNld+xJHu)pA zsm|04rV~en<^Yugvfs2fv zOVLZ%jWl(JyF^|i?~=D^>S^X_wv~RB+)3^y4^Vw{AJfP35mKV#WSlCb3zDwj#nHW~GSRRMdf?2>jrHQ1!}$ z#5Us&I7i$4&{3vu!ZMYFkLj39m&8_1b`vrF(Mc`}1~P3Hw+T>vJt%5Z1!kNR%ZK6)4nHo{=f184LZNf0R7f?|{GlsDk+}#B4 z0u~ayv`>PhGSI8lXWA$81tRr?P_BMTtIVzl{PYVOF3$e>FI~FUB z)xn7mVwYlcOb><=RWR?cPEt&iWP({HZJgwpsKp*6<8-;SP&lk=U<_%8QSvZ*6y|P{jT1Gh_17(drMMBmTx#x0KJ{1 zEts)tsxgvXHEq_aDaHt??tW)cL&Kux<;mW$G~WEy)XKSCdkq{cE4MXGbkpBm5 zyiFDCW`0FcxQB28x&bWrFv3}xdIaP$jWMZmqYpuvl_UTiT@;{qvxo_1SDr zhkeq|x?*;_Lv=bWqhkBMqn&rH5(??O@`$IkxXI*u)6+iSQ$UA7CC!*8Os#2E?nm8) z=+bvz7)H2pcX;Wp`A}lto2}2jw&l6!w?S#^Rv7;>#*9(pvsA;_m&EYkuMZ9$J7Rj3 zWf1$b5W5S@!Vc=?QYD@c6Q0U&4W1N}o|-VbE`qXHubfCzX?}^g*qxTs!Nple`J>^l zxl!?sM{r^GkeLM1<~5VxwlNMT?FU1aEyci@sxFtqQcb&@$Qg`eWYXvZ@!$Gh`0@6M z1hi3Ye5<=nZVR+#K?0DAwnR?GiJB@0CGOi)qPqO;=F=N?AmZ!``zsM)+<0R}>-NrP zp4nr(i2I(Z-*yN&5pYc7vV-5Ih*Q5jbY$Sf{&!7D5dq&Nj0<>`FkirhA^azLjA5X|37qB&FwV)9aO*gd3vQMUNqDog zSvnzIkVwgisfe&v0FHN{!w5$KSJf~IXJmN$0}Vae6quJ0;*bpJ?~2DVi=iE>9gyp5 z2g(*SE`5)GY&xujsMXc?BsuLuhs~azy*k;FUh>ovGZq$;YR~Fq+3l&ber4Q*7)zj| zoe*Oo{(Jo_?V@v8O?Jt-y;85IN9!)+7*EQBOTQ6^?dPIjW&aS+qmPn z!X+7I=0srT_{&3P%I^Z-fJSe>Hi4n>c5?j?Z=S|NM9m!S z>^yURc`%ZfnFoT_To1vQ)gqdvq?BIq7s?-$PZT<;2qH-au?bg$m74x$P@Yl+)t z&$Q-Be!?8}EMR{Ol^`9}A+iN^pc{z5VBOcD7DQTCx_xjZLi#+6M9t(45;sHe>F{V@ zsjS0uWgQ+W>t*E$S&vVJU49I9@LY!+k(=eUGATC%b>J^Y5Y+|8gZM=7?eSYp88*KX zH>bDa6a0Q9o=HaLWIE$1+u^UNY4&oEZh7M$>zqxhaumQ0^6=Feu|n_&73SBILIq^# zKkwNpF!N>v_X8ui^L>`>DFd?CV9|j)H35M#DUSg-03Qfqzyn~RmY|@t=DC;3^F7{b zL9SP{2IiHIIUcvy*wYRs;Klre&x^^D+k<2Y z_aHyPF+3yukNs+mjpDk(=ia&VxOZlDXLo0xxUj~scD*rcXV*4s9CjK4n1>CdAmU0+ zkyTWYgtT^ouu>?bs$^)?ByAF8wN)Wf)Kuh0h;4$Q51|y5kX9|Fq5?`=tFqD-71ctn zV^qBExwEE4E$y%V>}b!q_s;A*?ss5r}HK z#La+Z@|?&4?L!vby*SBe0 z8ZCn+4b?Q~o0o>@b7#%ks@nC5-hCUNE1LZI=ShlX#>-p3l&xBDtvz8G>Gw^Tfj<@`4@iFQ{Alj+iXU1 zq%x$!7VF9gj($6rPPG-j!HA}qh9N8ydsZ4&QamLVLxXwVv@o|Pz1YXn1p%t*Leg9c z^=1Lu%t7E4NE#Kyw)|(AJYHY~IMF~rsnm{c%t~ThT;PRG5X=;uQ%W?P^P(;9NL1Ao zOnZ^tXnQuZGZ`(Kti(1kg`J^|NKp@ZL8}=^8X-g>N$VWOR#FC6 zHqm*r2P;)ivTOCuM?Un|K0}xEJX|FB34Us4v0%wO#iN>3N8&B5Ev*r3!A_O8lG^v% z;#$D@fK->!db7VjxjNR+Ko?eQ%CRF_jyAQ(Z@eb7tN@J)UF8cPMi;V>n$lgqP=qWi zoK><~jagKRT8Gl14Jkt!56GSFePAt`&}2+y+!V}O04WwzU7i$C%c_AoR;xDfI#Fvi zL94owuYt96t=gfl<9lI%?NtZ(fY@sd!XY-O9^!|@pmi0lvdijaepOtyZomyTp-%7{ zV#2x&x7oBhqfhhOV%ln$_mM%6^h=1vK2(w46UB+?$(5-g3hNjGTzXBmH4+jfp!u#F zea~cSdTg$9L=zmxjoyO_SZTaVv49e0DXK7aZfJ(Ct14sC!InTzgUAI+0UAKB8lT`K z0BJPZZZJ_iP)J}jO_KJx(wXHY$`E3n@Y|mDqe(&|4Q?1mecNk5dK2GhLHc2 z(y@r&An|(C^z0&Tb7t5s;x1mCAst@nKW0#_vM6kNuL($f$_OAE{Op z(p^45Lg!DB;5$Dd(ehj6Tc<`bGCJs(l)qi0Z_RGQ*sw6)cKG==C4R(= zjbbb77N23e#Q@naUS&u0GvYG4F760hVY<#mjHOw<$g`4I!+4Y>MVsgnPl`9$DRx0j zGp^%qN5To2Ly?wv_u~zPIfcln7mO__C>hFKO1Y|; z=KSSJlgOzT$IE60R2M+iR23Pf!MO?Q7~MUr(tF;r_(d-&mdR9L{x+7vTU|5JGlSc;IhR0jK}~5sVdQZQlv4E z*mxsvV@|#z#(Hg3huahNZKKl!@ zu6#;ne4xCAJ&In9kiuxVP9+h!^@J5H7%@9o(52F(Qe$|I%8XisNUCZYv(13!P>5(O zLK#L8wqcPSNC3yk+X#a}I~S;fbhI(LBdSay-1-bDQ;?$fzVq0ozBz*cB?(PN){m!hNR^x zS)>P?c4?^!BKB-J;b4Jo!va0b95^$F-kO_yM{&qoA=yzb z@=kD`pv%!)Dj9mv38sUMK`(e9s0CAK`?J_L(Xejh;h^=hY_%{fI6gzS;&Mf@!|3q) z^Lz_=erVtecX_^Su6nZl&J8nKfX>`X$FTfK8 z5(LqRqtFfM%dC{{`F0FpyU%wO#kwubqUl&DwvTh&kZ&d}t(vYjS4WB7lCO>~CNK8p znl_gYD^Hi7cxg`+8TmE2@cEoV=%3D)ANZ#J5qe|p4mr*~NB4mO)h8u=NB&3mdmLy= zh2$$w;f5xh4F;eIezI9+&!MUztFb($T{?U*FEw>L|2Kh>rsv&;=F;C zI0K;n6o4-Q5Gw)969Co(fQ{FKxOTpb^4t4MxE~<$XMpHdfY^%w@d1ED3(BR6B)df(Er5;yz&iZK4ZQ#xC;u=1OX;ltJG<2aTvc&~zkheny#XOmF0|Ld%Ug@uKMg@uKMg@uKMg@uKMg@uKM zg@uKMg@uKMg@uKMg@uKMg@uKMg@uKMg@uKM#lH`vV+-FJspoqCouY%-&Yqz0=`TH- zXpM8FtcfDnebh-tE%oMM`#WXhkLXhD`LYoZm>Rc#ZkIeu3YZAfozq64Jg zYNDx+@~|E*^3azppVUNDAi{46VyGhGn1@;Z$Z+S(C4_pn%HxMbq@ z8}ey4TH}V?cy%Zoxgk_N(~Zse*6rPBl^f^Wq^f8<5_TuVL-7a~SB3k;s@)i8s@>_a z*;VoCXrw0hf9UQ~Tt*j^VJt31_Sc->8^b88k~}5cKeg^U8obhX{`Xz;-{bnf4NBGx zySc@(u3ta&3!>^ExdLO3dQeSnHdv|R_)AJ-Y;g52G zxY#PE(E(pbhV;W2R-#j^J-^0T+>5p}vARknA)dmmX0o5!$;I%Uf)GaB6) z0Jq^j$9SE$)Vmu-t%aOr=__(BfFhE=ND&h^&a)Mpau2m zM~jT(KG$LqcH?FI1t(OkSBudMp}BZLx{51VwDvmU3H>D{Kk8D?ghJ?3rar_LS0P%wGsiR3-W&B=Q2 zX|JBKlTP_r7)guX%BWa_=dh2`-@>~%l!_n9A0(6I8tzgfKa&-*SzeHOIm%PQZ#~o? zRm@#us+x9MsP0iKxcgqVH`LqeUG=H@TsyjlzF6O=AJqxHO~0W(GObOP$u<4Vo$Yn@y(E$q$wYE1V>gYFG@q7u7^@lg zb@ah2wCL;9xB-8q7dlCIIiGqDl#w!4O5`e;DiK*IOJup+C#z(&Y~cxb1{I|4*{VoQ zP$3mji`5c!m#Smiu3lCL)IoKOns?BdI$QVCWAtP_MOX0*alJqX053+_0DC^4Q#8O=bT+my>rGn6HtLpfi8hQf$Ib70*8Wu;Kjl5 z!Jh~B2T!KWk}lGVn!EVgqcWI--P8uv*3`-|4s;cRRy=t&{V;)9aS}syl72}~%~Q8_ zD#M)XUvmmgg6re5gLk4AP#aL1cODk4C*>X0V1BO#<4q}-46{~OIj^Yh*vM+MR6V11 z$S~BY0(GT&kQbW6vJQtC?>AwE%#<2zlw)#<+#&;bhuW{&>j|S09q?wG7qH$am3lqh#JO9`f)O99yT9%1H9hMFlHIn`DK3;Gv+X( zWGDNn-c)9KbJmhPX7zYX=5OK_R=s6j!h6tL`-)cHyXWl=CEy`Ebmc<1BSHICajm&YnO&T6-~8F`^GKnw#?k(@~G3 zI3;QHO$Kss5%tZd?pLEymFb-rE}i&`+{cp);BUC`BsG+>kk)&U`Mi_4ah!ExDxSqb zQPP1Yn$G>xC}%9~{9|%IK@TpHtsDunYWKpYJa@X}t2p;7q@`5= z`E-d-FZJn`q`PYBbrqoPBLLTe}#%^8=1f60tWehXK*bzx@66H~7cvVF!ZNli?z>FJGb*tk5)r_6d z)DAjM1<^vl(J9y(3)k=bd+&A=(HYI;+w=eD{Eu_a|NW0!wriUaik4!y*wl=m9&E`d z^iwQjDvDE4GH2^MW76z3k|@ZtL&Y(fJk#NnnWLA6%xt}sJusF0P(!m>SrrbI=H}%^ z3jL-OY|cQ58X0%4JG&zPz8{6{+b8-Sh*1MDw z@)I@CQ70?m&!M$ zGApr1`ja4p>1*=Aldz7MR`5^D3No5jpc(!m5_*}pQ(Z2&9iH zk=uqyaS_s=m&Xg-9S=|=DrRR@I9c~mW9}dYiV7m89A!(wv1HY|`5fVT zqAb%hKlPvKoi#JGt=N=i{TFjf(q3Mzmsiz?eIX-i=eE3NLM>@uk+Rt(b7nBCm&Na(=A_!ueR1C7pR1(vruBuo->Z+~}4|(zJ(p3{4lqESBEs4Y)g)KaU zr%FI*<&>6dKCV%@1fmbh9%0HI3J`S)t11+t-V~Qe=sb>2qNcc<)Om#te}yF0Ud!Av zZ`BVrJe|4vjwjnAZqZX$SBtNspB-TQsR z)z$P2jz&iA~1oUH!r+FM9uTrafgg%YA2si>X0558FbQrdm zTq~)O^_Z&%W9TR!h5n?gpAMkh2YZCu3d#NJ=rgeUQ9h*AS(dw(+|UuqccGt!`46(s zkn=Hro7!gGLU|F!eiHV5khPFCw!d>k`6~Ajv2u(ra2fgOfc^lm5$FasBR|}KG5XC# zy%*)F@M{X>G~fZ1Xdc?E#v9axEX4dlJ8lwjBaT!|@L%|Jf7G&n>3~lh*L7e7cq`4f z$>^PcHoR6I6YIw@PX|`XBUFOC+~c^kYt{!0Fz+42H4JEY=PvP()ek?{YUijA^`*dS zfi{xV6ZDL78*6ZmcDs(yx1c9^3GjEymv2&zE1#Ale_@Qj324EXKNWmvW*@AZkaN{* zl!LLNKr80Hc z4*&&cilUzi>`Cl3B&N6G43z;UgdqLoWQZ|lQ^$P8W@0rT?lX|t9D)>xPccBbD&UCgggr$u1I}>zN5t`%xlGQ$jhuZdF`?1 zb3C1N(oNv-6*{JlBjyBRyddOp!6)u})*9#d+^cA|rXW6U18^VhB>C)o91*!lh#Vaj z97Zm9OxLf)dxNxh(Eb~=$CE+FJfFn*bcb@>I7`G_G1}w_h`g)fzWy8b#~3(POI_MS z);|RQ&sdf+jy*Jn{l&nOP|KohZH$g%FLjChBxN`6A7zZPm?Ma`YQ20;d?4zy~X>*ouE1H0Om&<_CdV= zFt2hA{vM((oF(f#WAts8j~3&4*|H{YyXx(36DFd6QDg!x(#5FSpP|cp(#6 z67L1|HSE3Pv`#rq8R}NNA8yd|auMxQD!{v2xHA;m!*$h93zS<_u6!u&pM6>eEf?)( z;U0gFD%A-3C#YE+q-MoJc@A(Gd_+GjPW4(7-dUf;I5yQZX1a(M9tn7s3HvL+4}sr1wsi13_tU3C{gZV*y{;{#l?>UBGu=PYCfdJDpHjbw zbNFA}mw${^#TCcTd+)w`->y{Df-Xz>RnUS3Ar!HKQe=guYOt=$>Q)P>t>9t|1Y5Mm zl!mGxE(%Hz#if=;GzhqaYOR`zN(xHBXd(Wn7zK+q*iv_)Rrbg9bLP(MKJV_^714iu z$tUN|y!mnN+?jK}Gr~NjWadh-5*{x@qMQs#@1?$yeu;8+u-qHWqHVcky7H+r_>IV0 z$MN~^=)VW{thood3#g`*BL%x?Zm9n%S&Awo*svha!9{R=F0{4&4YVmO<{Mc$v{7v2=KC|`TvkRNNYxwWqmGyUtcGj%} zn(rkg@9xv-9miX~=O>Osa4@*tG@~gatE17fR&%R*XT+s!&-C{||S3Q%UCH zqou3d{kd~_fgGKmr;oMl^Sq~MoQzbW@%TNyy)I4afUe42>D;3&Cv`_&d85+F|F)de zCBB@b-T&?PUaV(IId7iCxjR}orxSu%<_&*dy${KA+N>h`j9oVzAxch9FpNM7EXeVa9!)S<_^i++cIQcz2|1$Glv=La3L*N$a2q{qxU_^ z-6?k`7WWP}O5f~eS;_MPY%#W&_+AY^A!bj>ZZ*x}Cfnvp{;LSyl*z>T>Di3T3ig?G z#PqAOC0sS;$laPdA)@bn^u3+u-q`NZL0Qf?>*;@|=76Y#JlG&p!t) zr>yOd((g)N;(R~;D{*#MIFotESK$zwV~(fpet1Qd$K1G#M8+}7+gE?|f@fcab{cQ#1rJApNUS;iD z{4?5ZZPZ6D*Y{@ZLC#kAcTQ>o>)&YN>e*&>{=B|lu8g%Q=l!?J3d&2n(l(5977T+! zus=DU=H^Tvvm>_hYnS6^wC4Ouxqxv-@I2J6?J7AV7-HvJZgVv`JKK$Mx>?`t8Yg}6 zbFnVXg|v{@CNR|F%OKTf6lkTHn zr`@xQ)K5kC7hIbeC+DXh;f%f^J#-HSyW}3e(XEbOu}|0N+6D)t#`^duJkLHhQqEfK zZ-cYdirF7L%3KQTrT#cp2AA0V*~{(C-oeLmVep9EGbi!>Mb_7)pldgqJv!QPJ@Je) z<*i+-1FZWZx!ArVnkw@s`{SR>`eze3it&q<9!+wZD-rA zlWC6AmGs)w0RDd({PWl2XIuA@qrtHz589b`p)vh0<{rTKY5e+k>{I3h_G$w9T;<3> zAKb4FE@Q1eO<5B9svVw$dbOt}arLE1s8>573H1{?@S{+>LVgsgKP?IMr+oo_6dHG6 z66yzb;@^cysK4+i{3x`}gOX4`s1rXXC!v0F(huU(WAH3@)WI?wU6AXZktLhiSASADa*10l1_Moy+u$`}ldxwLI5jzaP(~eOsQ6=eD>x zTh=&V|A_r_URix-?v}mre0Fa9Xn88uG3I{S{E6~dH}Au--z}$Lf9~d!_#JJ(hubh5 zKSLaE)_1$K4fVaHj_2RSnyKYUx0b8pd7HT>nqDx>{lBm+F32|Si8F|Y#hR;gX%V#= zYi-P}mL7Sz>INGR_sP8)??Su@&XGPL8jdlFRX1o1xA#fnzP(SrhCV?nSO$?tc2Rzp zF&<W!3*lct4d72N3&y}ih3_cx_QpWEc?Ub5u zD)BVF%N`e9LwN?ewTQ9Z-FMf$vpA;d+i;Qf8Go@SVtd zAa;#)Y7enErF_dGMkXlMUAok&xA3fusx;4YuPC~!T-R(yW2^CuXgp8+tBmE6NnK)A z6{_D)OrC)?^ITwGcr97nPP%)WJv;|%yj%;lQMIXdVPe^R(&~0f&0Cj3JFjrlET2}{ z(=oS&ZFT69251!j(g>C6;hVH8p5yTlcPrPrIinegwCp%H z51re_^ij`yTK(WydA_MtdSQ~jSe?BY{7r5A1pSaLb^mBzMYg#)zE5W5M{>1&*3_CEtMc^?wBo~HX6tBn)}u54s)WaS zq-98K{4E)K?O#WC^&TmVCGFFcKmAXqo@t=-%nj|WIJbQEX|i=esQ;9N;RIsskKJHc z9R#bHVhL}OVNP)gZgq~?IF8iSS5X(yfaXcHNe;!77;>EMkX`}6o2{)`-Z}{(%xO)- z&01c2osugfoF#!9*29))F42_J&<5ymZKs}CFKyT6$FrA5?$@X7meE&iw8kPvNN<#d zd{5cS_0-Fy>I3BEyxGix*0pXR3ykEzDOdIGhlf}=ZPfgO^roj6(8W94Yv&00=)*0u zcb*s3Ag+AcXg~M3&)lB92~U({+in-Gj{fr*#~8N-EJZ~zr)KV%d z6^=yns#eyrVa!crln+p(YkY4w2=~jXc5bDS9n{?^NBXzLv>B}ngFDM1_}xK~eUkEL z?vrCcLIvmHE8FSR)WF|u9No!@ftfsh{$U(C=2yxs1*xJIlRgm{^U0QG85yK(@X8S| z>&g;tP3?0cc|7PU^-U3so2Cicyuv^MtjVI^^JZ1Df@W49`Gq2xYOXJz(;bl|)*=a} zw^_HD_S64eSs&RqYX%%oUW;-Qua*~BMaSN%pmnh7U;KG|xg@^Nv37lxXYGik0 z8cS^JtY&@jMA53tu%aq~?H*;?l{EHB-717|JN0 z2)ytjtqY2&3@>|yn28gKcW!i!VG+zJf3H+@KYD!%Dfu4KJ} z9hS0iqb}teC{LqFc~9HvoiXZ70StcWit7}YG!Yh$tni}75o{NJt9CZTGd5>`?O3eI z{%+Ay5$YAy|IH!!EpR9E>AB7xvTjfN%kJ}UZC|YJoku&sZtmt~;|!~ZwMQ3ssT*ZD zP}48fCS|k!VH)*h-)I4$J~e;XT!uL;H*XsZ5!WerYCS6;{85B*L8u}r=ST1U4(zqZ zcBIuJQrPG%M;FA+3Rfl{0tDFYefw%W1q8ptSzEpPYa4F+oAk3(LJkxJ^qNPRu z1DMqtErbhyMZZzKEgzMJ_)09Ei1via6g_b3VZT#63AmC>NltuYyi=btEw`S#h4(h_ zzGJ`f2@im!v(=69V#E%9>T>slOy@sNVeFKcB|T)5TCaYl`-)#|5Bs#LNrw3bElp-q z>P8++CZIp`fjyK)LX|&!j=%3YeSlicktA{0H4HJ|FxIHX9LsHWs*YoLnv$J%d_+EQ zRhfK5u4s(VX*gk6KE)~q(mY|&xxbf%S_&e6#=Pzkj=X`bHEoKhLx zYpjCt(r&m(psk*L$=<;7RrIBYLd}^3)i_L?qC`jF@b<2&qcA%2o3Ih#6@_5}b<~pX6a$JI(&`T-WL{c*L zxTJZDj=Zx`QRo@{s=@^(lu;XZXcxc!ODqP&D=L>B8a2g~2>+n2W>*stwuBv@6jtg}|#Nxzn%sucqc0 z0CP4**RXBeqJ?s8qWyJEcQVg5^_fwvg0RtjuoYCpN~j7-(Z69n`nD_O7_5?~(ggRh#eFJd>(JTbPE20b!2i zljHP|OcK*xtq*XGJcJ z4V~tkJdVp!vNV^HQ7k>fP3;uaP2z{TLTjPDVkWOUW6rmWi9)`DLoKu-QqPYoofZL7 z`N~wyqy?IfJF{%@-J(kFj`54hn0lQqQ?$iI(`W|MH_p{L7eJWfk&U>;#OcKFQ!Dw}%2`dO}3R0 zfJmHYh>K<(LC?&aBSS^cj42F~WT|3o7h@ZN4u?9;E%#}rcKg1akv=_t|SCm>485{$j{ zV$SW;2KSbJnCoanAB}S>R3(_c$S0?kR_zogGMHKxzEqpy7>%pkR2u$jQ@A)G9_!E( zf|pW9wf(S$r-osH7GVosQ#p*G^}ATi&HpAd%z_#@3xz#Jlhc-PNk*DI+c8cs9-5@{ zBlL_)jdEF0IB-6YTVS*pDv#lx$xaF#37$t2c=VsoQQ73uMvu9zIm}lGk^@0mI)jQb z#DE~2-ew+oAIJ^vj4OB%r?RBa2anSi7iqjK=uBNRmiw0;+q4VUaXUGm*(gztNtzjF zF2PT%hz(|LPsdiVx^@kYjtObt#AaO+diQ(04=Q$p$56V?L()=b{LrbIsv zBt~mIV`4t0KJdAE6Wxz*;tE9xI#p#&lWx>= zOhpiifAt3$ITHk}pz}(#=WIq?`4x03qi-jfUq5!=e%wsyPoJm73ARc~{hg{EA|JrJ z#9D!;?Hw79{>5kY!66B7(}w z7}=R8+W^$dyCah=2BlQDrXg`oX?JMm^9q640gB`SYylef;lqP4`$K2}doG?;hiZci z@B_$uKrXCD?8aT$L@NCKY?6N;mdkL@xdnXmIthjg&?e&seIJLIZ4gG%Au#x^4Cn2i z-~pxMvPQbbqk0S)%nA65%?jLc77Q0S!?mxcF(5Y!f3mMrTEQK0Gwm^8U`BxDrj94> zHb77li=O~$hsQEbs$Ti*S(`|4R)-*8I~eQOEI8o3U!E#Fe2WP<149CR=8~R)Yk6r< zyOwGVwf)mKWa#x-(t$e%HC=25gQpea3*`{V0fD!A_$6P}F#QHWW&X0p7B13^^31|D zhAXTCa`J)x!jmvy;HIqRX?Ff%C>=;YuI!RxU;PPx(>=Z1ujW_DH*r6ZV~(y zuqWiCE-8a5)IHE=2pZK?Y*~f3_eh+?mbzoY44_pZ;mc>rPT1)Umk-IwA`>CuCmHSN z!BG)6A;_`zvu2CPjr>Zoa-r%{#XGXV9VL#CLipUiRS%Q1m&Ms#i^GGb>p9%Da>%OO zu{^$vFhOZ(XEi>7F-an$K39)0U1Ry%it$Ww_m!iQA+5;OE7Z6o@fm^VaAFh5ReE;q z{`|o-VF3)as^zg=YCQRT!N#^@)20eXg#Q_e%r|8ax>{4NF#N#__uQfHH%ZjRKsb;Qew`Y>uhr} z$a+b<0UMi;=s*^}QljuNV-}eN?I5O#Gl6p$Z65?@Zf2Nc9^4%gOE&VWCbNN zCIOaUV}1e~^BTihCS|CgAc}JNxXKcAg`vI=A-qw%aC*G_XAM#SI?DLvw@!p=3iOS5 zs7MWHN2LLZ%xFMH$sqvq`wz8~MD}0M`-hA3c70FIv>c$4E4muJ>jt~&3QGsxS)7V( z_>7!x=k$lEtZcZM;>$OENgCLyRfk%q7k+vb;)`>N#x~oj;w(TTe4H!^jpA1Zrn@-p z7gxvh(SN{PBSGohYTOE=*?ZUQvnhM+h}>#h;ZfS>RNlL}tWl5>nxk~eZNyi125@q2 zU{%Iu7tIPi`IAHeHE-9YxPqx;xZ4dcph+!wdo|{S8GE#!xejVfQ#2}StDoX|9~3$j z9hwHVP^1zzmJnzrm-~0oIBDEw_tl12Oi!!SlTr3=36Ckr-?v#veWx-c<0~}no+P=m zW*#Z4jlss3W5y%A+_4E`jEXX))N8OS)-W&ws@9g0otv}!OAO!{hv)86rJSa7xBDw3 zQc*i18V712+7^DZd&{|ZpuG@#xMbV*?_fhT2cqR_hcBtx<$i4gZ8eUr&tRYl`N%?Q zGnyeWE##O`8-mUREoC&KXhyo~YLN5|fBaH7zd}G07aN-+_?gTM8W^Z^Zn#dfaTDAV z*qpZ)8kMJ3d&x3aNPWx<8<)#85O~$J;v;#qU;Uqjh&nwO$==Q=j;qEVVF7ougFczjQ=lEll*^pvaSoN=QQj<qr z_i&)@<4n2<_hULICr>-O9e?xHHm1zZAr(w`_ z5X==2&g>WDdnkR?Bogd@b*C~49OkeLlK4On`K8K~(K0vl z+x^@fPcOrrh>@wL7O7UqKZQ;}6)Fv$Jr13<9~E_)O%^ThE38pdD5&+orEdM>h>JrS zfe+B$MC$zm4X}~ug7W`eHWvE-t7T*QKUXaS|1Ch|=k$l|v-hVL;1?K2sRUN=|MO^u z|Eou{(lc}XA1p0arvKL)GFJU%X`LeM{Pd>clAX)`#Y;?}))ED!ioyG1grJ}&DOm#l zz^vanw$|pWZ&b$+z`qR&8H0ge&4sa(wBekH42hvjnu5b7R4UCRElNT`Baw}IwuB@O zrhv%}3#9(_pYI9?&`*hNiIT}D2rInS%+syfC7Zng2hhIyB3R7_w?+aMO z*J`vRHD?MBXiB@;R>%mbcP=~RW~bl7M{H0kyZi%BrSP`K?#!IhMoSf-?i2)|r_IS| zvG=AB@4<^7;@_Vf^lsqz%99Eu1^B)F`qbYVW~4m?_qQkjU{6FT^KN?-1MHrPUV`kmQK5BVq0Ia3PU4LTyE9!Xde3jK&F5 z5D|!3=a6`;4?i^xt_CBker!E|U_>d=F(AWkF3z{J!3-X-oi7zavi+~x8#ar3W=@%W z(Imk>TVsT@caFeSfwR+pRr5#P0wVd73Lf<4jpq|4KB^f4DuY3kWDM?BbLz7PI0}nY`JQJ$JVC|Wp_x*uRi^CZZ zA0aw4lH{%m&JUCzsgWLuu!KuN1~UU)#3@jgS7p7(UOPxB&S#`Wz1X;@b!PR(>iwXO zSYX`(+A1H1hOs1@Tth|teDD9;Nusz>)iOKdd zo#hZ@&giP~z{wB7&e!I1%P8D3#fSCA3>XcF=!AJ>UAY4G&Eo5Y;R#E*YfG#UsJ(T@ zzvnqdtQ5hImkkWgI+If73gLpA2MReJ*Xp9w7Upgnzi&*QsjgU&riG(p=SGz(VaVvJ zUd^G%NJ7~y3!I{kCzvERF%2T5_J$ULUL90T_EG)xlRG?LO!3+nYLh!nkpWk z&KqM)ntD!|{CUMj?v^!y9Jt4R%Gj0K35LdY#cny0v4Np`Uf4d_Zkbf=Cr@uYV_Vb} z&%MdY)JbWf^ht5DaP3^OwUyRN-MOxs-H~h!&z#=0?mi$m_jly5O4dcHP3LQF?}2RH zEIWQTMaF_aMSY7*9P%ong7-rtjc^tKo>&*KUs@`n zcy7?Q5DmrYr+dGL{Irl1t!t82`Rw7A(BAQN(SK-{*){L=6^|uFjM(k+IZHiy8tV7kBC0OBy53MzzY2x_Q+w;1?J~haN9RwDQI3An zPLJRrtb?EoV4~wUbz4N&K|cjK1bPt)|1BB02=9#@O8|_oh7`r~&G9Eekj79#6x$OY z&ecNXL))v-BCe7wv&MnNWYM*~U()KBl8UC0*Q|J5HfShFF|R^D{Td%Pd|@$zj*X5j z%V+}P^w?vty&bpgp^9zUq~(~(MK`6)rYEJ@^BY|UUwg31fb1zW8(eMZD!+h%g=y$M z0!%pm)|9d5gEN~02&uHyzAo8p+PWA~3*ar-ol)|Bm&VUX>LsCy;4~G_TRP9x%q2Za z)X3PTr@PwmnJIv6bxL=0*NvTs_5G#wpI?i`{^z?(M3D9HxWv&drUAN>1qsa!d?idf zoYqZLKiLEjPIFnb6$^B!Xu5O|D%i*e1?x3qq?HaGWcG;dgRDWR2K5-dqXtMw4s`2$n&}HN zs%$Q-(iZNNR_thDAi*Tvgmo)YLQWGt5&Qg1nGCYVi3rdG?Z0MJ9B44ZW#wM(kZyv^ zH7CYF5l$~jSDxc%cL*yky3RP3>^Tl)HRq0KQaspyBC-^OO4k;o*+4`AW~%i);w0pV zInZ=VWGQ!d$q@`Nn(KX}{W%a}kxTHXfon=%fwX~^w2ZJ;u%y*XVvbT~DJcdQuRgD{ zMa;{hWq5hthj`9xt)I7}RINXrdIv0wW@2xjAP>H`i$kSFg)@AuuCB}9J`t@U`x*Hq z9j$>NM4MVOE2;KU%h4wjb~b6>=KP71o2N9}ngh=@Cr2~}Opc*gHM-_SHnx&$&-slU zo4l$_(@?)PIcLE#*H?9u+hAhBNn4qJ32f)?dya+Bop#+SRXep@I@<*uGBnwTGatH4 zLX1q_A6+nk@*1L4#*y zAI7v>!q_N%H@$DYAP8!*q;6Q~0s%H8 z7)N%|(cvMP&5E6jCx1qVnRguO6{%VMkLua;a;q36AX-n0pmV{ z45NYORI;p8+7b}*rqpaVRX_lrGiBpTjt<0mmQ(LT_QM-Sb`%d#oO&PRzK=*|=NqwP^% zY8#rT2A30mSlnv$cqG9t-*0$zk@xKKhqtZ_dAG>D)FK|cc00O+%qeuOv( zDC{^dkN~PuIiq{^5Ju=6y>#%mzCQr3RP=-;R$j6HMD;75m!_`e_xFAKtlPImvkO2e z*KSps!cSD`sjC*=+_%2>OwvlZo14bUH5p}RC6%eR@5RDX1FP}=@YycmcLa}aDs zJaH)!1ff*Xr6jqyBct;Wi(kqE*1)Q>hFS!+ipc7ZLe2GtDi;5G(egv!^b(wo^tM(h z{rOvTUP8BP_%M-H$kG_bFRSaOrR1u4$yQZF2Y%2pyg$U(vcw(wBKy@99ew~6=LAo% zU;^mXhVnW2FOA>@@5}KjTMDRsY3~!5k@?$idwe;!fo*n8 z!@WNs@i@2riS`(vl&JawmtcVV^bg_fbaSnG<#?P{FdGW z*b6;7oZVkt&DE#ywy*A3BUp(a(PUn^8a%f^hxsgN&OOdglg1mm+@1#O_e8IE4`z4w zId)H9UEUI6U#n`^!UX$?t&^oDgi3p(`sbz*XPQ)o18Hc&lKvhY0I$rdr$dcxa9{Q$&_BX%C&{h`$PS;`w#&bY0XH3p03cav!dLn;**k_3&jT;|kwOwnD8l0w= zE+yj3%);DTJfPoX_12v0fJWM-9~Mkp3e&YE@xd0=DP-?(u=EQNhQ>? zvKT}XXF_=!CLcK?Zu^d0uX;lF+G+{3C)TP=xeS2WVB+EW6a3r;<*Y@=_Ce&B9p_aO z#o~b#9HGT=mq#zq2Ec+C@7QuQZ27!0J+}j)fUA!bxy2n3G#u#tP-5Q7{NuVWl_Epa zJf}n*iO|NyXLSgZDMlM@Lu}GlO^wXa|AgQG|!GO+-_C&D#z3&)FM;_5E{Wt zW%7VW*mAg-dZ*OPWD&)we;c(V6)#sz{8CcsmT2%V14@VlUJL>n?G8bI5(|qE-U!rU zN-~bk#Av@htq@G>p=CfVPx@*bgT~k9Z_&)Ml&7==JtC&uHrc5WYc#vGOUpv&n9mhlLy#?0|h!zdH^3gE6rr0$`@?YQpEgrXv|59zxx2F;BX4Zb6*1ZdJ6BG7=PPN0n zm$0rx&g%N1P@C{9&AecVm&RftX9B|pCl^?nwBS0CDbSf$j8Qge>dyxoQfXBOh#VYM zXU9Z4Qhl8NS?-QdB33=(ql$Ee_g(N%31bIN#AX&r7FHUG7OKHu3+PH~%!AwO-dB5+ zrX1NOly|>YWlb;j=dP5CBt8I9TwA~~BDgIpk^Br6Y?=YGTV`XahB!}yX<|QX9;J#3 zMl!QO_*}k>u)nL%LMsH%tFB+5E4SSa4%X<5GDX6nMwinWO)ZFhNE#>dGx+kJD==6K zZO8Saf*1#t-`+`t!z$ArlqZpc31%PfCOiG_l;mcWG}q{H>AL-HCY))pO+%^37IR8L z(;|{TRoph*(@6kE>oj|sfawl9{8Ww}WE=$!`v66n3;gBgeGdQoE>`_spK2u4UL9vB z*P3w;`bmb|x!72c;h9e(!M|ZZ8u;)KBL;<~A%8?w!-H%4+EX}O0_@nKa9lQ@hx?O| zX>%kSN1C~l57gu4U^EfTLMTH%h+f&I&*0zf^GK?+C4(xXKM^>AOsi;pZ4+miP`x^&@M-4M@!K(W{eysHLWZ#N@01X{0m1GV`a$ex6`GG zm@qQs!abCK5$MjL!N*8_nume>S?rcExSp)q+;B@x4uL z_`U+$zE!(y|MuV6U&5>EHiFu)5XJuKP(c;|n~sos>%qcrY+esgt!BZeyauL+h7`NB zSjkN`Mr|!JX=mfwl~CY`+}C3+_^uVY{$ld{USl2kSktzlkb{+ywiP^80)e*D&LHMr zLm0db@X<<%hrs%myEErK{9f3M+Iu^*GL;pnvO?9gd+1lu`c=ll*`d~Vp-TO!Aa62e z(ecFO2@;Pae0bM79TSzfnMlm1h(s(Ipgwjo&2Nx5rXWfdqBO3liRR1B5jF!cD`|T6 zSx|Ds^a!%=(IKlY##W#Q$u*C=56y{$DIB!lFW%%|B9BpBY#3@AZY`N35lNEYV5~x( zorRLFLSJYvI)7XH8)q!G=mZhZg-Yc{ngywUyf+vB;@?AVIw}GNA}%cX zS5dZnU%eJp9l}*O23Bb244IUvD2u z@)H1Sz0B^g%UhC`mEr0&_z7z+KU!)oPBCACb8Q*V*>AS?y$qF*Y6+}1@WjX*)0xh@H zR||4xDRXNr@OI!3R{`q8EGmym7cY!nl|3NNlx_aydu5kH$UGeE*5sym>iW)fF151H zS=q$1d9qbxHaCwimsel9w(oZ8Y!}-|`0_mo-RQd5(W@$)wg=k?Uxk~SB}~(=hxfB$k!Oh=9P&)~AV;8{=RfN>FD+u_L?E3Ei|?FmebZ+)z@%3@fl{`m5&ggo_EC zg&)q&_ZIoVxN(a#rBhEVv|K&xYiM{{>ArVc8#8kwHNa4=pHUP-ItCePxKw(RR)^e{ zg*@o+qjlCOZY=tP{2VvzXFCF|_Ce?tFXFrl0~lpXQiBT!GYqH1$wOWll zGTLk!X=-Xc_)F@G>kIOtgQshcflwSvb)FWzoIhmhy$(lT=R7YwEav*0cXh{2+6%oTI^V72aW+1EIKs5mQV^;kW#skzCzm+(GjkJJNo({(kUt+(nuUafr{ zd|JGHE=Ygexmf*lc}~MbE}6~&mHMObNcSF+u!BOF;ok%!h28!WSgjy*PK+bk8X`nJ zI2mXof;+rx@UT zIz56~E~Hn-8?fu?j{?L}W8v^E8?P6&Lsvqra-cC`uq|j?w>bbgfoz;LmZ`-_jaP04 zNR$dwOo1(?R4fW}CU-!=(kKx+C%};$#!oqlJFBaAZN8$TUMgay zf=c$y*V`)0QnjUU)IL|G4>JKwP2VdDM@~oBBje&UU!?16B~gfmBE|;~1`O9n>`M#3 zRbx9qY@62wd@>9uQJg{U09hitMA%~zj78&0A6P{1j`oXWC=q*PKPPR&z&^uu%-A9X z);^O8x(^gGLF>4uR7S%23#tMhLyXvC;Syb{iPIS(?$E`b_DaOLFipo;l>}IgEftjmBvsTlr+_D{U*(%bcuIkqePal^y*m#Q>_iE z0V+$91X*371bd^pkS6l%A|($-_M|E06EL&{k%@&p%m&eQWMv6?0}NwudCRr!(O6iw zRY6*>g`-jRSokR~{5M2=g~xYg6^K_DBJ)scsG_4+fdO@g4$4qjH8Wj!YBC{u&|M7v z@cMB4p+Hr9^d@K#WFr9}K_N9|mYQ=wnMD`{gerUm7npyLwh?uIODYP;!O^eB8KHH| zg2l;^=X2oaok?fN>A?)xp#>J@h7Q5=?cKqz*fmi>hsE2h*bQOe#0CaemLR&bS8*-> zRNt3)0_4cm!q!#l)aVpvel~+pT4c&`d7+lvnN`joB3ZXUW>zanqbGtqX^HYf!m@G; z0w{&X!o@;U!a8hBDBFumC_p8)aHIL8m-a>2&)+6*AaSArl z(7g@krn|2qr|8o$)J_CSBz~Z#Yf#2bdnCsi1&>6zi<~0L^CO1auOpI795dX5-i2@Z z7IJ9@WpmKk@BWyR+z4|uk)Rs4sx~<)1;C;n4UcpW001?jmrqI*9wLVC3l5XcGoFAh zqNpWSI&&V2n?qfI&$uni*B1oGG5=>k3J19ez;p*-5WbyA5t|+>1XX{T<75NIxl%K8 zt^LN^^Lr4>)gt9O-MpQ-UG;%%(TF0E_<&)1ZS6{yVx4*Q2lOp;yMSgs5g#rkKuahj z047IyDXx(GkbT-K?JM6J*7pmj(GT(x7u9MEUvh6zE~`~kSUK9A``u*Dh){=$UO`GN;|D|u(v8X!boYR zVEo2Y3WKtUV&|<`SCDS<7A?IJ;LfDM?;M|G+qx;}GAkUAzT{6GA>lfYbxIL43EYN) zH-l6! zzXWFV)%ru-OcyoDR>$=#MyW~4A#%e>=f*1uh*hu>r=k}5km8h@jiU-D5u?le`LS&Z zNwfy!k+WY^IjXm;S{06dms-yW-RSAP+wYM>wZF;UgQdxFI1!T@UZNb<{~ zFsN8pcot7RpoF5>Z%{0*qAuq?shz>mW9_D{E}G0pIX00&sin}8+J(G?=&gN~s&na| z(2TALa%Be-1e1~t<)yTM)1iLr{PB!6?bs~3U4E?s zrfg8VQSn@sMM>1J(v&pjfkO6dl~JgWQom6N8wYk>F^*BX7DN`*=~F_%$WAT|GoNhu zqMno_iDnUn4u&FOz#RH*Joded@kqvi>jE^JUFU)MxS-^}hv`WdekNRRP>RAe%xhCQ z%&Js`a*U>e+>8n#acMZeDyU`uL<}>s$E6h!Ev`&FOS0}Gk;rUsgLKD-8PXqkzos!N z0%pZwiCraBOhc5?KqT%Zf`Jy~c80F9!Dh+cZZy?qpasVLM+tk?U-m4%(~q8~+`6k0 zs$15qtAuN_+~|~znU`q|k=TOEAF)IhV+_rVF~mHuT%@MNPbI>TdED^skosu~uy+@Y zUKH5@R>6b-cn~E;? zHd?3Md;KQrUe_ke(|oc@&Gb!~1e?ma7L&z5fHcjcdq$Vp=rOc&*DjqtR-2BYIr05| zqomYK?v;YxlZt*LFglOH!?>|K47`DiR2f1EIDdrGvi`4%zG_C&6w3-k{QnZSA85vg0uq&4lYN*b z6*xV`Mrb@92_Gub4{4~Rh**GDXddO@C#$LOKtotfa{NEe>ij5-|KP|pV|i9H>OX$I zPMN6Igb!<1@O<62-vLR^_;qd2+ooNFdLWZZ zL%p2^w~q*LBi5vW8bkNdcdR50=Z;7U-bKi+b&ERDOt!kq_OC@IZlO|V;hw{<&g3Bk%b;qeO8(Z7vNXfQ(hTXg??z}Mh7l};R2A&v&WHF3C29`Rwgo}(_FDYVORR-tT>v_L@KNy90uWB+MjkwV zmuEk6lWbhE+Krk*nK>K2_CItPeiAL{c-q7sL%%IhwM{+Qod?6cz79`^xlDOu<^Jnx zdEz+8>*hCZja`am#K~mH`4eg;yyM?%JgaQ8+7q;>f7^0iSkh0cCI?coF7j)#X!YXm zYUR;Xbo&|(43e#M(3`1ZO^qhb`rKP2%Z*COm3$Vb$+jO-iX~GIa|6JN)Rx0@l}M(6 zB9n!)0VNz2>k{chI!fgiY0rfhZMr3PtAdylkb?d!cb8#jqtYZ-T=RpTE7x(_DBcaZ zpvYn8^cGVt*B566pPkWp7?}-69jG1nj}ZwsipWOGPt0@Eh=P`j8x)#I6fKKEiy*?p zk<(cGL5XaPcyaWSv#R$uXb0 z=R!=gpn0f;qNQVDV|~7?c?rZoz{eS)!vvJ{WdNYj^K>@(U{+dq*PNrKFJ1~5U)r;B zfm!-Ht@7h^I`Q*_R`W0O1c+7Oqp~*#KHd!L@R$2iKio%3k0Mi7Xl1J#d|W7l^i~;&uD0ZZaIPGUN9h;<_o$iIut9d zOGkD{2S*iIK#-*WHHff~K2{ffiI@jC5GfF83U`E(i~D>Yw0rjozu7=3NbK3X=Ckqm zjpTv?nPyRJ@3#qp<31cJ9k?a_xWSVPE- zau+<#kBrCBMA{(wIq|brgR@6g!|=0vx!UyUbZg)4?B4FyUN~~J{}m`E99? zu%^s3xu_(>otGV5e8F4e%~j`SYv=CEm+$Tk+LwbeRh(=bY*8dd;=x^-uC7YiQh_6} zYW`tSawC#(iTF)pJx>C7_yrQNlvluCcX+c|np=i36=f7p1X&Pl(sF!AdW!Uz^8xcE z`@KBxaa#a;;fn?jZiTY>p`%E1cl!1_CxSuWvtrr(B=Vq!=4aboCTF2H$i!`Nu& z&=ugvdvN!;^+r@~w6zkEbV(L@anh*L1Q8>PtikqlF1G{hJ!7e$6dP-E>M4sqX#mv@ zs#2`PjVtSpMX*=*ik<@1(Gs_7L|Sk11yo7T+haOhE&%a)yYCWoQlH^%GT>)zWw>mUFA zt~{N5JXk7~Sd4sr5*jI#xQqy;hnaGh^X7PXk92&-eztd1rpGn>lr?IHk;X}hg_fuh zE6+KBoTEQ0$SgN4)-%;d)kmP0M^4Al zgo%>DBT=2U$1LA&8=`oZrtP)-PIbyuKhD8(npM`2otl_5H-@d(TXiUZv$R9Av^W}U zhV8jz?NtXMKn<|61i>69EG%lR@VO!6hE4mmGQC^pS=(A@J1lp*$8tA4-lxxgvYm^c z>(uQ)q9f)~wyQyPPjBTiY&Q(+|0$^cz&U-iMVs&B^0;l&=d6?>MdLk%V%h3X*%8=<&&8gp~X zY5Hwrbwr-gNVm*&=LhBw$n>_<)VS=VO*mAiyFttK^dwU!6b4=W=$}2(r}q1~c!%{S zHn5`wTIQ6{?1iyQ$B$eaG2YG!H4*1Z+(cliK$J2y?oy| z?cHYjhUz=A6-V|4u8#oX$sUz$h6HSj)N4YTMQrELMN6ggsL;;E^ zMwBpB_5~!WkS|bLR)aq$`ZD%M9w!luGENo`S59iQ7Zoo{DONdh-3kxKnt#)Y&}U^F zw+@c7$7LE2D0)CoWWBmRvk5qJz|7<$)CB%HCFw2ZN;S6@pMX!<77`LVvNN0UP9$#5 z%{p{}xS`eyb7L(M3u1<00oIYhGj*hXr!$G3pdQFgbfoLYlgrJj8;3}~T<$wUt4YjV zE@rQmHHO4Yi!Z$E_;Y9qJkmyp%4kU74xvg;0GaQ!W?1n0$mH4iUG*95E88Qz9E5CU zQT@+q+L<;JPY3r3AE!y@N}uP5<5=aH^$X{X2&V+E>?a@3YP_w6szI7qQe}jh-5}$n za!FN%66t`dqnf+}Hi7^%^p;9_Igc?xHug}x4|%|-e98QiT8T!vuCBwX2(fqoHMf*O|7 zyN%wQb~-&XmiZZPOM3tj*GT?hx(gOPuqQ^ZF7VF=Vy_ zgw_FQM59WOvyc=b5SK8>i({Vk2qzs$a! z-pp1YI%LE?i-il@%9{a{cg|9}T=6|Q3Q_|$OhKeZu_GC0B3RJB*;xWMBKn3HoCX4? z3vQoqjlzPmQm1#&GDS(9X3C|Et10meJRc$nV*YH-Cc1$2-XhvD{=|_$T7+!_k@jJ% zi@hkTtG;ZB%ACeLi2C~p0vROj?yC8)7y|!HuAh-e^LCsb!}O-puUz#zFIq*aMm5_+ zw`wv3GR<6=7xwsV3MBMu;6Lv$tp%;p!f( znRs80a3EJ+b`SORLn2jC@uH0>+}+m>vvksS*wy}9LH{=ht^lhjq+i;J`WMj{ zdmFR=S+d4H{o)kA6#sOm5!}9-QUO1jOMR>M#`hW(p2c1)>*S;er3+;}?>L~G91@>( zf;YMuXNoGf3`cSgd~74Dfswut%sINLnXB$zjHOK*E}W+hXy{KxwlN-xT#wZ3IwX1M z&djkMFNuhApJ|O~8i_a1Li~8J1nQFay*Fa>QK9=f{j$rQq2r{t>K3-KO1I4sx74%H z@?8I%6c!h=DpBiaa@D1_gT6}!W4qgP(0mj9#@>#B;#JB**IxU2D|Y`iL63wlF($4JD-d@p9VUg@^?mWRt&)7 z(_0R)xd(?-&<9ueKg10NV+yLEYrBARG6&l;(0^js;DYIJsG;wak-2z$?f9!bhLcIb zNQmh>S&uac9)0;4@$a(`u<|xT@)7loXxmNU zwHLBtTQcY@s_2xMR*Ot7u$PQVN#wLAO-hmzB$(82ZOIk8ufpYU^j`NtD&b|cpMO{L z5jKCowz|?(-eBxf`aG0R=Wc(@{QeWFo9_>)D1vE37a;FAQ=i|lNdO>%j2U7lYQ0gD z@P=1vgFn=H2s}CpPNr4KHVB zpQff=Z!~gD)uQbj*AK4VUcZqBdmH0$fJouAyL!*&14X0- z1vQ~TA_^Nw7t(|W1cgvkEDKA6f=JaW6{rX++wunp?aYuUwt^xSBINmJLXa=_K2c{6`r&IxO5ZQb4sz4p>UU9i|iMFrmQd69? zWk8c~iWQ~4RX|&5n`X8s>RM`1I4@+Gg%m3&EGnbF__64}&hfWBPpB_;U9X${I+xJHOqvu(CJsV8LmWqF6*v~b)e2PY62Su=rYX=K&R_EBdEc3Pe{AXFtgklr z>F_pKPI=$D*zvF~n(_W#{2loe^Y^tmIxTd53jAd1l=$V4<0IM=U9WOJ-^meH_ z5&vTK3&20_Frsq8wqVSvN&2o&h;Q6{ISHk&HYY~8p_z!eOrph&4hvg4bjXrZ%=+PA zr~t06Nm_;pC{|aTVTVJN*1Wi5J{A9YAAC-ybH%}>^Yot@MaH-Bx?h*TMl4%7behJ; z^n4eY3+7DQdwKpoKg7=Wg~7FB4?STL6%|!?S|YR5IB{j`Mov3x9sshU3QEe9gR5iM-kl}-W-km@^ar98I!px zSbW$C6U@SqfMu}iOh3{y5rhOL3paKm zfItmmMhKy(pXeNJofRTdN#pn<(H+s09{z=&Tk*boy5}gt7`RQlJ`R4)*uFRB<8ZJ}$bDEcV(_#CA(ujZ%P7iO zNlKVyV!Yx#!ngXFsW5M{#9ak(k3|j{UXd0CnQ1uJHf!?3Y*-Ro*Zh#&?^)*B;{|1U z21cAFuc@P|BXyQhgD7qy08+9KfHwIe;Z8u8Ts4<*o1_7u86QNWq3%bCF6oiYK zR$&zle*my-`69RbjmY5{M4Qc-#X?n&XO-kI@^J|ja|_oVfkiAM?a4wV+tLup-qqp8 z(x0BKR{KgSUYGaSFin1`??%V5ce3Y_?gm@$t~GAT`pe=W=`Fh3_7~7RM4c|f=WR?z zean%r+-FzqT4>-kRmk|C5 z{ryi*Z1@?h_NX~_Yc!uN=$w($?{$rS4c@wf$1E5x{#YC1MVdOQcm4#oqakJa+V?=o z(rfpK3u99R3_l8KVFQnrMx_p*R@Pj)6+-`eDps-go-8I!nP-8E$iMzpACs=8U2eIY z-fGh1L-u{8(>lH>HJjn@uEce>*nG_u)9{>LnNAzFbaH*W4sh?5cEd!x!bDl@he11P zoxGXNVX}gclNyhkl$q5mvK5Qk7fS`hpa^nHBXWITp@-8RxE(PxY zDl-n(J94=3v5GkQGmW}eU@=hx*{|1clb+v*-xB}jx%XqGd&NTpMkHdRJ`e4qVWC3= zd{($bU(J;LYNGD^XXr#v@%esYdnI&emZ zpxFkf6^I8%08S8A0D-WQrEZHq(raldj21{JIZ~;39uyIk2-=NX_J2553)a1_FXqtc zZ!%Xu&2GC-v8&jUf``oY@|D`!9e?qZ9`B^1;6leASVhGL-Q^LP%qN;Scc=&?>kYF* zYKja-hOGwgo8+YSE|l$_7m5LQ;99ZXd{a@2E3}9K`?!~}5;vz~0Duc++{5(l*HdTT zc*w(~nJ6T|%eY4@EWtd_1#Ww%ds1lT3LtQG9zar14wYc5l1>V_EGhM*(je!etnaWE z$(kdz=gqn^ZBSbyvP{l@?eHL4f_?-Dc5=UOay~Quy;;1kInFD>g|~wT^X%hO zcS!GuIcjnV`9pK#*>~PfsJle$2V9zw`NBmCGF1kkmL$3R$q7f?Bd|zSQbUlOZ!ZXb z@ZT;4gpKwKrX&dK3S8*TG!W+JH6W$kB}5)Orh4N#b~XYzJmh^gJ5@BuVT?p4|x3 zKRweOUJ#E+ud;|;aNeYjB;wDhr-&k}&(V|(qe9QYlzWT42Up-!;4%fcV6_Y(rk}JN z!f>!K!Pdm%a8PwPjJ9(WVh2X|1QAk6wU(b!>*X^H34(U2QEm7okhk^+#w{R_Yja?S z(JjH2ZsE`)Es(Jo?=iWsdF5_w+?8(JjSSPQ@No?+AEImn?Z7Z@2hyq2?n=M0eKLM} zYS;G|e3v;p2STFQL$a}Q7dD#09=t6|S^e32luxI%M=<3@Ni;4*5=RnDX-P1vlEWYh zsvcg+Xho5)N0n;HV!$?NX;kZ(+os?l_>>CY{L`WZzivBgtd`!Si>VNv%ln{5TAi0@ zUPF26`)*bt)l^+DS;10WBUQd?8zgorebIDbc%c1(cthc@@)^hnsr(S*sn<>NOX(uo zZPat9lm3erWzB@!fLC%rz#6;^rBq(f%4noj1l(Fxff}W1xM-YH2?18FjY&EV!A^ucqbG>u7QZfv*Cu|&_?aMULsUe!csx!&om+VWJ-E3!?E1Cj)iuMDUrWKTh4McdLz`;oC$>T^?Dtv@0P&%J~H!|?b&^O>{ zCKLA>duG*nt081+leR=IPL(cfEG9AZfP&ZelMKsgI?fisS&DaeO!^LUiGl3h(e6G} zU0@BeC_W`9+lb^!)hgAote#oNteix*svWC{vZ20m^(5{Vl_bZIM8Av|kK%dPb+w&Y zj}m@zo_36{?F=1NyjZ=}@E-O`?>g?WqYe5yJKuZT*^c~;K#PxD6}!Zgu9vcd=l2(I zf%=5N4K_VD+y*~GmD-jl86>1LqrpY(5hC^&CPW-taFs2?72v@+wLYvHd4FTsW3oKZ zdAniRJG7>ayS>wQ&~x@M&)Q-zbv(Yy#3)o9uzAnZD|f#b9P*Mob+vJ{-&?Yn5 z#h~Jq+Z|N)KoKwx`rBgh_TeMx(R*8IUAl1BA`nCY3srfdJXgdQi$zoDluZHP2U+#l z=}KkQ9GQh8D$51!bpvJ5LA|}>b#(H>v$8HTiJdL`1fMKA;58{AnYIrhrE`!93mp)ePjjsa{V)7H*ce`$OQ2aJmJ>1W(4V zk^o9Ghh~C!j1JWp^DqU9IX09Z?s#W_x_qz_q6BXfEZFTXfTbjX_R>FFP=e}=nPRya ze>_nj3cFepj@Zp}HrQzB!w20Jv`w%J-tbIO2E6XXJ1Oat)+!5T`;llfzX#B|5%>yY zGuFrg;~Ud3ucs^+|9;wPKo`mR;RfHScmeP9&R$;M%yu>a{jrM{vl2|s*oJN0G+<$Q zndNA&s;is4)?_<>DN(+-!OIQav+81I&b5>;Tc*sq`;mxPN6pzy+ckBGwauD=iHlR= zS<&Nct*vh4OSZwkxbUdhv42A9?)k09w#3iSUd-RLBMt9+_StPRIc2nyrozO{vF~dB z*%bWdU{%1Dd%viWe4i(CD`(0)F`&!(JM!!cu~~@RDulgCdZTp>=RNxT*vcCkUfypq6(l1PxM_aDj=%J!><7ei>FYCVmVMspr$}X1a&j`S$i7mR3!Pa6-*boQewKn8IZKP~}A^Y&^^bz%w#$ z$_%?YIbF76qmf>MfAblDWq?`(ysjUA-}S0Mvu+U4BG8=x)~6o$!VsE8i8WJ@*qQ?C z*rX4>)ga7=>*=vlqg9AHrXJH^jsN$*HMO*00ou@Gw)l zGNrT;_G1Yz+G54l0RawK^nk-B#;sJimx7xB*vXLSeF=!XA$82|Ped%?Fp7{RL=4dc z&l~R-qFiBEU4v(o?u0tesN+jPx0!xrS(;=yh^AZQ`TnZx^D~A;0!G-+F+lJ93Ta=k*BrLpGZs zWsl5QQ`9R!x74)<(64q3aTZk`8a1lwl$Nxq27{}a^?c(s(_S4=(-e5>@egwYa!)sq z%>$SP&h`i>GGlonR9z0(bOhR==QnDbLEm+uuAIT>H_jjEx&v4-bd08YnG>Vn2$mNF z?-*M{ZVm1Q$`{g4c=^NN_U!n5QJ&$`MAcXy8CyjVdSR~zdqgBnr20F|i1WCaWeQ4`+~3%U_+YSZoNJG@OuZt@cY zMmZuAvjZKSfM|$`atH34$SpsBctk1uzp9O#p|BBKKJ3^7qYd7XH|DH1fLp_CO=vHG zpJCdbOt&M-o^bec<_}mu5c<l&egaGM8ePhL@j`hLf}G`v_lXcAxv6y+NPvgzNob z(J*dFxg|b%pex-eie-&tIx}fT(AYIJjWK4$j!Z5QHiI9wFF>DJu_vV(LCS`7*sK3Y zY55+RSw#0>I*4QAZOP3KMA5kE4b^DeI3fnc7ISTHyn{3H{bOG^S|fCC)%Av0dWPQb zD3d{lMH-Mn(YFD>K7e$g!qe~uU5U+c4<1atGOmR{kN0~zK<3Gm(P9ts2BbXwd_mMM zaq2_#^;*+`unaht2T0u_afwCWp} zRqfY^#XqaMx+#S%Gl}SUIo!mH)$2-9z&xy$t$W< zlw`SO%0DSq0vozh#1<)?$rSZuilG{E&orx$gP1DfX5U<@jK~W|lm?0z#LpvDTr2SM zBT|Q8-jQsQo%aPhFdr)LSSG!+8X)Y2=iEYIGsTdCHoYZK$@g zF!Y7Ep_dMzi5_K}GOT*&_)4@bVsyxVg*JTARo875MA?takB-%whd_3rhK!Rnn_%wV zk8U|BlD&@wngwgWFn6lP4B}M-BUWS?+3r~0yFjcoI($ObhA$w(V?%<%=d~oB&11*7 zYmI8mW$xpn#n9uZFgX8)4?TwOFhAXN>$uM*bonLZvT9%-DS_{Ljs?h=i+O4NF8ld@ zKDj+zWE#o0K1(!ep$uRO{n3XGQ6=WKiLkL94B=_26SW|4+7ehVSR*1%s4%WLXwS;3 zI47LR_mf{*syshm6$#e@5%uh-(pQdU%P$ji6w^$2d*-7p!BYS0W0|vua;hBR-eD1R zAz$}g2^OZ>hv?C)_8RWntmE7`Q|)POs04*+ z%E6kyH$LxE1`0O!AYK(qX)4%9zjO?Be2jILTdRs$5X&w{45(_@)}vJ&rve6x2bt;po8NjwDPJkw}YSFHS5QU{auvJA?UZ#%gyL#d4M8e~b z)zkc_Wy{AlL+EHFwnFc^>-_l>PU7jnKTX`If)l1u6RW}qdjV(u`6={YvY}!#5~&BL zY}_91K--&*>ga~@?b&6QslPfpJ4aHJU5TPgM7BhvA%(MQ6G;VPe5e`xte^#RbOfv) zAqi%fD=3Lv#o_EV+)y))&b@^uoGhw+U@3r`sr1O=M7qRjG-Ip`n#}T@%CSdn9z)k` zPEOM(4PKOGCdQ84{6zGx3lvMu?{KMDLGWb=t%(W;3PF3vOu*f27lBk47*kV0xxT1X zOz=VG72GEE^^}%9q>{O2QfYfhF7oi!DHF8!{Hc{Bau~{Y=PcBW0p&DccIy=fjw>f*JM zDXI5}D!^gHJcW*N=poPV!mdpU18=Wd<+PTlSL{4U`(=-26Mw7EPDk2t`CN1r>q%WX2kYi}Ax z5l~uX*4O5$I&JkQtFn}}oG7x_1Xs3`%5A6e+8qYFeZSw;oGRiaCM9fBs}wT%CdXl- zh52mBXWq7jDHEL@S6G3D==m%n6G@3PNu%L6Ej8Upni4xKH7CcP$~n#cZYRmyG7@sy zSEO-Y*EOBs|6c5GKsS!&$(@kNqSo;9IYca?x6x7Yb)A0gY$RRT=!vIg8lL`#`KmrZ5&n79h)~*%DSS3_YfWMeA&8UozN{v z`+dG~+&GU<`#fl4zU5Ru62l$Jnfals6#N0%Lnp2dP3yNm{Pj6G4*lgOt?~pH3XJz* zxU7MnfQfyx-ju$zZ0ShPx_s-~JSH`nujgZgF1idRX z$GPjbQN)vBSx>`p%SY%sOW6@=AODffIfis4t8VL0F?8KGq2M1-Gu%hk@I$3AmF3U+ zQ!jGT_{(qx@fvbp$Z7!W{Y~7Myb0!q`s&5)ox2oa@PosU>P-p$TFH0CuVee?)ef~K z&g_aiCbLf9M-+JW4_~FT3!gPC#CQD(*(z)k{j*9e0z8jw9bqg=dx@Sc7K z2cYF(CI+x+fZ%oQ^)<$ysJRMztlxh2ZZew)yHWEc^9t72%(zV31FcSZegC$U(6ef5 ztL}=qqN!dB+gQry%m}PsI%dD$-aKXBs#qlN8_CQnt_+OfHlixW@L4SQ>}#RQAiIHh z>Sc4)zKAN_<+T{uh{%Mv84l~bNW==_#eY7ys0guEi{jUDw^f}pdZO~>36|IFr{}$N z(Hnl#Bxa2;PtS1aRmatzrol?N_gGPIKTFn>6xvlTE{*rne!dIV1ZM1@*X|R7eI9I9G9>a^o_X@3 z@qDmj1BnN&YBEhTTp1LpR(dBWp8YbDnDivSHRZv@T3KmR$BMYmV&mV2d|P%8GvE)x%KtdLez{+~jf>U? zyAy$8dz}nm4dhzdYzEh-%Li}YvP zh>I)B(f3L*H{vldSyd{gdJW5;T9p}KqX9d1cpWL^TY~=z~cZb?Z+4VzK zg~Tn*mfcv}31J87A?pcYiKgY1D{B*Jw-wuXgmq0r$3%gv^TIb&?^)U;@3XMOcIucH zKVcfY#M-$un)|&p+B?CGf}U;JFivMTx!+G|RQ|GN)!Tl!y<$>34byc=bzRUVnN9F} zpS3zCyCb^HbDwm6i}~;P^>z@K?I~QM!>d?7`H*gx98F_C1sVr($%STmU@?CXjkva$ zIaC4Nqk2DnjX#R4v-1+;(C6oJl-Er2;vCy1HLhG>U?i4Sx2~)#0bF13O^TS6du^{_ zuo^B?Fv?6HZX~QZF;3!A@`F{s`tUxa>&a)9x?)q<2dq~8@IGRCp;2ByFiTN1X)6Hx z;(ASmUON(akoD~5-xz-YTEH~QgTzFAc--(t{ED};gT+95H45(3rCx`J7I!cszN}70 zJm}LsxCp*+A%Auf8ln z!;hdYEgWF9OmI_eP6>Sw`r$)w(KeVn$&dIM9@f7PsEgR*rw)C-^tk_Co0|xd5%F6* zhQ~6=9mJXQL_AIq|GVlNZ$saDyorNTpc2lZtwQGGsOP=iqXI^C^LM$fbdKPhAMF#1 z1K?Vnz9mvd#p;6c=D%f~fAKAmQ8QV0P1#)8NczFsk$0iL{}k*?`K*!&*Mr7|%>|~7 zurQk*J!GSccA5ws9X2AqOk>cAa?Qmg1yhQbjin^f72%J{Ee$X?&IJ zU)k0CRIm7>f9@@oFZ85k@dR}#W@gtSCrLXF)LLII3isSjp@`U=PH@~DP8|`G>g|j6n``P^-U7MJ$p!_II6LFAyglGrFsEb%P zf*u`b^-8+-AYZYN>H5)kT+D@ExWqA`PNF1OOthQcdI`+6&wb%cpBDd$i#{{v8_whlI1(7Ey9eunh@g10bBt%-#uMiDKP#2<3Erf_jS)rg)PznqhIbBi<6@+GMUcuzLoERS5 z91J{J!RY<*JIm?b)GB-_b_!Uz0+Y@co*IfL3ZtS$_T{1tL^AZQhJsD*M{D8OL+0TYrhIE##sdmj92F z%+s&1OlUVA)yW!BuDMMm|7ii4!eO?MF+#e&#MN3|I+7SoPt<#{J)X7sCK#h1Y=i+G z(2G|+zaB9))!u5FStdpw1Kwk`CDbTq%$iE=HA+=I`r*zPWA5i3>?eH|l^S5v=s?4p zuc2;MvL&H@_WmyjL)5FLV9La)R4%D(sZc0DJob>YL{vcXVor58xqV=yOjbx)m)nZwRXa( zC~B>uL66684UH#?Ti!F;2bKt?)%S_9%%w%Q2Y^=u1^ngs<1FIH_~|1jp26=xT>_no zGrL;tio^0$e^=ZogskZ+>0ld*H^U`$O*Z8vZecw;&gnB56gPO~ydTELG5wwEPJ_GY z`WlRuoxc$8NW5j(PAZWM1&w?--H=cv^Q!qcKXe!1IaiiVkGOJ!p7a1tJ=mk2QcjQ> zKs$Xrh8dF@%M-BAFMqbnUu(AOZ`C?gxh!x-2Y;BSb#%@xOP*{8uC`~45n z6^2Gm@A~Ci{A*|phj~BR9nBk13fBJP5lc#C@HhNAER|M7ZpgLV#px?CdyuwZ z%T4s3PaHrp+-#R<+`E77?C;tlj=PuYfQ2oku-R_gOKs;}2L#aYpz!OM+ydV5Es4(_0@i++a5#^AX$|&zI5)HEdy5=MLu7$`0cwigTL#WO z*fAHnMOKD1@zv1$2=RgaLiii)&YW%2p4p6HUD>Aq=NQAAY+PvZf%D}e9Od^SsA=PH zImT_%as<0}4|AeW#jTfbq92r_FFEfCk6g5pRpr7rjxnz=YlQmy4GY#0O|jz7)@p63 z%Bk5Ikg;;>Jj|{5c)Sw5V`69ds^D6W^sz=0_gAlPEh*2W5Z~Z_Eap*Y zTrv^JCk&S4s5SnfERki8QKv5y`sDg_Bu;gNuG>;0deqHo{FU;PdAL`ulLMjhGzGzK z`7;1+Dbd}z%06XrQ90C?3Xslso>fnt(s#7po`r0|JZ4Qc!LDnRrWCy^vKOVeMYsrE z$ICXvQrcN1t#IZA_6lnsT+}s`xXnYVzW6sE15UruQ+u1BU4_fIFQ!CUQaQF+I2Unj z>(L|ACA<{f%S+9=#7Q1(H};kG>Wak<_{${8)LrZ48Ei?;nmHc%^G>a}h1s?FqEwZT zo{oQ5IenmBY2q1N{eZ96em-CPcR$D8&g^mPU8@Iwz&wDaXZIhn^t0a?b(hbJE#yug z=9@yDaMLD@cr3of3U`S*k=&}Miq+LxTb;G)N93DjuqSh-DR&HW66QbQzPuZ&b|JaP z<%N%YgSfs}uHJxaYYT$WjoF2YXx7!ugj>3!z2oMwEqe2#uC7SgGJRxc8oqNr)vnKz z0l8K-iFI|{O^)9?lTwz8d(oHAvo@@yR6CY6ZFoNjSj%l>{KNyDw!89?YS)k(Vq=Yd z^h2F>Xxs&&+yQgAhjc@j7P73y_66WuL!u;x-JG?IT>O+b_6qPNN8pKT7%}gXu|Bg7 z8+Sm);Sm@Ogc03k`)%6X?Q_NY35()~xyuyadw?3i4-Ub~os^eOG*<`}Fr!^Y8kfYR zhjm?jaX*~~cIb?^n)i&K-`Q?`mwbL}z8#8>Hx^fs`*L~!y{?&VW3k_gI!pEbLK`x{ z(XPIzSD@uE*qGa?Jlk9J*O?sh1PyZ8&h>cq%A+OkbWC(9x#`8XfV&d;mKI9hmxnXU zr*oIJYZI15=VIQv{XB~seaxe;sAXwOa>vkBl=;5Uf9dufw}$mA%UVv7Q#sf>eAp4l zaZ_$DXbS3|(|i^*LGtf9e3mqUXaVNepoS!e;A+2*@C|QOE_ov2277ZLc3XKd>4JYw zf_260o8ofIBYmqLwMUOX^**VmizA&h*&_~8s-LE8s(?FQOnt)j`f)C<&t1^RU_RX} zsL$Y6p)cqVOrzipS|KOx#BSTkK?O9JV)u#ob_LX?+$;< zd@h+L53ny*oUvyKwT3&#N23QZ!<`ia8&MzdU(nVS!|M8VV%oCIw5coNb%lXz+zZ_s z6Mrc@Fn*m4nEOfUVQET!sQMsJkFZm~TLnIBHNuGu0-jq8bHn<=r6`SX%OF@BL9Wl8 z%vEq>r4#4(RP+(MP_7GeLerCAMGeiff9ZPbM0&(15Sr0DYqpg3zL+X$O>=&gIBLTN z?Z`A}v2(gigwK#*5tA#aUs!NqhV}B!xS5|<2YL5-)LaLzFMmhACKEO+*4OEJ-M2}jV1eY zB{nMU=OwNP5Bw7BYkL6LR7(FM9>^$1tZeDkj^EwX&*&<1tzipJImQnOd=k~RG%B#i z-s1hlD>J&GKhJZ;?I|$Uq#b=KK<*`kaiN~Tsqgb#A2pda6I4z5uJXU@Qs34;m;|fJ z@yhOeK6k0mfn^I|ZtjG+Pv^>fyop!|ln${O>7V`yF1ezJUr zAPyCLP{Jc?@^V z-+eAJw`3p=`dt`@pIlA`8Msic6QFRS$uUjAU5X%ZQ&Vg(-y%f~Xyz-C3>I%uA$&8b zD)nr#8BBGjIaRfrM?N!|Ae53CS5tfapVPBhw#!nRy@j$uYixDqbC;J~U}|~f{mZY< z{ngw3^=9XD=Qah%XUp3GOjmqG4MyBXCJFt1%Gw*q8s4*S1#c&I9R;xg(eX#QLEPlE zZ*2aiPeiXOh3F?*BTR>JtCxe^HR4k=FTTA^Zn!r`Y?H#MHlosLPJoVT)-r;9OVsAz zv?9>oYJ|W|QiuqRQZxb=F@}+-rP))LtxSX>o_$|4uR$Rv)0v5kw%#aB$bz2sFXoFr zwVoSCwlRUNDq(%e>t&OAGL|%T*Uu=rq`V5-AB(~y^GeKKvyTATe+)=Iwf1V9H^5yT@hHLALk#E zIcnSrbk6Y^9{np%qx_Ux$Xg3yr=mW@&#R7px5&kiGS4+lt ze=)tZc;8pS4R9lzP5ltp4@bA0zdlM~t{-n-8}>Ie?Cz@sR;|49^i=xdbj?9rji2A= z+Ouu+P{UkPoZ|cl=4^$EFaHvUYJ7!n2>*#W?62($J7DUNe!Sk^%N-i&oy-Xjk!<2j zbws^$NqfeDSJJp|PpYHj_730`>j93wT-RWpy{Mg1ZG8G7wv(K#drGsHl5HDusDZF^H8b2{jP_ zqa3l3p0$K<3G!nA4H2k+L?-F(6J&tkPhiPXGUnU$uS-vll}cUvu#nKVX{7t=C#P42 zBc=UJdP$3~Y1&oOws~XM{yj#Nrq{HxbeEMt=jvl{A=9ZrIV6l`yxU2L`3=g6Nt7Z_ zu)qj73~rNR8Og1J3kf4f)XEriEZCB>I*A#a9xPJe$TxqZ=}0W_9p|sNdIPTn6)ilt z1ODRW`u9wOdqcOnKXkZ9%to_>+5-$3Ag2Q~3HO_r(_GFSs2HHE7tu}Kd#2Xt_y z@Am(aQ8g3+yDe)fAWNgPDg-N;tZ!78q$)d33|VJ>6COZUkPlEJV!#Ai0ndT>=0U;w z?Gm6bnQEp=g3J3M4FGDGB+&2fE$^_}WvBzdIs=0B85U%-^4WnAS#_rO_Un`&&AwcJ zq$~9g%}ak!{Y5XF=k?Ak{Z^l$tyEnf93{5nX|Eu|o)Kd9~cmmD+ z?l-;oe@o;2_g`^#8zY-N=F1BPKRv9r54FlsOWgO zj~_GC7&W6Abs{nup*(O*&(eVjbyLoC&(J?oD=k`UQ|jSvq1)|p;wFtX)4q8FM*vKp?|D4-fJFVcU=HQysgh#d*M92gZeCf;m^ z>?If))v*mA$F&Ntp-1s&U-_(|uV{0j?_7FY<1#NuQgZQ?=sep8=zCo1e9UMq0T=+8E)E&o0vs@lBS zE39d2zJK!+T|vVTny0y7T33m=pS?|kv9lL#!dsX9rt#X`H~UQBH_|t$ud8|n_3ZS| z9JqDjK;yb_-r>TD*9@H?mVg)P#tj3h&9VA&%1 z9v}NN08f3A_2g_|jOKUb>_OXin5GYV6RzK)a5ptojCHP_oKF62Bl8wZQoU6~yt1-b zJ}fSIo=kJUbHS_&oS%htu3WR!{FF(z8XCVqq|1ZX?!mhlN=p{+a$i5PXu2eu{!ufP z=$TI3NFKWLbg#h|%Iy5_xP$!Z^AAomNGQ!h-ul=C`?dxCX%%GnhuXCluPn5Geiv&c z6$zbF00P!-yGHPuDoDJ87mKz1sjx5UxP@EsE$ZCB$1Ut_&3lu`XTxC4ZaHE5O|u|c z*{N9tqKA%J|avudrrrrd>F~E6Pw@ z!)4Z5dmRe-5iJe>|0zl3%J7+@C!Rg zQlfyyLL*hcDnhO(#Xuu*0Dz*g^@vCXfHnCaDoh+BlgNLd!Z7_eR2XIk_Wz$aqmwja z6~cfL`pP$=>xLE_hh-}m@|R)1h=2J7Fz1L1b{V6n>FyfaIgFB};LdT5Q%61~`(+)g zN8#&+Y~x-im~HZ&M>p4m>rpiOEFo#psYB6Ys-aEsYG#Lvo~P9;qo}IrZ3zB!r1t5q zri}Tv=xv75ZBys$p!(bm#a-Rn-@~LyLC94$3LO7wacj-bBr4c;kBWb7s`E9Ef8^9E zbFm+shM0V$>6)}_SBIkt$=|9aJ3Mdl91;j8Ns0-ps$p}4g8Y!~~ zkT;aeZm$RR@HYOYcBZb<2l%01a0bn(%&spfEpMZ=Sc13pmDEM#hW!}6HFjV+PW-jw| zS@pHoWv60^eXqTn8%p?W%WmFhw0+I`mhov)H-hb24D!hDi3+?VR+9VLqlLV-`&sgc zP{}Q!2i~{pHtm+5y}9Jah4v-4JBoXL^^QzQ*A#=#R{H1{?B4>GKnfvdmy&f-h>N%hOU z2WFhPW}<2$ULm*z=u9DOb5zRdJhF-ac0?8_t25+rLYUMUpwc`N6GBhQQ__;OB>g*< zmKasLpp)&)R9TdY0$^hKMDo!&B|La+aE>t6poB3A<06J+ z42xLdfJ8h()9SRA>HPn6mt=ICJw#1llhrvea8TgDz(Iir2M-SH7yRF5)SnriKWok6 zZKBY(f?sxy&i8yY4n8c7&i33}oS&b6!u${jFJGknKrjFVo3@kx!|byBH?zz1ztBoq z{r!al69y&y<=;KP1pNT8V?fLQVPw|-W@JWo4tBQxM{#22U}R(cU+YK>Qb9!=>*wdj zkC_;VC`bnkAC3shV?PwVh~dnum?X&5MGR38kp8bOR=fm>MNFsW+_Dy4Y2$@(@iFR% z$Dh&x=(P$)vP4~XUZ|O(mZ--Ud}-vMfC4`ng#3(e67{bvYiw^2dZX zh24*Y-|0=2ja4F77k9F4TLr{P>dlQA;g}VITsZ^_PFQkQt?%v89A#Yi3V|zDMne~!SBpfoOZt|Gb51VO+&s! z>{8QBV7(VbXbpEhuSC5^IU=?oUi`sMJ0PeVKubA7iepZp{``fj!f*wWEqi}L#VtmE zk`jqPD=N<*@}q}wRQaOGo@B|SE1#f02J@8DQ;${EXH~FO3tzUC&N(hzIo`eb8No3! z%ZQ#{IbnR%e(Zclf!!a1xQY;^8}q{YY)K&QKqqh4?bpBKwL7G%YQGTJMG?!j1c)to zrHn6IlKRM5UF71D-h-rH&;W@lG|I@JNQ;Cn5^_uCJu*bC{hKNrtCXx-s8u%Nj9rsz z!QHZ>Rr&8{gw_{rmu(WaCp=hLOq-nQk!)qrump4Z`*E_d67dl70hR_U}wtg(QNA*OMAwvJ=hBKYvyi5qD zNQ$P&@u|pULLe}%7nMZt4SfnE>pdO){Y1gJ@qR|4by1N zWb%nCcXS#x2ln{wxeCok6wk()6 zjO8fHscIsMyT&OSkUxfU8BpdF=G)g!tW&#>&5?)d5rO|o?qlx=`>H6lh~9nT{y&tR zQ*$m%u!VPQ+qQOW+qP}nwr$(CZD+@}oxE|*cmBaST~kwiId@altJiw4goaJnLYwmQ zdQ)eRJBwtV$FQ_$$fqr`#2+dGaUfcjHR|EiQ%@0H7gjvY>~#OSJ#k)>q)L=q*~Yo_ zmk?vo%1u%(M(5F_Pq^Nd7OqIDOv1AWqb^x<2`uUeVvHIrh6|0d)qP|0oMKmvGGD7( zA45Oo(YlsDFbI^eVXtK@(n_F+U#RPt^YIR<8XC{-6nE_x&cX#8v zgBoU-qL9>&wO{YiG#x-5zOxUf-z|YWg?5cKeqv9P9kjGYk}1*+vu{dT6T4;WX0E|3 zVCx?u?x=A)5?9)LDcz0e@p`-5r7g5dpUL4Jaktp7vC*@Y$zGkSDbkVL&=EhM9^A3Q zz`#MlTVZ1^jPy6^ljsxNh3UcBs705N21mNCE9Z70ov^5+^!opD#M`((gk0r9{U;Ep zT-v+B?r4^m{i-oXvNr$9Ggs;{U-V}kmjguRJ2Z9-*J7us+`j+DN=@%SM4@_@+3{53 zAk^VhS8xr6hekl|7IFtUE4c*cbPY@7W-4Dhl-+xp!u2NIOrrE08Y!OsO9+SaGy&Zx zPg7JN{s$+LQ0$!!r6YL$xoQ3JFlpEi^DO3JuF1Sp%p7wm^`dc+BkZOOQ_z_J z^jH3P_&b?7YF8I7c{FZcXNLqG1LH!>Q){fd8Y$1+j68qPTXb5*+>tt){y~JX0}te3 z0MMayw*uNd%zTtnf&+K$d&4=JoRgEVU<5LJCUT7cC(AYTOD2Tp<>(d0d${ML?)x7v z3CaKSRy(aWnQS_#hHx@GHuw+9)>}1n-v}WvzKwBAq7G^_0t%1pKvBZ#ObM77ra(z; zGK(yftkk&xMW!S%PQ*MsUXJ9ZQUR6hq(TO|#TAijP__(X9;v7kV2&X2*MfIxr*Fsm zZ0Gyi?S)M{_;439CNe$*n}`4hgmYk8Fyw9sf7W;XssJ%CN)AX*#Z1r0XuHUEVT= zUIL^z;?GJ(g)S3BUpLV0DCL5V|1!4AuV1OrxK?Wo_mxJjo7i1tnb(kCr!KciLXpE} z+>>etWNOtB9%X3_cLDS32uf&fB6)+-!1~H;S`EwK$I3{s#53xJw&=2doB1NKUELYM zcm%&@C&4bQDg-d3q!`D`=#Y^2|N7r9f<9Phw>->0>yF)2+a?o{Rf90E?PWCP9prKj z7WCT?)mq!hlFBgK5M3)qiby#r6%lzrLv-qc@=|?EJP}E5#q3N6(+;s{mfFRP(b4w-opm+a}Fw_es~BL zyQ@+htn-CsfVLq-NFR6dO_7#1ujK-H(q=%fP8ScRRuWbUYW9VvL!f`u`dI_%1vDJz z#bfo9J00_njKg0JFXQ1R;J%?SB%b~2;c8N{BC%Z{cYL~s)SOFwqMN}$o_ERtw>=NY zJp&7bU8n`k&|wWWTo}p*(=)@L3NQ`{ofRqIAJ`z1^yo_d6I-pOdFBIWNyzy1OOKLY z&G?$fJty!-H+D=NJ~lR{Oboc`)=5?YUsm`EtY0uk$NJMhQEL&F*+7D-bk1E_= z--Fqg$oFV?RXzhvAWrxFQSkKX60`4@N$deA&K2EB3Qlt+hB|0(UNeEVvqnlqgFIxW zuttr3roPq2j2%YaNjFnhQ#Z|byRarWZTQ-7x;o7{^NdzKgvQK042%}Jc#u)G3_btg zL-P@W=k!q|SbVQ&K#H8Xc=1j0vQ5hTuNq1$PGi=K`PPIYuY%_vxdEg@mLVNZ7A_@* z_*z`1AQ{nMC+HegOha5@SWp|b{sCp``=I`wBA)I;C$Oijfv&55=(@IY{@FTPZ0}%S zsFG-!CH19wT!PIu*LyY#3`l&N*Es(Xzi^z9#O8#ada>%!%OLOvZKHG#0Up|)^&k6> zP>#!!rq=>3TqT5G2U>wv!XPV;7=w53+kv*B4)g@$3qf64sL|>F&!;lLmMR;;n z9;ruEWl|K821q7Rjz7HznP7lMnr8S=Z&0O@#)^4qE|x4hTcHCPaHJXWDvBMmcB#+a zL+xQ$6gvnP3~eO@lT9u}SUoNoZA#i3p)8(jSA|Mctx)MEX%J5$i+-dgz-~%^CRoz< z7K|0mAqhJexdjViy{GA_*0={JP7ZDM4^-}fa$;`(>NSLyx6T@>rm0j{%TOoHn8G1T z;93s^ZpUDHh#WQKjttJfHKKpRg4FQ7xH0+Wc_L!}r2cqMXFX3hkotz!%n2 z&nMvEFd%NIipVrYW^Gpy`1o-|!+Xpxm`k$d# z0NeXooMVNNBe>>xIPa!_&-d_iG*SPIYVx&r0?AR?_!<7GCAl!ix2Jd7?(26#GkN*G zCUbAg3rs$0e?tUN)C7D^!2dgG;KZYMzx5ThDfEm!a=*4`B8@y@s?aUQ@M13I>8X73 z7}G2<_Et6`ZNH55jQ7H-Z=IklE(U$(Fb?UA1OX?*_I)_6sY31r*vF5*R7J_B{)-6A zu7xGZ)V(B8<2FtG+GrV|#Np*2%g@PC{t(yj0V*E~v%VO)*(>MY1#)i9zy8>A2HEkK z^%t^!b?XPoJGx+B8vd18^XK`~X0G4y22IQT_))){{rsjzGQ>bKgnmfQd+8I&)j_$yj+aExJReYfCR|DX0jvlN=I~ zNugo~Rl`u8QT%13CuaO7EU>6WhysXH2dE2C#R4QO=+i)e&ob;pKd?^tmX*o?>A4W1 zKWZ^z>_?(B89Z)I6QYM`<-#WvIk;dr?*&3Z3fphb??YO7mph#|AUEl}Tzn0!-t%^T zTVUsEZ|7CNY#O{R@(KRvE_~knGpD;bcb#vm(RXk}E@xye9fdgzK|+WRUC7WD$~vpo zg$9xM&;^aAB~(Z(z$QT|_qDK5M5}!f0afD7ff5fX2)+Un$?5_$Ijb(vtQHsvt^n%r z+TU&I#>f2^Fz4?0+&BN}od?*omX-~(M|WpURS)!9v~JdC!ZFNwa@6s3#nNV2&BV^d zVP=cCNu%4idh&A2ubbaAzjEz8@Ehm6?y&F)0MrF|J9*L0`b`9jbL<_sr_y zhH24?H)-f>=1I&EtD`C&tMy2mmYUPPjZTAsvG1_=5Y_$jE<*6I(+)mDn{z_x0M-WC zfe=F@2#pFkXTa(D^7s>oFySm(gC0U@#JZhCpM1c2nrD$V@O9|f-Q3dgr1k)ui2r;2`G^!SA zy9N?uN%NvggjY!-N>W8?CJt7s2zlZ=BvTJ8S%IMGZxq?)Jg%u2CN+~D`HTX2;z!`R zOb;2yE^;>1*dW&m0T5*&IxYmUYn7OxGOO-?dhE+dkZQm-D;sziBZSP5nJT|#=00xU zw(ffItTx-5nK~)^`)#4?dIsnS$NRDQb{$@Q8yW^dUZo$ACzy7F>0atp?_5%Z}pe#|zRUoIqi0~9Wi6hc}XWlYS zedurwe<;mfm@mG)?A;6dm;U1G51K0 z06~$qiwtwD4y0ve;EBtG2VCr>#;U*oOTko%iIS8GN+EV`B1poyix!=5%swdv;@Th* zyt|}JBmOp4m{ggNSFxQUPPCwhN`~w-R zDp#VVDa>meRXMIdy>Y%jhT~-8vg5M9!8&u)2MQOiTu51v@u__9y9hf7S3XO`&dr|1 zp201;*ka|l>=P8PS4$yBG{0*=ezhUdzVw%;nkZtAH3*-`39`6#e+?RkSue4j8R;`I zU|SZHB+8&2iDqgFk*U(E0%u%w4dhfuPtc7*e`Me>V?tyIGu`&Xs}ijV+rC_*TK2v(1XZUzQU zh^h>0z=in^>gqPU{Q5qe5?CkmYsDru= zs{;-Pl7X#~tpIpJTPWF)FaTR#z?2%|&q)Py+))9E=tvaMP(M)=8m|h65(!*`24-YR z+8@XkE0>nZPCr{Nji7((B1&!*qgra8whc7{`s5Tt?hHDd_SCcO6u-7hBfDD5FS`(X zI+bi|YpiU>*N{KPnia3y()ux4lm6EbAHOZEJ@2pj{pzh|i%D5wB;NkcOGZr$uV{3U zWb+ML;*odVWd9mpa0K~Z3i1~_b)GAc>rou(A00WxG*f1qMzb%P=~($?5sIN~a8n&q zPusbKM3X5qA~Hsm)6=3xY}k+vMrTjW<1pHOy!Jiwl zxGVDiDYGhjyeNCc@&)3=38y3xDR@E1Y8(3a`Bp)JUj<<2-QPEkwIl~6Ryh*m-@(pl zQ;kHe_rw}`vzSDc5p!SfaCMC4%R6J0v6@hGtsRNnSn^v-0<1l``qqw+uYC(G_fWza z+F#+m9C~aItQqR-cD|pbt=Z~rjO8e5qow(OpJR`A+}Ct)2gWyFZ7_c=zh2G&gZ`a( zUiC0$`6#(6)VXpw_BQ0REwL?&HzwRWV=g9luJ8rzlibg|<6CorK0!H5c(ZMwaH%C} z3baJKw0}^XQRN=3IpPE6%WRm%BQw8oqkTBS+6{;eAgP-%!}pt@2u6J0XjhF2p&y9v zPN?oC+CElt4o%Am%eS3QcuT_?-d$x;O}4R=Sb27rpvqkcDlMDA+>OMlB_$DpG$UQ- zDo;(sof~SoJnip`xqCUzCNdfMJl7UB&q7Wy#Y=cu8zI`J<=rp21l>6Fz@9Wql(gha(h;MnIG@d^Go`K#(c8 zb}2ajCLmX;_so?>z&Q5eqH!>=4=GM*7Bog(oy|EZ<4%*^gNA@hiV75P!mPtk-uAf#wOX$n;fp2fzUE zt#@8nIQ}swg-);8d_5!Z^~2%c=<7O2huczP?aRBXrKNDv^J~nei^n-@Nq_6 z#U4I0I-Sp2o!xt1Z@t`a9KWO78*>5(97TtaqiltAb*cwjB85@G%Aq6wh#x3gI4q+I zrw071B8O6x{*4&4jDjN?Llh-KGnG|nD5ZXZVbx%1g=%e3L4#ho@?-WxY)xhLUMt4C znfsp0dE#CGFIPzm3{KG)DGHI+ftM0|uUIO5m6S|V0pB3aEI~=iq&b-)v*M&tU!8)h z5w$hHnc}|2GY!hhakz)vlC!5M^|KKom3BAU&OjZ{S)-uwNgd%uSIKTplwlqNxu=^E9ocE zPfmOV>4q9l{jS2DWw4^EY7=@>M!&H5vSMucVvBlGJd{>_@`TKc(_6qZK)n%d%4t_% z%}Uk@#ar&3Xm40+#_gl*k(@s$?y&ee!Y%5RT5_}e`9Y8+D174Yf8?-}`Hcpqnco_O z3>1$XzsWkPwKuwV^zK>vs`eJ8fR5V8J8ti4E9x~9*<_$Uk#&`Su_94)!&hF0ZIvUD zD}`3SnqUc3SnX(F$;UE4(=VaVxRy*J1>FP;?!5vA_c(YYtdRR`um}>&O@d5_+$Ra9 zkqzFa@>owX$QdJ<#boQ_C{!;r;>2FSra>6eXlb^jQw!Y*jrQf#ThU4JbxE%H^&VDXO0AIYrCWKX_?C%c+ z{mUxlJqGtLMiJ$JC_hmMT|Fe@`24#Yr7y+n#>)B{&0mu+FEjnNu`<0ZzkhXC%IAox z3?aW^zf*2wP7EiAW|@pI4f2TQDW%qBdi}93Ofw~Q4894>og(7PAsK#8m^;v3AxD{; z4P-+viVLH)7h5;b9MsTlyJRyp2h;D##MiCv?Bs5TIG&vg8tT^#YFAZp21pX~0 z+35Ug^N?!9xi!bvvuECp z>RwbV7XI(xO6Cr---~LsD_aLw4_K?qIP$CNE;*8|17{e*4(FC_o9=1HT z1VK#fdNF5k9TXd5ZE2ij?Z%q(sB!CDf9#RBqd&ujdQ2fB%82p0G34*Ek6yk0Bw45^ zOPDN?P5mB%`A}j6-t41zu_gz4^U(ytFq)n{DR%5=tANb1Q=mMfk)OR9>S(Bh#S7Uk z7Q+R=$e!VyvQYd|x`6BUKp&;D|&XScGT!m-x@iru>tg+aw8bMDW(r&D zwur^)v~rk(AFM>UoB5WYLUn&}1>6)tj{nAwKLvdGmjvkcy=~s7(+7;<+691{-NbY+ zw|SX|87!KaBS>X%@v#F!D}Mn4XJ$H4q9qq^%ly0=Wb;#jL(+jRK%fQ zeENnJo9)yp7?w$G;jdw3#9a6WrqV5t_?IUzDcA}JSlhd4N5v}H<(Oo9$N)1kL|z#2 zIc}Xeo4q6or8%Qi_?kT`>i&{9uC8Jq%$m^^*J)+m%FAn{S(nFFa;&Xuciy(v8f>C! z#9DcoxN_yn?oIl`Wmzsm9N%J(`7n@(*-z#sCETDLWJ>5Qxn4c1wT~(m4T&sYCu&aP zoZX{s+nzvpjqoAmWrJ4@z!yVdDH-)B&12R}Hi3tZA=qJ`lBRZ&+hBU+s_`$Bas1xB zN8y;^bQ9Pk%$b@d=Eyk%i;J|zU=RH+0_5rS1`yxyq}Oduz!&27sjCljI_LEY)z%mt zTbpiGlUe0|`{EFw;LWIXK~V~B40inRuE*SQ#;j{xtN+elJ3O9_e^WT@4GISXh42jR zGSQBE#zGET*b`RQIMWB=qXdR=;Kb?OTK!+k&-7(t4;b85)cZFVdg}UK6f5^bv%-I0 z*H+fw=k{a~mI&LWF!W2xcOw5s|$3TS9)* zLip0bdET^zU7Z26gWInU1Z~x-3%6|E<azB3N_ zkQ;QUXJ=b+o?v{?`ltzj?rpA9n;?ccX6#687z7Q;Y{FoM)iMwWBFg5~9o&G1W-Uk# zs}>nuz;;AY=}DKf)WGVBVX1SV(ssk+b0+fD%}I@!n;#WTQJ;Cx3kJt1kTs-|D@3rk zPCk>!0#In;%_{|pG4qCO$umzSqgZDO%RWTxrD6U?z-TNm4mi*o@Lm8vjUv+@MKj`B z2?~g5qp0Q?Flp0L!G{lR7*4=XOEDAjJQe*HkWtsFF)T$ z=jUtQ&G`25Kb8uJec-8A^`9p-8GTb*6=r3-;G}strNF67P~8 z|L8hdn$jU*KLy4F=LZ&6p%DCrs2)kkk;v53K2s4POxWB-kM@56%hetC62p`HAI3pn zW>?Jk1qM(r6s6Sc+xagS0ZawH(KX6%iH~*OfO%yv5iaU}W84S8K6BB+t(`ot1b3-i zXEbzmjP0Xav91Ni78=oVe}LLl^#pb2E{%y4(S}OX&iifx(H|znxRC&Z z=MzO|u@d$x0l9!&!a<9$H&kU@Sxp6C^{W4`kCe3d74N1 zDV_HB#(L08iFw7>uF2TqapUGTrhwykv&-%j;*ED*9-?5H18%S@U1N(wGIBQU%xe1B zbQ38Lu)ggk#{_%K?xYZB2#$`G4XhhD7yt*>0JqU_oP^46PWh9v-%{YMHdT~zmP50{ zz@_KXw{LgU#?{^d=!AHKnd01Iy)E$x;lUIzN@xs1r@xnf=<_i`d$v-vaaRncE4@)2&L^-8)QpaiK z52WBnQupBO!}1B7;TO&OhG{7gN&OhI3Pj3sNXXzf9tnnI4CT4h)HK1YOhqXZf<5vi^Fuf!1JD#4e9CPtNUT`-*b<4XY&mtbRxWD z)@PvYq%eC83SrP{34O|&)UX%ENclC|-0q{!`FI$F>t}TL=@ipmx z4FfNaVzK%H{)d%ERuj~T3`EWUZ967p%X>ITU?)j)Xc653Toj1!RgNJ`HSCmis)X?^ z%QM<6*))NRmTW>rt0IY2g#XNmWQ8S=N7ABK8-`D-ngFREu#s&$gqm6`#sBAFiV7_v zQwtV%iyS`8pp5j@2}LWcaKnr@gtsr$$FNFUt#h?d3CtI?)hHe)Wl`2Hei^PV$UXfD z?b&`u*o7zu?YGVi@JNu@&WMgHD1YmGc8Lp%iCRok>^LyLw-_RUz{HUP4^x&17%+54 zeWDGRh&vSd)5sZxb-XrD3tIQglAcfe2&~}FO8z<;&aYzZ6GuZHym=L68D&i!3_^W3 zc`tAaP9B_#n^41ax_x(W5v?>?)0*7jV5BU&d^`59_UACuI}aqd)4TH3fuZlG;w6^u zX~wz^W=0M1P&XFop=#ke>#6oQ9nl+p%|~Zys<~fV8(^__1m)e80+*u|_F4lGp~2UQ z%WHk**K%iA%Zq19h{XFc0SFNh4(V7=aVgF{CZ;dVUerneXN1c=oiDcY!ATd|@vGzR z3o9w?U*In+Uf6}%t17VBH+tX~`s5`92NS^o{eT2l{0FR}JI(?9YsUu3cQb(~d@HBTk_oR0?;& zHoPfL%g&!JFeM0IE5mwnAAN8y)|`2xSG;4i57RGgO8u~>Oo*5Fg*(I^_kbU^nk&MY z2dZ=UCCsYpB(Hjpg5TJR4tmX(!*kX@K=7!Npsk zjo4i>@iSP;mVlEW@%G6`FRQ>e@z1Ki1_NNfs){D2-h0094D?c=N(hgDZlbvLFYu@vL$Vzs`8B`a16f z<0;;AeM0EIjgOzG4Mi*5OXW7rSzGuEFQyL`XpT2GN0C>{i}Wzi>^U$(fOg{HXcR zru|1R=f7Lr7YXk9T$8={E#q50lYixdrypZ#6Aj)eJeAX1?%d|(<3Z7AmHfrCtUu=6 zYwBmlXM3_vA?*!ONj;GiCGx@S?j|&+1iG;jd!5P}-AM7t-EFpPo@GOwtU1#wZDnib z=oLicFGrrJh4osgat!d@dHsdBn9Uqz3VMXdtZB_T1M)=?)U9H+K$G6I9<(2bhvq6V zLrW>ogR4t9?VI5HJNBGnmzn337f6+fKEjje)}nub(b>Tr!wX(^sT8Wmri$5;@SolJ zO9>!lKSmKy7mu5LCO-bAvy^Ux^=YkCMIgqfiaxr>r)VQB(G73H%5LG~_8y1{2Ojcc zRnGEurqzkgN%%T%{Jml~`82=wFdrw`FC#TehrM^?US&_h*FPp6>xfOlI%f$RF-~!^ z_)aw|kI=>O)%8W}wdE`b*Ad#sJfU4Z%wco2Ze5?B8dVUk;$dAnq)$c?oP9#?9~*PL zy@lg+`L~;8s{CxMQ{_fPPY3&KQ6|x6ZL}H9sWqD2Kb4?^C(161|NFgZ>yC&*%&}B% zudq*W4A$xW)bn}Q9#Hs6vKy{ccVm__RSBKW0{vA>29_z<^q{{F`M#=5(C3FF&|&G1{Sp?FJU zdRwMce{$OmemeSq5J1VT;##wtaZU7=iRqR4YB_N8bt;q<4FB1+CvYx)e!8M$XxA?8 z(7miRn&mcaI--E%8Ek`A+jx1CpTJOoIH9VV$EAAGOQ_4acqGT;kglDfsDVXnj1TS) zN%&-0`6Cp{f{?f=u}5pda7of*RawqM%Bxd{HfTIzr-E;Rj>D93vwfr`Kg&_ z^N!X)C*P)2iL3Jz^vmMM8?&wsWv)rTtns9rI2^;xlp2=49l;r|#v@&$X`Pp7{l~A1dlv`p9-%sp#A)F}Ar6A58*A7GsIR2Gt zqONeJce{KXc}&V0>x<{(B7<3jMi}!|DBL6Up~g_>ab}{?65If zJkfauRoXc6$GsQ%lh#qd_}27C z0jsuCa2mTkSBE72*fHJjM>U2j)i93vE~PA`JDJ^2R>$t7W6JL*BQ-8RCE&^Er_glP zQ&2xMq;@XK)6oG4@WAG_S?skruj2>hIgXa)yv%*fcxdcACLj5e_;Q?sb{qeY!-F<@ z7C|r!aFfJQrYz4C`Xu)~8f4uSbZURhh`%{A~BV1FayxKd3nCGr3uIG7$J&n4vl-^39sH&zar+P%!g| zAH;1^_D6nyJAE+IYueQ;>G`Egs+8EZ-zm!0oWte`e6QjC8R3!$1bd=`=!W27PnRa+?=3UV$Z)7i{o-6{Q2N{%+o30 z+snI3#&Z`1yGO2Rg`IJ0dgf$yri7!c7FKmcHn{x3AVTg0nb%Jcx=Ju)T2xYnD09V;ae`=7M=SfKl5ooS07$%zXC zc#psjoJZis3NS@^hB7X7bhk(NKlAoud1;Q#YCZtS1Nq-irPqxc({I zZXf;fy)X*hu%PAv$$^(YSV_OJys1rKzrb`ASNs;P6N%0Y;f{h?0Y7F;oTr|hq|PFj zLGh+>Qn9VK2;RXvY3bD|$@x;9Big3?54@eDI+Wkvj7{))4`K^zw-kQ)DOkibn9Xt9 zD@!(w-YnsqEus82#QwJl{8{3qz;P^d-7s@Q_@~AfrC*{?b+>1xkuRDT6`V8QuEYEX zEoH*Tmi;*Xg;s~>*i_JJ$;)BGxzaaUhxcv!UY8`3&8kZK5KGksVn5@4oqyC7a~;37 zyxjogN}ixXiv>2uBTA%_D6^nbAt4IFAv^&kJfPR1Iuo+=048?!Km%>Oa<(Ib0dd~| z#3+eWaWn~((W2BoLji6B+lWzdpi-f6H8YFw@tvRk=5BT(gP__Y8FRMGz3;gV-g@3M z?z69c;yc40`C=lgCQrq^ikVgB6rhLCJ9sWAy!NriNd3^=i;*XD3(nhotnGYv;=SC) zZ@E1sYtM81oJO*YdCmg-D=6s*UV4X`zp8PWcXzdFKGRu}R^?LXgK#OK4>Bj8%ZpJT zke3SlC8-~tGxJtiIrmVruX2S(ILH&{+;N-!yF|V8?Nk*NDemRJ^K-C(`G&q>`%V7EiL9w1oNQM zRs2)u@Hbd!qW(V@wtpJ6u0wqN_Hn!3)UE3m1!&x2h|EZ@g@^pu)d_z&mLjlHZyJ(q zqHGY`rE<9{t@Dnw`pR8hc;}6c5xQ%{`JSwdId_LO&J@^rZ7wFKZQ*UIlE;5?EDSF+ z#l-Z-`GpXLhWl$+a8jhu3pA{&x|N#p~^`2cQuD>Q`^!E`4u3XMwQ)fwvFF+Z2WM zFO+;yK850$?DJDu3tkNK-5d|s)1i;P&y3u!Tleo3*OW&a#)noq!)3QOj<O0&E%9DCd0pIE@h1W7w5puI zg)q(dn&(aw{F}}5uEc5=V*Rt6Hl>7SHXh@9;J2!`wIN%<9GGl_aRdKa)w7=Yb%UMS zk$rYhb6?a8IR6TYduEwBGyGp~%fza82fIvP^Wy`aXHB|;-1YI3Tz!GqqLJHWGEy{r znA^IHANZbov23R-l?V3G4~zx^zUU9;*fR+X_GE<16Key+-ETlQbXQ`UMwYhK@e>=^ ztMls4dyMbvkM2%zP4PJuk{f;cU_I zmV#bcJ{v!(XVJj*gqK2f#P$r!HPI!3C&YI{`91eL)Jk9z9?BKBdwMn{cg(9& z3?Gymdv;~`OE%44_@QvhvmWFElqXxPT+yvxJ?6=kkq6w5=GkE%ubiDBH$AvajAFU( znSl?QY6Q+o^+YB9JnsGrZ8{c&oq~m6b*{QVeY!|`LgFQMyu`H-RXA^N^-kn)bcxy*AUDY(H%$*!-G9j<5w{((W69LyyBj4HK^UwZajs8XpbKDqg_ zQum!C)vDPdO%Utt!>uax#PbJnT8Ag>y}KYO2`csn@ie_)d7=@&f()T12wMXrC_kxb zRZa12Sx(?+=*;mf-Ku=%X;;c?y&EYD-n`WnenHxzAL@!3% z3-$r~#n^us-xtwU>$-OZ7|$Q0zOi(2W*9d-vM}V0<`u}AdRP7a!o7z*qhI**9^}c) zBJc)w@5RG?yGwhv`H-zj{b{CnckmR-x?d6h3i?ee@57#{Ym-FwljNj%eyBYD(eJc7 zbGqoiwBb6;N$=Fv`(FC3`sA!KMPOO-yHFF0D7S0PK9tKDci!q5p;fqr6^H|F*ZW{~ z0gV;u{7RKg%Bq&kezX3-`g<*gKZ4m{d0VrXHei?snPk3JSZ|G((Okw<#A(Ff)rIMe z{F^*?%Kt^z--g@IhS$>~PalYPwt(0K?xA{XS)h}w=anc96{P=d_e`^6s|WHis}IWe z$K&ILzljUC#}oQsTg`N`?HBIsk)vFzukWs9kX=~A+g0~`z^@(BP(cjY-L$km61k_t z3YSaBLgtf1DI^L%{07%HPMv6$sbih1?$7*1^+p1DS+TQJnYX?i(ap&BGyw5{{=)YG z*#_?Cu^T08v|Q(JuYfLHH`j;WB!I1c%8YW1N&c{_*4&oO=l0^>daVR^g_=c=C#l<- zaIE%3vfYFA{=Ml4KkH-qvYrZ!xHVH*iEaPmT^GNn5QV9EkRH-CGuCNgt{W@tAPx) z3^789gf3McIx(7Xwx5p&VFLNWLs>xZ3x@@79=+Hv<z~V@$UlB8o7Eat}QGg@G4iz+b?0Mku(ju2} zNB=CI<*j;YIvQFkN?II41h{WMBl5sN)o}#_mX@~i?Tg_Ug+#&pEyiL*{Y3vTdIkGH zG@p}@1d*x8LmdlRH@(LYISqYb|`GdM~K zbTSu)H&Do|fIX%L>9flhzA0;xYm+N)tkXc)xU}*lr7;Btt(^N zqE#x=vqe*Bw9fkvY=zMzXe)X-C2G_(y`_xdIyv}B%EhNb{h6NYb;rU8xhL6o?EUYj z?EUQa>zTS5?Q#j!4g?J??dlY+MQO9xx10tVki(x{e;rAVg$ID|CI9+_S;e)3_nG~V5rq$vG7fz5kmC7G{iN~0Lj^QF z0Nwx=B8k8)gZ@V>OVL@tGb{jVpIQNI6)2pxxJ;|PmI|!6J>YL-6Rnme9u15vI!yAY z6b-?@Ug3d|N6n+R<654p@w2~tnrWldzyIX%m!`iT+8!3$9uC?Z#j##$V>d_3!CCn| zsH?foISIm?dXVmY2AF}|ab93iX6}!*ql{;Y#7i;99Y*7@zTkz2R;c zQJGgvDi#%ji?VP?No1IY{y!J7Mq!CjPv{(N{SltU$HYQ-*zE-P{pg(Fk3j1M=j5RM zpQi!X1-OoYKS@%?aPRha5P0=uN}`_JIt6-UHSHGy|IZ zoCcU2;3k27QbyU&)>B65=ku1KS}948rf(P)wxf6qZCi;14d@z3ZletUWmf>cpXDDw zpLvtu6^ATi(^$MqYCIz$H^KVA_&|Pw@A{$*Rj>IL?iz;$Fuq(M&MEx3fV?*30YQ3? z%bcxqeIDs&#Lu)yanK%N9sfxTEq8i?04ibSK5p1U@*!rw54=3<0=$wK9E$QA5eqvK zdhN&e_9FZuzTftW=2F$4Snk1omn(SP6NK%x_q}CTF;nK>mQVWr^q%S8q}v03dSNP@ zH?ep6UzB5-T&@9DjA}T*-8Rq<4n}q%j$MoX@Pem%q`nZP41jv=Qa#Dl3$7Pql=~~_ z6NZmuLGOfY?ZmwMs%83&f)OrczR=Yy731%Fq`@IU7ZzX8WVmV`-+Za7NF=06+mrDm z!<*vq!rnK~e3$rp;4Op46yC|_6y&qGUl-L9>P7vEr4)V}&2Iw@e=|+_%@k4hlCe6I z+ex=u>2w{Bu{zgvuiQ)|S9gw>dHE5CA;t0Ea1QS)?d(TyP<>PHVMWn{geu|9I40F< zeatu2fr{Y?jz~}M8ekfkliom?LOc81=MQGE`Ai=6UZIOE(UTW8J@QZjiXMO2(o2`K zCk790CC|%I=n@BN0>C=MRZ33Q7`-~kt`)#&c-cB+sjb~_2j8KQgU1(VZ;>u!4qbBk zOTmZI%?FT35W`cL1$8-7jO;%%hf1!mKm6LE+5B#ZGfTxnQ>Cdm>k$sv8d_;_uP#1+ zp)#&6*0`^eA=AszGj?2M;%XYxLPING6JkXt;H~^B+>~h47@%3@%CU1imnbJbcjF{2 zbRlh=UgT;sami_=*409CdB6#=#*5$k53sG;mFi^VVnUXW2M~n2rjKt`t3WYWiG2NMMPsC4^5l1fKMKSu4qxR1!RCNmx=++V4f;5IfSq>_hDMy{TNR3F!G(Lwro$+4F?Ycp=oqF?q_^OqDZv#6ap6@ab8@fLoV zc}{r484vUWTzVG0`5~owAjSZj30DCrp8UYRWgiat-z=MDXb07WH`|-7ysP0%b&b9w zJGkyGTRi!u{bII&1{z>D^I0OEk()a`!*}aZbm>n+%BO|T=>PBs(qGfq&P^_LV-e|V zHZkZ-4y`BfOg}@f@kUX8E(Z1BYWGz$?X^~fct2e%s#$PyMmKL*M1#&#;Bb}D(KMlh zK|%+e)D9YX4Kxx&=kPg=ql;|LHd0voa71tBW(CkG>YHC})g5*8M3~y4DxpI~3hxrR ztaF$}=*T6#%|IIG8VM8T@;{v2W2`7aw=U|nrfqw!Y1_7K+qP}nwr$(CZQDBY+xOh$ z?BwKT=O+E5`%kCSqdTco)p%YG+W?eyah%T@q4_W_<#56P5@l=$yagvV0h5+3*a^*J z9ssC6a_385{}(8R`F{e%Ffg+IHy9>r(}$3Y?$BI@zo^Z+Qz12^f+`(>DF8pBa=%+Y~dMYhh`rgwQfgVyZRE!0B(oNgDD!zaJ zoHaBI{9g*h@;@mMBOTj+D^P-j#Q`mn@XI%{dUM2n3Jx@oKssaW5NE2Rx39sDAykwl zl1ZEoPq_4HFB$@?XwEg)DY?!KGY8Kk`49TAHBAFMOgF4OdQBdpQ|!WSL%sah>=dl{ z&sJMjJ!kMs%LL^~7Ekn=ec8Q^-5q^MhP(RH0bh2*r^qQ0)OTUFcg@QT`HoJ>nZoqG ziBf5?To={>-_H7(hX+bh$?8OP%*BAGM_8H<2e)-XDY=~(!`AAAkvRu=6^~dm<^D?P z5wo`xarcjn*2*Bv$h8dS{4={XO?bH}LKk1nEQUI-hG|wQWu8l^e>0rPa;BPjX&|Md zKuxTla%{k9QE^JVwz)eQ%PhH^5U^BGI7B)Glb88><=Nz{8f8YQ|7e=XG#`6hv44?2 zvB{X3eR3wT2`<|wrMLTEH872cs^Mk*in^xN;bX)uzRiFm9Lc{{c$QSn!5Vd&;eA_s z*0#2+XjoVkC6{B+8^fgy^H@#omu}Ub^iZlL9zW$?)+;(F|+-j78E1HfBT~T4-0C5jC|DS zaSt!w7gXC7A0nWdMf{(tun7_z5?qXH$}j;&7)F8hGDB0c2)f!6{#-vn_?;$X0BW_I zf#koAYj>n{B@5(}E1uXbrjPdbuJ4YY>z|L9Z)0QWA3RL%S2zUhkeGA0nBWsumy5>t7;0Lv<%#+8KolVi?EoKCP?j{jIt#vS$6nOQb~>^#Or)@__~xjRGC zHKUvUX%5~=pnt5Yk7cq>^UY8-{ul_Tbt~+qD=gM_KeF{a@~iMQd+W=h)KY@UUPKg| z{Iq}H;q~trRd5f!E$~A|@(`cozi)U4Es!UxRzaYnJ0ho^v)j8DQV;Eum zA<||J9LPJ+=5$fyec$Aup>=`$qNXa$cl+^ba@ATrWor?${rBW+v&X zdG(Hu`YGkpNT6p+PGVgUWjz9ExKg61LMipnj3F$^1{-#E00HPy(b z)xZGFl_W=TsH8FbX2wN=t4sB}L2`h>QOFGcX8;g2Q69^`5x=w8_ZNEJ(Y3RrL4q0xKpTnKT z+befTH34``_e2QZ@^(mApbL84=i)c(jQ;HK!uGRugO6xdQHOl!*=1$4P z$z9B=8U zTYWFB5x8i3G^GW+=EC@!{bauu6q-~qTVrZNYh3dz47=o!W2W>1QM;tdDfw0*?itBD zC|903zEG(t+2udsNYplc_?9F6u2n+jhzLy*rTzL=e4Nk`dfw)EY(s#S?fRTcnh2w? z&PsnpS`m-dciyRk&>Lms^ThUi@8w)zQ>i9VDrL+{uY4ublMAosmO#~f%An+;WTRxQ zWc!MG<_6~m>bmMi>pJTe?H1tm%VwVS=sMInBym00i##ay5I}n{qj?B%5+3qmNuY2v zOO=H|ye1`2^7Sx;nBt-kdQP1;qGi!v3rhVB-KrP=-(x?$_@Jfw$gc$@q^VW6N+~1W zB1%*YyefAdg9Dr@m3OpO=BosarGwu7lD@OM$YQAFoG3#tg7KBRwDW@g*mIE+({ z{CywF3Qob0ajL|XGX&FU-OO@cxZKZl*g z8t(ZMx2~#bB;0@}g;k_u8};@Gq!JXx=8|(BEKm>EG*31@gy~MEy$^Y5g2IirK5G>h zIFfvKjI0aq?lG=yq1-tS&jkejI@~NeY=Z zqNzFcc3afu3HaHTWOv15;0<>CXgZk}wj}iyonMBpIjB$ ziLz7cQ!^S&5PGr$<V$u zJFQaqeJ19G`0;qX)F8tDVy)HT7=5!?C-Bj_n(Ay-up!tK-PjU7tI_OQ;^wMqDr(!1 z+gmJ!0m^v)^6+%`T(3rz9uGyltS94iE}Xa^EBEXNc)(e|HH28*LYx^qtx(ppMCWMI zmHw?UMYufq#xqq2GFA9vF7LaI*>#}r6r#mKU9|dSkCBkvcd$hEEV<>X$%CWLqb&F2 zj|&M8-zne{cvyT2!sZkb$4=3*x+l5!Anw(fa5c8JZC6M7^t_h`8xyJPAx8#GBLBq; z#NnO{vHFRY1aB;3hxY41!2$_1JGa(H!keK-C*FpJPPVEB#FMO(pw+&xU<@r*;I(Z> z>WMK|J{do9#&Ep;Ce>GwYAfORf={FEPv3YAR z%}#n5n#RM&!}`vUgoLniwRf})9(15TKKj-tj5b6&Gg~j_m1Rc>cXQBbaHsnt+33P> zte%iU^j_}(uXm97yWF3KF4Pxv1I>UCb!dM8NCvT%w2+Cx%nuy|&g_CvN`XHCfqhoY zIDQmlzd-=hB)%ERR9t}`>GvOW7tPuwR){1Ki`(pa5ZUKZk8y0VdD(Vz@#)d(l3G3_ zi+hsb7Q|;p=f0FPZ60@uv9J!?dXr*Wa*EkH_th#vm607D__6+L)(o+$(o>{ES zS-b_l*UFDzXDbE|ekNl>2O~V0UUI`<{1eU2|hglYTx^yHj%&vDRhU4m3Fg7J*S8XzTFT_ZL}YwSAcsQHCoC0g98$Cj-lulCsT~J z7BAOU_rj{c$tODx;`BiX;3hP$($%_cdPDe+WkQ?6ri<#x9-Hp`1l-1E7vQ1vAr%Q4$lO{* z`~WN56Bqwb4}N7;5_0CH1?^#*%a z7w~@T2ntFF`aLLd=*CnNU75HpirFZ($;ru|>~Q1>`4BYNfK|eW$*z0i#)k*!Nb#3g zWl9&V@z&TcB`t)07fnx(0sa)$)>#Z8`I0O-BGj6zZpEV(`Q~vg;(80ghLt z;4VqPfS{l(&bP8d6ERUlLFuCn*stX91xFQ34xwqySS8VaXZXQod~XAFTT(}K=e70; z(HJ<^K&9I=_N|jW_@*aP&ePW*D=1T50EMX_eD}oxg;0XJ0s%Q09N&SoA_?-rf+}Ne zsy{(f#aKl-#R%7h^dk3&)?@X){7CbdZ31~Od@W1wZ^WRftz=T!kV&g|^5@@}-{J4> zTnlM!{Me)^qj!9J)jWFSlHh@GrSaDqv%Mm$B91SjZ6IqD?Js2&y*Ob&5fX`~FqfMN zV1X=*HUbCuH)D$CHW8w8m!^hvrn*(L?~}Rq`n|@#;_6JM!6IXLTUQ6*Y(M-l>5*Y1 zq}d9)6M7xkA2g%u0Jm;u55(?}lJKTt&b+QYm+v!ql?Vq8HiD=5C&L>*n*HW|D!%v7 z6(~lP5b0QX%Dma-cjLZG80Zk{kjhX+|59cJa7(J5o@(b27PYOX%qo%mp!{RoI+E-< zhmB~fBMZl^dW>Z^)C$_n^~*~rn0$HRYqi!+_VpSuZ%#{nma^neO= z-15^(KVlJyQgbJt+X4p`J+1e9Rk7duX&$KiO!{d4(dB_F*cd`$Eu~c zc*5~J&u+XmU_O0x;v8{jaU!vTIBjJ{v&YPIp+9KRMXEB1@NQApN(`R;FTm@hn{cJK z%!j&S^o;rGosFr^^BJpxjPJ?j`0?aU;wgm5qVe`Te^nzwa+xR=PZ0MATK?rmwRSb4ys8+OXuVX;e-xq0YC^N7`AvU1Rywb ztd=Bpw+!BuLOcV1EM&T}By&t~0)u^uezxn0zvwB&a`r&Fq2|QZbIzC6(EB2_2P4(P zQn2J6UfA;dDaWfPv@*JuIbs)bJh)Ff1@4VaJiu4$P}l0|=t?RDGmn-S4u^*!1)Y)M z6D;$ITh2jqaHsPDw;3MQ;-yRsrl{nq0uB-KAj8Bl>Xbmd2vrJdo)UF^_=1N*-*V)!V&!BSsgw5SbQ2Cru-K` zIixw?ufqmNvURZ5mb&vTcQQ8rkSI0()cRbAzNd|3L}0bt)Mx^$dGUCRWmTE%9==j> z4}O7D>~hx&II&quhfHL7=)h~3ZtuThe`G+3>9;|dubc*LOOnCboO5Q|p`5L5C!&p2 zxf^U3Xb)RZ(T|^!{^goR)3e_9hDXuqEvwyAXSe%!Ig4@W)x09<_Rt-Hod~TBY88uN*U5*e9&KJmsH<|adC+Xy zx`o=1jMz-!Y#fKC=RPE6^^xQF(=;A>cSacjtZ9vHMI%7=H_ks(K@dpI6v-N*vbJQk zz+E3__<%cr7ajwD(HD#QuND|NBLH9@CoSF%BjA0_pOw943}jmHcDO;@AyUBt??d@8 zK+qCOAZ<-*tsw}j zyjXZV%tHARFH_36WvfR(U<7U~ago4WKyu+gb@sl(VvAh03SL1#Q-9WvoGeFUH+wiH`Z*~B-~09DHb=$6-% zGK3{@7UQLM6xm1h@ej!#`A7ZznAe!va;UuAb0VHERe$LqP1qnb{ip!00T0Au0fc(V znq2j`Mf-YECJj(iX+yMjX~btf^b9kx6&|B6>DM4h3;?RJP$)F}%GMRAc+50OEDU3G z_9ML;o*1o#5lojP>(&iNMMgf|kuuOh!vSgX&;L$>fn=570U27=>01D>Q1tscDz}r% z#URD&BP1a-5CkNb0@?HE6|3|SE{0G>>W4iuh@`;>hexJ>GbD-?dgC!8+JHy53>y2} z)xtc9{1Gn&9`O^+DwkVTluAi?bMR`@MaFZ9it^K&{F_j#wj`rW%o;-Dg8FRwkPO|u zhCC+K?O}?|O#GKln)?mC#bTtwYG^3Lq+CZ-TWtFc@6Cy%o9q&@W^=K&QP$hx3zr#M zW~U>uuFl}TBYG|OzIxq)U*t2E;I6o!suHsllqdqI)_ zm0#Ulmkpa-x|E(MEfHZ!uvFOO@DCw-mhuD~0qYp}pp$K&MC^e;Fb)^5 z{ubOdK1L~o40?=nRtVQ90&K(@khMxAJ1iHNPk6IDKv{{G>~~#Qhzv^aZN0np_Hsig)OhM*L$2zyqrzlgH%>mev@0$z6`@Xp$+K z+$77V#vsRM)o#pg!EWIPFQq}8Rna|5I*_>EpeQEbMc`$CJ*RPW({kH%8_y~wc#doY z`abNdopJAV{Kv^xhhk4ZC!*bLIWUg%VxSwy5HW-TO7+qj{!!HqaB9TRp(dI7BBY#cgtB zFQ$K_iC@ASMsn4CYu)K{dl&~_IdX_yQyEepV4(mSJQ#vtA4Oo0n%`frAtb<57-4R{ ztgYKduAcGY!Ep^MR!ap-6|0;zM&>fZwIjyNeLi0VL*Aw}Hm*0;>TnAX>j9Ad2&r=D z(m(gfvxZn;xx-2qZZ9?^hV3DI2MFA;Mg#Q&0{Q;=Lz_zll z*2#cL)_p>bOT;#>OJ4HEq@=h_84J7Jf>fE#5P!HD^T}YWYgu;edg)_PDW7_Bikd>> z@c&UoDgTHb=|QL0jFEG*s|-QLM;OudZo5|Yp#W2jt~+yAf@ zbF%yro|WM`HF2ay^(r5{5X_A5)QpxxF>0{9Gk&*}n37o-Fa^LAG14r0tBRJLBZMIS zXMDFMTcWvL54uC=_CA`{`D&y#c4be~~RFbUFIVL;%(=;v;uMnh zSE6=-%x>@jT#+GI;x^xcGFpyKj=6sydu}iZr)MSIRiSR7d1mMcN5F$JMBP7Tn}SuG z-?h84Q5cUF80))}1m%+V>Dlb4DEE|p2 z^@$1#7oM;A^eKvs)CIAN{rMRlF9NrhEhbdZ+qz~h%wZo4pRYHsTOI3=?F;|46G4(B z@e;%n%nUIGD*`J=jy35PI_x!%EWlH%dl;{oyJiQt9J~@qkp?P00irS@B#BTK$lgJ$ zpoCA1X@cDbvW-bOePf=Hf4I?mRHnwvqB@#&tFrDu0fmy1#mO)XA*kGl24ScP^gz(BhWR;?SVI=h zjtV7P&kpZhLkgi!OzPacw{wYM>2Z0b6>#SebxeiG_GYP7YgHv)h>f`tYUTmAcFY&yE*_gOm#R%U0*7A|ezf{1%JX5ulVd zhYhEz_z935Amtj!%{77~-yZSye-fBx4cK7XQfS`!gt7$^p?c0gzJ|JBovqo`v3k+N z`iUxTAjA3VXPO3kIu4V3yg#|CFK=G&(nh#)GB-6( zzP4h6R&}=L+^*VQzpXg31EjT}1HMG?K!tR-$GvO1lb_E&ekPpTMuhFMkEX^3Cf8IsUad+mWhAyL!(Gp@l#PM1pz#@??mDXS{Y4kKbeYjIP@@_e8M#L zktG@J;t`?Lk?tX+1jx&Bmphhu$;T5V@iB`Lp9LBoi?`W_sZWn5HQ57N$Ze=~+{1W? zq~#KmU~&38Cs?~DXBGh(`flT~kh+vp7VG|mj;6|icc;^7@Ohs|Vsc4#kQGT!1MwF% zrW})SA_$B6S0F)W!;NT3*Sfpz!w^#f|I3x?v)Em^If2mqI6KIh((}N&G{#x=BeouH zp+uYFRAY}?Vmp=uvBZ6yp(+YjkklDkJ1VQA%=}7OL}MN8*|?5o^;CxBIi^@;z}}Jc z>^DjSCNh_mh$vl4Kdk7hFpX*q@4@S$ZaNods#0dDwR%i>RH+QeF7zqPS%7yE><}MW z;yA~aqAf2kZ}w+iP&qASFTZnqZx+9o!=F&HcMDUS#*xL@Rk94K&t#cxQcu_%%vSIo zeW^uh$m%ZZ9E-^a82v$oj(nBFc=A7@fqF#N-tZ$U08yf3(d@APH6p_ngN9?R52IRL5@ zwE+@)+rn07N;sEv`#%Q^X)cLaYnD?ZE&W386Ed z(rj-REzlS`#^$YP#Z|Ic#6dN(Ck%?2)oSDT@XeUd>&^{Wh)+($+FGmIWNZf8*0*yi z2tVCt#-^Cp`tDICgEh3+r|_)tLbj16 zDj+MgemHRN>nW5SpJa{R!TmfNUXRe`*W3$3B!??KkIyMea!XZ?D1Ku6Cqn{$#DCeP zfa10i@6tMhF{A#W-zGb9=6We}GYfO@&X|NRZ-=^1txV!RjYG-yh};zL=TAxuBGDd& zN_pZr+)-%8=8VPKnF0CUbBlUyr=}WhR$~XOZf3 z%e~jz-lr*_9A77Z68VvGTg^XB?MC^U=5nv4z4OW@_kblhYa*V7mo=)PtkcptJ*QXp z1&;okb&-9oA>7lO3@&AvR+5U2R#+|C_#$GcId5A|u+OXl~KI#1YZ8sdy_I;7%!RVWWi{7J@~l?xSnF+KPwJq56hi}6w6bw8BjEpdQUSvH5%q?Yd?d`@GDh7mG$(V?dKM$)+mY2ACTpWZh9+~TJMD*w4 zsdl;&$N$w>j)x`jygFKKUn{~PwV`xA3CJ3P*+^zCB0-rOhWAsAjig~$A215u(%Gr~ zMMazkO0VrkcvOg+6a^6pa-3&1dL|RoIv3^X^Jq+HSHvmR$5sy^I|3zdglO2LIV#|+ z>Mayl&*i?%yHS7TDpI(5oW&lOwg|~pQg2$zl|ujnsT*O0l2~%gjt;=`oUQ$|1pp0j z27430FT@n4Eqv3jCqSCu#m`&8w5BPiwqUr0HWZ}`TN($zHDePd@*$fMKJ?zIwNBZG?{ z(_*Yl=~2D67o)HPQoIVx=>>0Wnk(r@Dc4TU2-k+$o<*hw<&`cLE{fkXqk>lcTm`Wt zlwNq1*OgZmN}ZWc`g=f-9lly#I4%!<+0x6Fo*Uyhh=WNerqm6N*HbUgjJiAfI@O^Q z;}fS&ov$J#pf|<|24nZZ`(*zS`^zNlXXTAfUG5atZZ}Vbe;YaISCR+D9&!;kr7;gQ zt`<4J_k;-y-1>+kqLO&i-?Z8u?N(0W)a8|*M!o%PXrQrGP13T=Bw&cV|5SE1r%2x9 z@?q53Zgvt;Aj5dGX8R{D&8L`IT%Z;cz$mXHY{g;;-k#MM$NV`EBkx*u00uPIIT-@RwW|jWVol>%Y^?-#_yVP#A-qP>0 zzfB1Rgzg;@dJ93BwkF~Q(4Wo2*>}daKAVFCj|Zs54SQ$O2!_LHyxA@y$||M2Qmq_8 zboZ}cAEi)4?!UyXh>aKl?6>Fx)v2avC#H5T>TS+99-?VXRa4tsS&>u?V_>!#x;)k^ z=)xzbX`|YJf3vs3191^rS2S0euMyZ!OEt`lH5E2qisY_&$9p|rOia$*4=xJ> zkDwjTTpk5x8`mk->}T&_{EKrLLBj}9Z-hD&N(qjOuN{5oWN2Uv0K(klv=W`j$L2+R zIyYN|mc~`ButZaZOs3Hp+zH090^@u!kE!$3aG|gZzbY`1zJAO|bL>ui?8toX364am zH8q|DZHw1u$dx&4_<864&PBKL)>enh&2|@L1Z9j-+=&0)k#dkmLB8@)UY@^fWWt#0 zk1QWF2E+KGN=9+=AdK0ih5h6DLy^m(!I(=p3l_E6s;CYeMr2Q;1(N9lW8?O~je=3uQ4B?GnZ*L&F(Q#l zQi4$mRe~!;{~rm8+1!g~S~G1aQw7^>Vk^aCbnWVD{A&CnO!HBj@!bLR{yQrXsukjq zJ~cTz4t?DIlr2`pu?8OxHSfZGG*A_{_^+} zKqshXT;wk&rpM7_A1%zo2H1v#tSU6IdrQ8Np`wl~Xl*RbJ3PXDS{P>2WdhprgS@L-w5qya{)Z^^84!;B` zBxl*od0X>k&Ginip?}W%jPv-DV{#elspz)Bxqs7VLRh!8mF*epG@d1nil~ydk$7d? zu}a-kq2KQFw?a{QPD#8=MKYx!F*p5e`o%cyA08ldeQqpqai935voQw9lLDX^eFK4* zuJf&%xo)X}bjCuJJL!zJF|D!5A`W9I%oP!8KOJjYZKx3M7+q~v?Z|ca;y_fWqB_i7 zJkXn|WItEzS0;WGDf-wSh;VG3cfd!Adxy~5bq0<|oPwR)QQ0Uw(t}{#OkxQ+glBu4 znJHUG!%inbY&W$pl*u_tG+Y~WKij26c{-DPaCtS8e@}eIePAJBn%@WhCO(-I>`Q(( z3IK~h;L?zVEwSgWY^C-R$43%UZ2#LC4jR=nMVI*L4{Tdn@~7B8I99_h2ptdT64rn zA-+vnCR%|2ModciRrl)l1_P`HTdF#bmFJ|E^N=x89cCvrlAf`hh`&Tcqh`^xZj36Q zpuBLu_}cPuopgv>qpidb1NdU&OchvAj{}vv6V{BJ&2Rcda|uerp>%{yuBI~0K<7;q z{WZ5pt;-E_R0RS+R1#`2PO$HEW? zOdU>%b`Dm~wu6z23HwC)tC0jAJ&n=x{QW5V=j|L1`}WzUnscCt=*VxF-Jh1igNx-c z%5Ww_%EXuPf#Foj!t-RlYu9VYgMC1b4k7C~jY|m*4w6jdnmBy+!9dtR?K>Fq*g&(~R1!h8(abdnQWTu6j9Clv-T3 zb5Uq5B5)$dWGp3=_&3ErA%<$=;Cjg8-ZG#C`Mrev=mX*z=kr+Oq8tO2QY~cka7o4# zlyqA0xflSp?DI~6j%xdLs*oI-)&C${A=Z#w29T4>CU`7UY-Pz4Da$Z8>m@LfhY8ir z36Pa>1eyk1p%6QRyp&2c+&i}O7?8a|p7gT*rpyPtV|3wa3w<%Zq29+o-1LA-gL|*A z|GmS@ZnZ+d}CF=l_sW`__Q=% z&vlO=J}a^zvNi!+xxvDfdD^qNFE4+Y{+h!c>=Re|m1bm8uA9Ft1m29qFNAl)qC zv@oYpvOWOo)uAaTa)75CdEeZpCcHfaUl38?PIWPSKN#JpeV^=+OTZs&e;#xUG7Jg| zF)e7F2^MMm>_HPZ@+1kb9;a<*ufk;A=(4*6Je~*M>Q7(6!e>De`pXsqHnTl?2Zz+`rZ#L-hb)?YHrNL zDsMR6tgU_suy+!sPPxCG^2mpv=(U)tiM8@>|v|R+xuVJUoJhQb76|e z7w>-240T9?Tq{9EoU+i+U?f`Rq!C5nMc-UAI=Mgy^(N5}3|?ONyaIkw^?yPa0sg15 zvUa4Jz2Zf@N{qDKw6ZuZFD=h(B%0A6O$WF;m0#NyHC@l@JIB<#eudtlS>$XR2o71C z%6QJe?$Z;L30sRKOu78+sUcVNHaVIyJM2EilOoXr|@hAuk+Hw?u$ZkCtDl1o$#V=jwi1q zZP2#q|90J8QBSXYP=cWB%+zfN0N73M909Yfo?gq z(y5U`5Fcckx%vc+Q_Z8XC&20Z=JM;d7h36t# z37z~w=CH4;r#wzp&ivO>?AE zn`y1IQF(7?j5meWbPn8zLDz@BlCuIInVo*Z zVg|duY8z*!T96{38%>?Eik?HuzVuby zumeQ3OZ5bE1j8aq*PJ`GwegMu=*q;ja>yIIhKZGrT@f{V1Dn@A68nsYpP$tgSCbN! z!#(4{&j4qxx|YDY6ydh^o&%Il+!2=BxLw1kI%k98fK3bYL#6c+;Ff~~NFxY#sNJt; zIu>!Bp6Gk~4yN#pqHXf!P6c8P@A+Ot%L?5jt(c!cPd+Ev?ELr1IQkplv+*=)n|Z&6 z#c|L6@jvh%tgjMaZ88GTc#5JAaAi@CQ~b~Q-2D~F?&AXU14rucoWhsFM}Efec3=2r zdt7=fsqpuKZ@kr#F7f&`s@t?4MXU#7h>I3dB5LPXMw@@tqP2(8is#9;#;#w~#Vr~% zhSTUjV5d1(7RB>S+-6Ed85jn<`#aYs8|rBts<=#p#pz0w3L)KMqztopguPKG;) z0%{kSXQ>n0a*oE5b^dPL8&V{V_c77D${ef=gnA{}CLhs9G4UX?O|}v!po1!K(5E!_ zCDQykk>yTk&WQ8T-9#BbYODdJSx`2VPSBRiR2StE`B656wr4cx4lumjGZBRGLfaPw zJ%1hEW7Z|SHO=wA#2DY~n7oMSWW40ioXG6)bAne7whEyE8Jc{fvg+y+TBP7@dw)K0 zn_{8F95c~TIzFli2se~|AE)o0p@|#YMBe#H8RLX;uZ+Be%ORji!C^5OMo_togVld{ z8!T<6rnayo#OZKF5*q zcJ?X;&PsEPtG=9x`j{lPdS01|3W{orYhzHtRbKKnd6W|CqM66W(j|aHz|Cy(nRtq; zCNr(J_l-6)rXc4T{YvL)lhQ~RWS>sfXfw}(qj`W$=t2?mHtK!+ogQ*HV+_u|JQ`Tc zB)<%#fnu9YTtv^xn)R^rk4UP6%*4*=%LO{-1~nn-3qZO6i)!@1{CZMs$MGF`z4AEi z)9b(uI3-?%ILznq$M%y2Y6ELHR+hLqtwr0pCb)%7mQ>S zyDloBeb7TMg*&Qi>@~{wY})3Q0(3-Tk5^9v`HAnf&vv9>7a*Xg} zBg^bJei2@UH0ssXg?9XcnuH*u_-5b7t=o~V;s{~{od59%X1%?^$@yXU1G5()?bHYJ z+c|hEHiX@BS^Ns5e9C@%+kRw2TjpoG*}l}zLsP%xpGWb)%lsA=7#qgH_B}Ri%f*yb z{ova5U(du3P@B}oP5>Mr65DK?Y2~L&xhZyc;q7J>!y4mnj%}=x3oBx19!Uv~&wBFI z&>rOj4wnaFoJ6*72Hlj+!ylk&FZ9f^7EKdkF`b$UMRNI`(BVaM_~Vo2gir5^12SwgTYQT`WVCF%79G zVQ-ARJI>cgy=uzc>hElf0BO)8;+h7iC9lq7dIs=eZNz?Rer^*&5%M`&yZ}Z<1N^$?^e45#UI=iT|IaQAjLQ|U`=+n8?cB}Z@t|`06ixi-%ukK)+ zsI@jLgvJ)GXq+LjS?$b4K$s<5#r^^mJRL%9C&BITKp!>MEG=PlX_9fe8rYFljy?|j zLq=PUqXxBr=S}Hb_$Q8DR#`zWSXbOjfP!7!5K|lBHmFNL8oztn%AlVU^#BB0K;5@Z zv|swEDe^ccFcaq37qxT-@OEMICjZOvTO$|KsWtchFmqV{x$(Uv74AG+18BQ=Gy6?N z;rmY~>XXRmoyeF~$ELMx3WZuPNiqWodk`^p!pqKf{R^r8z8SM z@BJ6CH2ivhx{FaMswtEX5r=faUI5+b8qcr z)tsd0^npzsmQO@!3wFWm=Z-tna^mRfxO`nEHY?W6w#8~97#qmy67G0T4I*G~yeh9E^|Z>AUE;JkkR$=d1y|BGm8Wy0Pt z_Id3xeeHI|w!?PvBXx_@_ko0wOPrqaC^e47C3S}Q+xwKSFl%Rljp+mUD9w@0BQjz4 zGr9ZSY4CO(dF}F^tUe*|vL8v+?>PFHzBu&=Q!DbJC_4{Kcr z6=_1hlM}7H7$TeTPRCWL)B9Oj?B61n;uag6)N2VSwqlWoFuM^|(;oK0GH! z=Vf5Aq>4NJf)x_n`-T4Dy`i1QvfZCu<11WU_#~g<()65a8za5)(|ciYrgqce7}J9C zTuLvxBSWPgP7n6gJg8;T?14+W6P@AjR*?%(wqh%Ck>*J4&0uFa+^rMCG;Zh>%J}T% z*wSQdk2?*p^uHmfa(-|8c^ZI0^SOlQH$R8d`JAdQVXvxHy71JvT3GOpElt1A1W^KG z#pZ$NhBV!PR;BYrJM0Ing?p{4f(tjCi;h(zt^2bTjEOs(VRjX#`GMr@&UxcLVh*>< znL3o@Y$r!Ym5BNWR^djX^XC5VKhNm~qKz&PS5;1xEpgw$bv1UDl+2N88Yv_DB@~n+q8F{zRXc9o zCHy7cH5{uqXkU~S^D%l}K1`1pX27faUSXcOb9HDUVlJl@ayCp>VVL~fv#Vpm z=+8yha1d30G!{ojK`}ViN(G0lRq}0kdoX8d#sh?JxFcO~&+EQ#K)$@+qN41a?lF0G zJ8CtU6|fOs7~kD6oM7^D1m>IRraL(vPA4NCyz1yUzBaDDOD;$c)~rv>w7Sc0uB|V# z{HWa`nZm4gb~{e*=^i@uHeVD1zUe-{DVbbN_!@RS&qH+*y|-Qwax@SFb1(+E)kE$> zsAyHRzH*`KunbPzXy{K{`Z(go-Eehpa++lks+oDT9|3<6YE_Q9 zrdLgNYG1b)QBC|%&*(g>N3LjRN)2)3Ugq^RZuYim-=@chTn=ls``PLeW;nV6&xI1! zs!{P!u3)cfgFd0UZ;Ug_m=$^(&|Y$SL2g;^N9c-i)n{de3)5|Uxm*mY>lR{%m z(Jo+}V7KqIYp>&uYCBcp>1ZYviPK{qz3#srNLS38%c?>xvrd8ai z@7dCX0)|c+Rk;kj$)EWHmQru>Br0(&dg1#K>a}UK&&$JKeb7-I zCL8%o6mX{C5snm@p_EUJS1q5V`vaAf0YNc$(o~kOCcv03XP7K!*5O~qasY9n22K5` zFPMTKX^Cf?U{yZC(TuO&F^8$lLnJY1 zKnvbm1^MMQatNPwF;mS~&gdO#kKZ82k)0_EOEdZhun|3dJpAu)@4@u&7i7bbR5bSC!k)sZh4M!knLKq~( zq+bi+j{H$D^ng!9QFZM7x(x6-u3v}cohZf8tNbdJR}yB-;D1GiK@8;%?2ut_X8ge3 zYw}F~`o^-mP%wLK`ns%Fc%z#|w&F}|^uV5{S(AO;oXyB5{t#v5`wW!olBuiCOhUlW_eH;+A zi+-zdD`m^^c^`@zF5R4 z!Wq_TjW|+uOw{OwdHMGiVAaoiy~ufoXr5uM@G>qfcYkhyo@28qnm5At&c& zaCx0VKi!E%k0w3IojJQlKxSx5D(C!W0i*KnFI{SLZw^er1KN%{h>K($ebBe5vg*m- z9ZMae@z9C`u{z%w7szK3s4JC~=x>96H_tHpI<1-77u8W08)5HI{JL!W_6Q)Vk2JNS zf{ARjex`8mU3HnHWznX#8ADPhp}!E+A;K>NMPqU*`#*7@P*Z3G@xysUau!U}g)rPo zX^P~?;*$5;LVh7A_XUanKv2m41wldo2ZG{ALi&ZEK#Zb)A*kx+1@?L9|3FYl#EFWF zuGR`|x+TcsPp?;vA?_Z_t7d*D8JCUWkN6x_1YTpm4wOEt6;S{^DfZ8rXp$`3n_dK| zpb{SclOk2lApxpzx{sGDPArl99dV5RD~l<6HWl9&*wSbw?sCk$(<_z07-u11>4Xtr zeI%@)p@$J^0}``jk}FF7(9f`H>k|1|zETZR+aLSQ4nBt1`?1U=2juMHF%+mZ=QgYg zzKGb0p^g8=-aWJ zl=0h_CTV$v2{#6cH@}j1+wZ*{%;%@!;7kLext=vqyi-tnQd<;W-y^^`hrq1j$^W}c3gtS_I5NHa} z$zQCXUqo4yy2nCj3F{v{U~Tv-^?mJ@&)B&+iT9|hK3ZyAVX!fk20Hukkwv|i3fk(h zPqRL2jXjQrmqo@UJjKUx*%2ylu{8SHe?VS_Of85NsS7kA_QG;eq+MMBr5a*uWj0x2Nfx zpaH#=T!GE6M_sWlcwg8ph+a^4!g{Dh2-#mO{evR6etgo}D9>NJYL9ZD2)s%TQSh?I zMXQ{@;!XNF7uD!S5}ZQt{tk^^CY}k}+SvsAT}*8SGR48#95%l@+V3UnLVUmmzps~z z{!;0Oz2h)Md4+C(64C)d2Sz{=4sPAz2Oy2Etl>S&x6-w4*I)bFQMBYjvT{IzoiLqn z6YEjL=%w?e&fJyFtPWkW>%cQ?+7fjeHc#A@%xDkQ{;p^9n4L8F{h(REo5x&lV1`eV zM}cODwFcA{$aroNK4BJ^sNRCBn1^JD{0EvA=rT|wZ9%zqb5%8HK}Rq{R14kXe`lab z`b!?PQ2xU};SB%p4Ag%aQ1=7>VW47bW8Xu|!~UCr()terh4o(y)C=~1Gf=FC{}?EL z5x@V%K;c-kJkkA62Fkc%T`{?+^Zzvibwlg0_m6>^pNIIzK#|{t-WYugZZ9<_1@D5M z{KhK4a0CV>O&!I)-(5%G)>kO;B*SQoOZ@w<&(#P`@hT~jat>cCAvfJ2aoiwvJpP>k zUo$trYa)DPr0R)nRg(;5^qHVl`qrvcUc#Oy6)uIzV_l>O00n^f0&junL+FFe0?mOG z_cIZ~z$znemKZ3ZcS#0F+bkEQh*A#a3;OU>b*$M-^v-PFh1-?Y`akV73KrL%h?uW1e;A-~9R-SD+BAe?9k~pYrD} zUtPzzz1I!NBN|i!RzOMD2g!ffra9xcvfS{H5ZV&;998I>a*=C^R$WJK$rZJ{A^Z;m z#ZiRx9|p>@;U5Fl$}`dDi1S|z6vylC5}ddh%}>e8|74&J1L}mSvR}oY|BHdz{%;1# zVTM6KfY_Jx;tVbABOz9H+vsUmcQ!Z$&0?0L|U|R>td|>CrYn5*j;mLni z@WO!D}Ps7qs?xc4WIipR@bW8t(&p@ z^1r#^JUn<~P&`E8T*K>|Ya1!MM6XnvIC0d_;i@=`?kSb(UktzB^OeF2CI7=f5!1+@ z_7uuC8ad?NfwPFsWpe9i7e3`SJ$U2PCmbN4?DUnXz;!-`V)Wou@;)1jDf4E=`&^yE zNz11-OsxdA^YpA)TE!}E+yfYRKw#CnEGh1fjhb4^1JP6+O_n~HF=gsl; z?#HfVoi1Y8Y~!=tvI*Lpcw#rRI%_L8J=0$<4_qg@R@4CCDUB;?^xhg}C=98qnmMhp zXseoCMb1`qsuuT+D3b(L7?a1u`i-mmuF)bAooGVsQ$$duB$0Y?tBqvEhc$ZVi%|v9 zyM(%zo}Xc>p%sg@swgI*siML*$|0()Wm&}WR;!kwt|BYjcB;`WMXD`H+N#tH#UN0? zQuXu5@2p7N2?Yu^Qh-EKEJ_I>7RY>e1dBEQ!A&cmV*Re zuP3r0yM^en=UK~hPXFRZ_701$WLC4uomtf#8|nQ$f=G*^p_W@*@Yi%IK8@AY^hszA zAER+wK{3v(n7$P+9?>&7yh5y-w1Ug^t!A#3P`>(3_knF}*O6WBtgCK02XH;5KOQDK z6nukMSGwi^r!f?@pG~m?la-*iQ4qpUve=GwF1MLDw7XmqvAJA&ZxM!WP3^{OCWTql z$-8I!4_cWIbz-Eusn7>oN3#?986)DFG+sg_HpvuNh-3vdo^wD@+i~dg;ur?wenCSyP`9|BNA=j-}84yFJ6s_SY@|5+VAfnjIdz3zTbb*F|F=Nnh!h(tC9Mf4`x^Gw6(x1|F{)zxcss_eDK_)^s@-ZF6EcU znET`d=8nF6GcJd}fcaGE#BEa#jPp+hPfShT6bB#wAx*SHKn$JwTQwuPUO-q`Kg#&D;8$IwFUxd}3WE4xg6KQkRxK z>pw?w%gll@5*djsFYOa6=rb_m&a`vv_vR;yv$=)*fej4Q8$I^q3`El?Ez0jZ}rZ&=&t|beE0BmEqhpEeDOZj3yKM3+qQc3|1k2H|4%xW znUR^D?fkaC6hc@{XBpDJd-=9dp6bC*1s0cjAd! ze7}_OsJT_yZ~NGAoi1~g%e$%53k2XdCc6_O`OO|^$wa<}bS8e9%~qu{C6dJf5nZG- zr{^`Vjbr3Qe|nwf_$;i8^An>mdkubiHJ@O6Im4d!zfm$iw4hs^e~!>Fus#gDB;E*k zOyqn%-+3Qt(C4`seSd`*#OHF@-18QHCxP(xxlTl-zI~#W^yzf^>i6>7kq-k5J~ws( za(qI2eeThU@Wpf`dP$y-^o@yQEK8zfNksjX>4~8qK06Px?l*Je;q%U`e#*IQ(cAg% zthB%&zFl9gSo}A(T;jy1-A(C=`1=AsWQUp#$0cJwTi(i}*^~wuaDSGs2~|oSYAXd@ zZ=00~nh<_V`Ef6bE#N6upvWrlv4X9P}U4$f|t7cVJXzIj6*tK?3^+0%$;&)vP4`UFMU56PKql!$5 zRVJDsWQ3AKBkMd`*UqZiX^=^RO3e_R&_$kclW7^+ufw-D;{wp#Cs2Nb;jz{=1ncD9 zT)+(}nB*t?r-q~es9u8R_z5&y0s@y|I7l4Cf3*~PMHe#rxch?KMOY6X9^ofcgM@=* zL1HJo5`IM=80HtOX?)=tjmQ{+gN*5k*EG2;)VU>cZ}b4}ncA6gYwmN0t*YK33UpP& zk05^x6v%<#?Y*D}c#p;V1u9WZvoc;_RffQluqjJPGzGNCK)Wt8M7TF9w2v+>#14Hl za!7*zE+li8w1H#-Ko8nLIwbl-au0%n zvTSbt{_EPvhgXTTu+I;`03hF+40|*SL_e_siX;up0+7$AB%__a&;Z5~PARbM``iP3 z*vfELXmvDK@j5bm3tNsHo1sWC#C5`!f|&7)DEs7~sn^D2crL~Gyhm6M(3YH&+~euQ z|3Z5W$=?Sn^01*mW9}*0j!Xq3*oWCmGV(gF)6+)BWA#Uhh4W~HVU)%&Orh_m)Dtvy2mVPS7@#k{ zx`~T|j#<<5?o<$K@uRQ{NNZClx<;4>c(r^vZ}^kh)t6seEC5*T;^zUz8+A(ni!(!5 zF`gBkfW+D*kd`mBjc-&t1EEco7Cxy>87rR{_{A>G?n6~Yyd?2NTfEuGxRLfeUf8X% zkps*HPDg(Dyat$i{E(dS^9ocNCTfUiFYTt*qJi;z))McDJC(J^Klfg;Lyt!!pjaqR zyz^&XyhmQVv!Q>0jmU*L2HPRIK+#%d=Hs(PuY`3&=L7$>AasZWlIlW^!vd;!8sUlD z7A>~=e{ScUYdpQD8{n8d@J>WuSlpmmlta3pE<22N8L>sYf9ucSvv2N-=57nPecktg zXoPKVz*(0ofkbKK&)-?TH&JSd-dRZWCg<)>*pZJiGsLSUp~@2F&Zt3r112>-Ic_B# z%oEh!M#>D^)WxfuJd?jT^015l##|@(VqP2p!jIrZ@#9$~TZ%i&rt~uQd5Rr(TS%|& zoTl_*UlB{Ziixb^Ar3B9=pnAskA(4X6JZ#EM&>-a^X$|3U z!<^ZJGZ?MSk64qa60$Uxj*wcYmiWS1XX4D_WaV9zE{D&t$e4o6dF4v1CL^ZzTvgJk zIH*`Cw^NwpIGep-N;%pJScg_!m6%IAqE9>**!E*AOdsKeD?hSu26^fFPQudAk?(4) zAz3}cIxfZI-#L`BDQ$65zu!<^v1B0@#WFXu$T=+V8LTH%T?jRn7gOG@kJe)Th2Qab zS2!)hzYFkMS?v(P74Ndi9~>_>DACc$>A7ZANEkl_C?a46gFa7dW_a--vtZyn-!Na0 zISE{(K7c;cq9>s~C!t4IP^joTOhqk@D(Ofg6~+mOt4DCtd^Vz7b|;DEk`gc9wFnQIA9@hK5Ossz%NyR1j#}y?k9f!1{Yx8ZVGP}Wh(NV zVcd4!ymnbrd}e#d?IBbj-(r*8e5`bV-%pvm{@Z)N9o%9U$0OYm{~DuUbzn+Hq9b7n z;N70IRo}DG;oM;!ET_XGPw=qhb@cM2C`pwYPP3m_Lm^>?2aWsd7yg1b%kaDGm5d@v z?@i|SRQTu+&w1G=8QjRtFl3Ux*LT#TRDsg~<)H%@Kc%)8e?Byc{9{wVhfwNh48IL( zdTll{T5>is97;Kd15>8r2748lnTYq4ZQE#_Zo85vGIaP|RFZ2qF+=sK8M;jGLEk}; zB}x<%HxHpDZ*%I!h%1@a03Z3yiMMkE^D*&cLO8I5=T=m(LZ zaSEcVkC=m|mp}ew{K%v)byb~Y@>A3f(Yc>)7D8IYux71na4Qv$6e3XxuXK=el;F>V z-)|s3(ibszp&OvSSrq^prk(~rVpAlq7)C<*IQ;`IUq}~wGG0ltBa$U*N4T!Ezl6Gp zR(4#{!ZPi9lx5 zDt{D@K>2R-)P0Yzw-SCXj!+I}diI-TvOr?IRfPJ&y({+RP+G%B$v-`V12E=6uN8RT z3!?CYXxWmxzK(w`^ak}-p`Egw?qV#id}Qy;@J8ZRP|nmD^c~hKCSXRgF6++mA^M*C zneo|ah3@T#t|e}fW=48-B-0L{=|JGy6apl8+evY(r9k=`b{V4hkZvzrAsNqGr-$#a!#$n_0i|7V2*;?F~C`WJ&UjU=k;MeAd-U?5@{A>N0qx$8zMwkU??wGu|#7rrS zMYAX2n4^^^`u7IQkK6NR%+mJrcFX2qG0|)VV~{mScKqGuHQqMZ!8N*?dPDTZxizXCig=S@i%v%gIfI&gt>Yb;>scnWCjTmf@ppzkIT@l3BA+k<2G8r*QB!kuszkqrK-x^ zN7ftE+ok?fJ4C0+d`+polzfq^w?=*Gqm$t&Qm*`zd(6&sT4`NLx+Sbr^-C@hqUDJt z-3VLP%9Yx2Bt5@$&A>f3+!bHs?|$zuYNmh&a+QNHlm&@wh2G-rp)fOA0$YBBcj*fgallq!<# z0^8-+#hCk~EOhkR()onTnYVvA`!j7wVG|ncfA~yKGah3#srzTklEZblb#VONKHh8a zNLokKd?`-f-GeKa+%6&KiL;xCO-n24BS?(wkZ@75CVO-_O}anQdT5X$YL>N{b_(l_ z`_>meX_V?nUF^R46*DA<35Hkf#{W9!_C8*z5_SnUBwt6sU1EP%0Nl#9^7WyXyWGyK zw@}_qn@TH}GHkMNP$bET3j698y7Mbu$At^eJ$uENy)ufHNtzl5rFhdgQ&mS?o=l#r zlwpp-ywGqJ3d}AOGfMoYNuGT4Hak?NucET}WWBGd5{K>ikgXEEn&R1y#w0dU)BL4E zv?f|Ue+~9EOer!=^Q0hf4BE3N5HIl1X$#Q?cA5ZfYQ9a=#Qdr1%?4*v{JFM7$96R_ zGV!s-k7feB8m<6NaWr4EGxR-N379e9Fo7;61Mke3JOy(l1B%>{2A_ls$6{tiHe+pz zlNvX^{i$|(KG6lanI%L<+Da)j2DN^of`om`4iEKVpJ%|{DJ?#HrtNd2#?a!%Xnzo9eYgAdg{Jx8@CnKd+}In6 zw)P$D)>KmQ=4#w%^wDiyK{C;G*2l>i>Upg00t+8_y3wo(t1N?tNcp7i^f%mE7lI1y$EGF zcP%RlDvq!sJwdg@C4T^USFgJ;jvQ8oduP$W9tVxNu1Oy2Pd1`eM)=WrVdtqO8eZV9=5lW1y1DZ=97hDxm>*F%RHj7&JrXQ_Wm3{ z@E&?E9f_id9%>$LwDGR8%e{%s{+We9Jq)w)qEumQ(t>75af%2fb6QDA@TnHmwQsXH zBK=nVz3kE@Yi?LdS=hLMReOy}V&6D==#}->XMZt?ci<6ubh`PlJq{~%iet^n!}5gj zX23evt8Sh3D{Y8yya@A90&{kEIS65Fwl}qSfaPx;UT#FJ{$`uIx<;L!J8>D=>W$&Q*N|0uJJ5C( z#B!SU$9G5br%v>kHD7Mfqk-`VI;c+b1N7XwOx_+Z2wB`lHkB+MOf!;A@fKUEk=7GD zCSg~lNlz+mf@xJtPM=zbA#o&$$Bhy;&0Vg>Wb)1wu}@y5AwPP#`ua5stQ3zg9zcn}64Or93Z`blOd_7U8{F5jky)0N>A z@W_!=brZiZ-SEKeYg^W!B*ckZ4n9IB#0hH384%kz+QBVW-+iuh!y2jb^MPIWfd9pD zRG^xy`-MB`^Jjo6PEj6`djcxi5JQG+Thioc+82s}jUSd9=4X7KL-h*ms|x{k^erB& z674-1k2^j2PlLk|IlfcvzxWfPCtLwjEP9x5A~+18_dq_500sqPNT+dRC}ruSdAiB@ zS$@iDLMuyBzX_>?n0FzDN^-W6G+06qCp$!}n2Z4E`&{TZa{)FXeXG*HESWtde6Vr{ zF2|_HLT-ugv6VAV4Q3H5W`5J^Rtj9^ob7+6>$+N~ZqV`;^4fyZd-OuvUuT~=-hQw+ zF}KjFU<^Tw{yzcOhs?DBAF}y>1cDD?pL3+g;3BRnXIL>azuPX8UZk z;P;RXF^V%P>J=98+Lk=cMk%rt6t@PeanCbM8A2w9VNlza?EnbzOUKLouZ;ok+C0`f zO`eKp+!A{Qy&r!z5Nqh3s!H3vexXed1#Kq9uW{xLZALIli=9ti2Kfgs0tt{ayMrY=5O})X zYH0ptDn71m|NF0Em%wfkY>!r`zYKmLHB601cm;HF&D5>C;u7f%T_Jn~Q4O zI}`A0EYr0!VO8;c?cLTz@$H?0_qUJ(`IEM$CFcqJstNPirm2y25ABMIn)p<;B#04H z%ay;2zis;d1e_;7!2_DB37Yta<+wKmydskwFeT>5#0 zvfHj%-aC*piDRp{UTMy2estHpF+pue3Oi=F?J$IgLX=Cy(jPwlB`zB$1 z@)6T63=gd+v=QAJX=@CfDxC(ApVBzC%gNCopU3VG{8v7YM7pSTO0Ga`*_^pV$g<-|132Fh}38Y)9j_>U)g7va>eIOhvDgS^yQNcOb_NL5$}CseM(T%d{XVVAv!j1ymG6-n zO8~dv^q-4k&jNX=vMVJ2@a@UVbuN9>2W^0&nUYhCb5r#FWyTUo5Clx%U$8rs@(fcD zMXw1WygA_IEPU?ZrBEip+GoD!Ls9dqfgy3FES7M5S~9+8LgaZ_KfTm0_$OID@SZ&+ zwj0k@1nm~|9ZV|a>gzZ^a%}9mi@)M8oBB#A47grf z$`<-M7(VdzeATUwo`_WJ_0s*M*Vmg&cC_M`Q}{OhXVcog7fIW1uNuqg&s|)LC-^-V z&ZIB~?nEZmI~Y>b_OQf`>NigsLd9a-kKtV(n1p`d&sexnNmk;x8nkO@ttm7xYAHOZ z6eJON+$D44(s6wzzKa4-J96`gJ(Lnv3)8x2h#Su^$5?N%LYIObQ^my6J?mb!$hObB zX__MWhuJ%JU7agQOT1bWrnT%Oyzq9`YhUQzD9%k3vQV2%zH9nmZ|L&4;ndu}Dh8xZ%pVi#U_9Uk4&!{2Ghu zafSYpXnDd6ApYcsDj z>sp$w?^joO82B^h1lej|%l+T62K*0iFKAmDXTXl&y#hug?H8d{%C_v;vZ6^`nL2bM z?8fX)SCosqtz}e;R!lb212sh9wr}xcF-zAB6D#~rvLL@f-P%^;(Lgu30e9a|_d-)k zR3%^@-H1;VgCNf5jUOdXjU1)bsksVfIC<0Dc?YU3P=0^F{TdQ*o?6a^u2=1X<{(WWkj#Hd-_-e!aesW?{0s+Y_f(W5K`@*a0;&aRxit(!2(g*kgGRU$Z1mBnh!qRF1jVe(X z)#%bHW)sSg(`Oo5ILU(JA7DeM)eK{fK)29gPlxWS$)uS*q1Isy| zvVjp}*0n*w#{Bc1j1m#Tgw`ciuFzhy3`l=;p+fMueWYd3%ZjL6ki|z$ z`;|~B_%(!ZQ+vReP@Ku6ndM2?4cq?4R;(e%Co4lGt|fwmiKJA{AyCZY{gKx`4=nk> z*cv+J$Q|zI|MPkKJZ?xBytR04doQ=%gY%QNJ>QWk@96+i+FrswX5nDqJmZ2f3{hWp zbuxtjX9B0NnCCa8aaCaPbxqe<^q5n(`>eCU?|!gy_}A8x=tJbAMrb+q%@Y#0R8(=uV<2dH<+&bMC;mdg0%5^>L0xzsme zWz`+RjWJt@&X>B@^X#W>@_0d^CQq;rg)?qW^XiHTB9@Dsa|2ff?_oYou+vTJb`fGV zx^i;PB)I2`;MoR(MGi`vF5z4DyLVA%( z3F9`Kl(1E@Le=f?{2l5gY^~xO?fHpmFHDP~i;~e%v8;&5mHPYh)+UqQX3f8JLmS*t zp3-0ws|`=`0%xj4MDK?c|Kv%2-j7Nq3F?Etc4~mXik}%_#*%bmnjxdm9DzLOocTMP z>KLtFScY@{-DtA)@>9^)l`dxjhs!~=+3LzWEJAu8FD-JeemGk##B5<{;fFtGmjj5z5B~% z9`(vOdqHL(Xj(p82a&lG0SM$NR)3bLE4(=Cph?D&*~~n8Mrs<}ytUGI%NBb~9A~)X zx;ss7sKJk(RR<`{9A+Q)%{9Gv+(@AYO zDZ&hihM3)jTJny|D9A2|%+dewsFCPVCloiLbXXC}aR|XX<Bj{$@)p05pxKF zu*N_rW9rJxsJVO6zxHbmQ~IM4prWTtz;#~X$}VFuS&fUqt-&+RUY2o*3zB=NmCQO> zl0C*P&ROfxz*D*@+n&iG6`!Sw;KG&rg?gffYTm|!`-RFP*zA{NgS=8`nlbb5O9t=Y zd5BFzXsg!--*j`b9WneypGf2YQ}y_Ggtt7Ck@xtHr<9ZXhDQ+12AzFI2<+z(9Lv(-k11-d*bBd}OU zV{{}Rd2L-bGfblWduiWae+(nI&R8#tFXz8*u8S|Hy<36R|7J=D4aPO`K{jjvd07oM z)U6@Ak(Xl>2A(1~FaT+q28sc}aJ>$t4Ss$)A*BR>o*P2jP#OqTeB`B*wmp`bXvwan zKA>gP0E(}5ne#z9PC$;~)`W+S(ENnQ#d@;-;sC;jnrbHWvv<+c2p%0gde2fmzXdZ! zqFi5IgYNzLmTOpbX6MT~Ezo6O=3r%Ea*=v>0w|V(Mv{)G+O(imm?GSCg$`oi0~_gq zI7vnEfDEAGfcF|0`G8)bB7oUVp<6K)h&7_-3aQP<4e)A~zSi)dI^O#oWt@^qD zu!E$Q36k7fXTt0Xmt&PAW?5r?V5(v>hu0N?7?c+0pH18Ewo-JtEah7*Y~C*1i5cvC zreAGdp><~LeCPu9Uj!!Yw*VI0Uwuux7BBPK*gMj8eKY>%mMqQ)4V%C+PT~4ob3Nlz zSuNzZnH!n<>*fsL;Y8m+7?Y9f$;=>yftT2~5Smu{y)5CzL{WW;{r3TN27SoRKWgF# zd4FP{8jW+>WMSb6GW6xNCD9O9L#&lyN8&~f?JKBs?a;NME?uV9TpX<4$UmIj;d+kN zKeQEY1Ka@IX5~vP4j%^=O?-R`(yrTREOpebj?=#tk{;j~A$%_Hn0nmIq3Qn)^cM)5 zNB28`Jd|-<$W@?88w7B(saC!qNafb$+z7C(RLRP*mZwpsOJdMmmbgvU-YI!U@DlY% z?L7I3^FIclLyD!aRw{;3J6Ai)?6oatQ*oVFORl_MD3^oF$Fhp!pvYBPotVEY51uEU zi!Bvd49`+(73Apsp>&hF7#)wTeED@-9@GXz2U>gy`S&+PcOe4&-w9xc0%5G8aoLAd znX(7feu!k^8Wy6^dsrpu=x9A;mUQ%N+Co*Kz{>)#o(!11z!X!odplI0}R*?;%68Ri?9+^%(N6E|p79C=l48%S)iZA@)Ujaoy35Unvg z`gkD+vC&FVoSoy2DRDE#Z`sG42P>OB2xu_Wcirwl{5&ZG)@QIbUYR9cAHDf^TVA2| z-gwp(EMLFgSY~rP9BjPZw#h8qm#}VoMNV%%O#u5I?PdauC;A+n!C)U_;}3Q5@u;S)fuaWRp5Amn_O%vC=Siy+1|F#TgYZxa}t zT1-gv@A*g=IVjiBKPh5&ZngJrW2FAm&Gv11$t65L+j|Gg?@*3l>7%~GZtEJs{DX>T z?B}h>XNOukEsjT^D+bW#y=|CXdFoqfJ}+i+Vj$E1YH`$?@B<&)ML@GWbt36y-7SRbSrm|s7*?jHXZ#7{|!%$Ra-JyLRLvW-9YC?=b8h|!swcItvNMbGGBi# zqD|P8wzgg3+URju{!P(O?H+N;zHA#j=yu)V$a@G;A(E*=kV9IeI7+PkDBp{ih$y}l z+rJ#7&3WQ_M^7iSQoa{@<*LDPe?90;J21{CUH)Wc{ZJQ~IF+JF@d(gc5jwvnN9#A*9>`y&P>tnZK&5=Lae@L0Lx{!??C#iQ39UaK z`1V2(zg+w3=UUqfy?(JME&-Qw6o`j^#0QRD;4yj$MHJIc|B4yi3k3^~!n%SUy-?Fm z8~mQ=|IOAv*?rtJfB7=uZ$x(T$;@_WH8w3^&~|h`fnp9jlgHyUz?B~G(ghLFt-gNl zebG4m|7owAEFhdMd(p+r=jzjk^B?Q!4@Ma_(Lf`Ri{kRP`9(a4Z;ky)^nZ<7!1UDnIR5CH2r; zp({DtVqvr6pa!{$IrH8{!_0U2J8__VOlpF^U$0F;Ni_+H4Ua9x)m|UD0?}o)Yl$~q<7T}}KyL|*Tj%%;cU0OnIlKRrgHpjTYQ$(HvkxO9>OeM`q6Cs=h}r=SZ_`S~k-X zCcRMnt0y`aHe*Zz;fzN2sY8B^-$gy-Fz>c!OcgaL2nxT?$-A1y&34d2>YeRKO zf7a8|?T^hHR?P+x%_RekKe*t0RAYG<-rxdXFQ1)Y+H~xF?Ck+(H~|yiEl(Xx3VMK5 zceB$*Is(&pK2H)iU#eJv)kd4mtJC2fGTUTPtXQU|MWe8?dLLBiN9gpk8qvlKw8@kz z1a}*PEBC+4hSNBK6<;5r&x_Qd>Iu$NR<%tp&F$;;ECv=@4!3OtO`FC5D0kbJ&FSeq zPz9X|yh#@P^?5=-rephxabzYM1FQyP>~O|`nQY^pn!#wzy!dJ6IWIU8a#{LACzSby zy?#6k&%XtV15Xc~nK3({0czlKDHk^x%tA(A1;6VwI#WfWe$lzksO#XMqt=DeZz5P9 z5Cy_n_9lb`K{TR_y3Kq7Fm}I~S>+g7Cg2YSWj__dM?n1V1@II{iO_`(hs(iMCJSBR zQKc#NcX$ib5h+Dy(m2`sL*TVU*6;EJ`s5jSsI(W;>wFp^PI8MK+8KK8ggX$Xd2_h- zj;^Wcb>?55R0)!tU+znOxtSJp&9X2$Qez$RudtBM%g#D-_{>6DdSu)>9z!VCFIZA$ z(ATJ0Ul*q+0m=rcCQ&~!LtRok0Aisusi^=NXgz77c6HCaudATGI80Y28~*{m%Zowp zM$#ejf-J^Y^$b^9`0^>U@cgp!`BMZ?Lg`h9P!XS)a`*V`^7kj z!|-+7hYyhrN0?kmjz`@bot533>wld5%Ab5F8*49(A4hTh5Z8)N zs8;1M>^XG8Bp(!IG;X46@dM}}Phhs81mTI3JVRsxHnAffWdfGMezb%ej;s;$rx>x6RKBj*ip+< zp;%uU3vC;>YLkNJ?Oz!KZyUGEF4kT%%6lx>bq<*~k43Or@pefiT(RTffPqRHUsYVN zHEzLc-a=)t+f@ zWD}Lc5-6h$g1TVcq;vPOxM8Hl2(Kix>fKN#BGaZ#_%#E`+(yt2+L2m#{K|~$@guuq z&)#ynQg7ued>GMed6b-2zHV$~>;6=lUZ<(RL9n^;s59?*b4bg()Ep4rgDngh`Y0~> zdvkJpKd1Kg_E|fz!BOmZtO>^d5vR@~FO7##;>hT(8GHEsA{9Nnl=uu%?a4`1wSQTI zlajaOU^z-%!e&HxEGVkY-v;k5pkvCz zQ+->X?a#u!$p&A=s+3u6Rm-XY-V3-nKx;AlIZ~AiCx?TJgVROcEZC*_QK$R}lmd}n z+5n0QZAWHJJgdlhL_AO?U|6yry|=oMan+bBh+} z1~?)KR(Q#WTmAS)t5Fg|YKLkV%*TQkFfMv=VA4xRccDBT8iVjo0=;zCT4ranECm%E zn#{9|ojjGBrdbFrgwkv6weF70^Ql>9F{jdIeO*_aT}`pud>Z`a&>PCvgrJn#IlWu_ zWRZ37q$;C=Z3ErumLEOELr*e8rrA#&&ZTvKU<&&y{g}wvMe5BgEMn+T27OJVz+rBHrRi4os^Ww9d~vvS9$q` znqOt|VqY!#8cfBX55OJ?B+>NP+@4VW#&kL7{5^+EC9gew=Ib!iGF*R_d#_oN@4TB| zu#v}?6`+i_JT|G8x8ia6oWKAot_Kr$xvUV6a$NkduUgY9odhaXQo=6Eq>L8d$3VtH z(!$mwPzy(0{{V|2ps3LcB!AGsEH3EHR#wF4O_va+_Wmqlnn)K z*#DD*JhJ%eApi^xJs#@`rZB-|#JQISdJ|d|Dh~b=M0FoBL||XWnDLL<)I^i#FJ$5;aLi%W zBuc8}0(KxISO(gSmxbA59dif$GK;>Cq2_4K>*Z_>zPG!#>bzn8EddAYfF&B5rd{*h z&h(u&n~UczgYAz4`x;RcXNZ#EJq;pmJ_epu?s`Y1^wCTn@Ntt+;klg&s2qb^)|(-Z%;1?pB^};~G?A2~J~TmSRq1Wjg5cal_thRToQHH_C6ShF!=z~w`CHcOnZ3)I8j!_ax~l-RD& z)lDaLt((Ai2s-3K6WA+rPCS%3osBg_!}GvU;!2 z!fK2i$@+VNo^W)f%j6Wjj<@f-BA5K1OP#q$HgndKD-uOg-nui@FCv;`JSmACNV7W&52l=?1p%dyyT95tl<+krXI(6tV7%}iwlh2{4=9+aTv04xHw*;z2NLXQZk)_u%wdB z)a8~Q`>GB%kL<2(xWyw*BgBf$Au0%SW?Jo>iB7dRA$y?)%24A`iLL7+lDJQfAZg&w zg804WL;Z8AZLqmN@v>aW)8&@kQp{*DDJZ@hs?!?i$%OoIXm&6b-9keN?Yl1 zeC{~ioZgY^YMvddIUxlML-NmKZYf6~9Q9$%ZDlbna4qJ zt!)&pCLT5Ty3dnfZukEkz@ih^>J<(Yl|shM@;p-VyCsC31LhJ8f5si> z*5>cVMdxDnO2%pD4(4mdLoY%@CDsxH!-hKP!*>M+#@MtcFq~@tvRlh89XSqL2ep44 z;+pt$XmL~kAHt_wc-sI|Zq*Mxz4a=d0N>Fex={z#50?O)tbMDr@kUdHLK=#`U3{L23j3LY(Xnw{5$Jp3_F~T$6a2h8~LW5BHP^Vm8s!@Dn#t znpQ+IJ}{=A!U=A{>E142omUEzoMc`wYsdt{-@!IsRplfL8_yx&Zt~6I^pcY_0$BvETfv~SP zdq!(U1!@E#G{6{R`%|6`v$2h#Byk!p)#%CAVId_0pmJMPG%=5Pj>W$(xz0?v*e}7C z9Tg1k*f5(I7ehnYLZLjy!r;IPtJQP)NqGNwFIMpRlyt4q>8SF&!_M`rF4#5y#pA(2 zWg_NLdWS|;f~{X5^Uj_r^Q5tpx;<|bueYXxMpxTV-kB85wJUgG-L$-ARcW^Cy{5Pn zfXSsGqn-*Q3ro$_Z|ik7DYY{6HOvp2TxeUkALUm$Pee{*WKD+bq=h3x>|R~pK(1vX2mZ_F zOZD;cn?0b*pl&#!xiWR|c8*~!D}fSB=Mkpu1VX&IlJaZP(54%`WJbRYd@sWvn}YgB z8bdBA$?}~3FaBSNx*VCfPHf%7#(AhHr{CfGl7dhHSu&bcxp0zQ0VDg~0D^u055k;0b*%?*-G( zE#JXBlzJW#AB~{`R~>gyl?Q!Y9zB51=sB0@32ROmm;b@oHw9@HEZw$k+qP}nwr#t= zwx(@N+qP}Hr!j5Y=ACmME+YPi8~LzvuN|?Yo+>IUSFYtK#Q3`<&auL%r;C|{gl1s(WV(pK83Cp<9kfI$iqS-=BY&7PB@5 z4K{hd+L?`rm(#@@iDB0pqvF-;q|)H^_K&!LsP_c~wkn?}2$F{ZbP#I2V8~m~alm_M zD*MmJ7~61`@*{)O+HTd>YKZs|@;R<2LD&pwM=`j-Md$^VhJ9FuODD+0m-8x+5BFLS(&oysWv0AvC>R5wO6z>oMMfkVEinR=nx^D*0biV8$=TaRR zk&bYEA=Q-QCKMdOF2AeP9!jwQ>UvF{Irg|O({|%_<3dt{o3213USmcixsA4sb(`Hd=2g=n-Jf!BmNaPH z)OtQWgpcrGRK!Z^3MB84ZspnWt$P9Ot2D%kU*pW)j4q9K;EQj6 zJWCYSmq=;k%c)ft^~w-h*|#lW89@A{GCLbeTexp?3%F=&vGStatJfXl+xel0EH^@Vth zjomR@=Ji*!pR%XvIyVdx?$shCZ%bM9p#Jh7m+nr{yn0nrWQXli^v;&p3uF3j5?9lzUQ$>;uoGaa3*F) zQrU4G*Y4zac6)a?gb=HF5;eXq-Z+x>qHVn=K>Mkli)d!^{C>+(*JdErejz0Z*!g@) zt5?Ral@3qK3nwAUA$uDr0AmM6Jv%V8z+BWPw7BU5ff%y1rs%4)WQZ}y;ZHs|Qjdgy z*7`Q5cVzlw$$TV#B=zfUrXiFZDNdV=S{Y9n_HEI+&<4cPvf4M<&ELf|iQKr( zgJShyI+>0Qb&mr$4D^^P?vDebrSLf6{8tWq2ezaQrxuWjapWNTP+6EQwYT-}*7Ii} z7ypd#k%Pf8LQIT!(Qn+XnSV)@uohJY)eKII5|##>JI#G~80}`*$=)i3EsAt!I^dZD z1!H8d;cj>8lfaZip;*wkhD1O(@RRz@n!DOJjEQQE9QlF{I*p?1G)(uvPbY2)F$2gr z;&eT5^97GwFuOV73>m_Aji@~VN?I9-c|3J$zXukDgGj}oi&u_6Zg3l%nz7I{0Jb9q z%9e-3R2$`fKMHpFYbBme&)xU&Uh~@5&(>tLzNGKMF4y-xRrGMV=D=dsVY|cIR}s7G zWiwOM!N2^((< z>g@#DC>gQ(TBuskXZ&dB#($p3IX@u2Ezkoa60S~-*b(+nTmV;SQYWhZGzbm|mY{0@ zUcYyhNM8O7>2HVEeUsWB!Qe3AU_n?6Bw^w3a3kZj##dUtJ`A-4>oj z)}VF^himrn04LMH{@@Y8`@#S00XD|U%QDI;=#O2O!7W^CIEGn=If>@W*}b#;VuP?J z;ikxHR+i4Q(X^`RTBlbqd@(+bAsF(*Fw~uMsErS1d`iFctaDlBd}_DOiJo$*>Z<2%qSsOxncR(Ge;%o|zOS#&e)6W=z5X)&xqgi^pDmx(@;QNwhguF8cb2f z;C!T*f7k3-t-jk(+RA5bB25izvHcm#rK)78X24NyW@{C&AlN5F5ts?oX&><`^$!n} z@G9_5^bcxX>!aGl|EPKi>4z-n!?=05X57Y{8u5eXt|@_q92aG~e6d|>nX?OIoV4L+ zLzO^qAkpw=LPoW$cdJXa(b(Du@1f-=$Gm-&h_2mvn}|-Xa14G>5{wh0)pUr6j?b*0BxsTiD@-^e z_mskj$pkAj&>kWDaqcYfL8o_Xq-FrTM-F`q23vD;a&r;7^6z;>_$Eu>%y!sGpxeY_ zwt|abeI>BVw;?V&up(VNq0`dwj z*o)TLw=ugMePm zci2;X2sx|!>4ue^ zT;JoUF5?~gHICd&Oa?lqw>F`Ux)6IN#i5QjS-|p@op(vK&Zb4o`aYGDE}j^RYBmwH zNlVHh^6Q^I2w%NFAHtq_`2&ONiq)c&QfMF%QG0uKP;Uo(rattC!BE!(DjC7;iex*z;z{?p$^>!PpZPl6?WYnAL| z3rPk<3$Q8AAcY8)#DxfuV)zJ=Ja|;WX$8K~7p2)#Ngh>r(IqhEf2GBVd)Jjwst-d5 z;W@y@AT1#{Az#4MHJNbqP(G=sBttmCwQmtKvPE{o>d(#-#h?6@ z>zD1G-v1T0whEr~C6qH%JZ+Ka;xO_F(XSd+O8sxl1XjyA;uyE$a&b9kF@q zHdSv|>Vpi_hq}EWLlV$7!gvRs5T>8C`AT>pgSEKB9QF|v%^+_jsOnE`r4YDZ0HR~EZkn`V=ZLmmV9{%^7Jbux=zEZHow=vDCdTp2f2pFPpV8KZc9gv=MH|im z{<;qk8NVK9kD0%U59wSY!-^tV$&H(=F%GAHEWyeeibh;?$};pg3Ej6bZgU5`?nY-* z8a_vyUH|eQ36{lt_fy}i^4t=zABai6@{Y*G({A?LE>A`cGJC4fjKg(R_Ga^+BtHS8 zn8{$HLZ+svPx}Mc=QjEXZ^<`t*39;TU!`Y@O3~5Z;$Xl&O zA~2KWq21sn%aN`D!f78tXpD5@2o*9bUlUPxhf&wk#=)M;l1vm{?2>OCZ zrherNnFd0QsWm(f`YZTmR@I!jEzV(XE(19Ldm@5R%3|gE{^R8s2!3o%R@H5H+Up8; zcE5hZZ`6Au)^lH!pKV^kU-$&@wz3S5ozmPk`hQ~TpS|Lfg*G$@xmq@W5PG5r7O#4B zx153K*f89#TL;aBe}Qs_M=if50SjtUiil|5!P1Z1?8)IiA9bsS8Cp?~6LM7N1~3wW zA3kU(_9<~C3J(4@S*hR_yn0ssX-CQ{5~Kfv@iqVgXrX|J-BDnAJG|#}(YW@l)f^gBYX@8t) zBEYL#=dr(jpit;`wmRYeT}DSBXawF>VtE1oH71wiw}hhs*+fL1L2?FUF(%VDc@y)2 z&f1WrUP<6tL3eaordFc(Sbey!{dxurLr#9pLwj}>qMEp`4;Qc1ewG=aMej_?bPi>2jZNwk;t3hGNF|#=%o8EG% zX&vMNWGd_s#0R)*+^^sW`^1j(R=E?k?@}lcd z{$lk|^+MTYO(*JF3v}3$o|5{4=)$Y;U`)v^zD^^EMmM{yO?#ej+dY^A|Brr-x^5Ix zs>_Rt0mZQPwH1v_X5pH>5kQ@=c+Wk$p0|frzA}zC7ol+wBC}bm2O|bu*SMYuCSELq znz#|_MPvocl1(I)=2Ji>N_*8^D+fD3hq_xnf*O`G!dk0sI730!&ah|J8dDO@SI1XJ zG$`bwBb__4<+@#ef&N#t;0OGm7St&9r-RQrC7)C1Pnpw8NFL#r|MTY0MqVi6$|`T; z$wWnN)tokqIl8Xt+OLkE?WKN%c)exc);}S_NFN9kL+jGRShbuyS4PrW+I##n#Gb## z+JWN9>zVcX7bl6^816ON#G>#i7b?yNt++0Yw7AkQMzu|D^WWqk|==ZC6LpbyJC~`ynYZf93wO)Je_Kp2~?MVlD2wKa?7qOB@hn&sT zXM)*4VNw>UPx5@Yz+va!X@=;WEzcC$m84KR$}OK1vXQ(t6Cg`C+>rvhra1uodED40 z)UvTjZM(rQo@@4dPhi!*!nfw{dFy1qxB&j>@F(B$CzB}tXBWajJR<)m$enoR9p;~g zpph*%d6;h6nR(@E9EC@>qpaQE7eUi5l>x0QN5A-QIQB04{vJr1mdPs1DNMUA?mh0C z)nT_rG_Sx>DzLt6&8WfzP|qAD&M>rXogvLU0OB8ZR(B146XXE7pj5p?9_N2j1$K$L zxGhM!+uC)fGBg+r`17o*ZLw_2r?=NRxu(BWIJKz$bN)g-fMW7@!{t|T0*fKRTMIEo zY-@!eTHTFD)wbQ;`M5f+Kxh;QKNNKO%RXS64td=^C8|on)6ubn+%&e<)Zzb6;YBj1 zqvv;V9&LCL_D5)4+3kzn}b^-ff!D`Omwh=T|8GfoGL7(Oj zK`UM{VLseV8^?$W!ax&9>}d}iN1kt|JGOv4!_AY~tG_m}6U>A9V*?z&h9(qpq@I@( zWx$YL(?A@~9g%ZFVFO228^z^Zvw)8uey#^b*-;U?wF@L@U}u;DB*P-?f{lTPhZ~L%g4{%_aG}sh0`Tl zD!@A-eMdX_k5Q7i@lY2F5JiHvn7kjvsEmTiL)$uU^Q2ybo4HgpuYVtJ*rmEfT$|Kt zdH3nWO1_@a#?K+&rmRn1n#Tn_2gL!;@@}=dD0&Z2_hKl@3d`<+%moMkto~UUWNkSZM{xx}A_-I)AU?haX zheS9*LQYA+=T2;2nn8pN2NltasI+Fs4mN63K5Nz^yY%CErknGj_a+;7uH1f@`y6L! zj1P78qgL8}(O)r;iodN-8B?$B$#GHhE1k8*;e5S6uBP_X{V(V@$Wf#Vrntk-^Uj<+ zl4~&$f~_DB8ZY1kr!ZL2vx}BZdMs)mP^7s=F6T@pw22R(fB2vTX79HFi2)AZlFK?q zTN|8LrE^%zW)n5FY!R>DQ*Ay<6$vR`K`e_usRmz2){&exK65d{hr8FMXS4<24mnQ0 zdy?-xG8trDI1pzzt=E{io320>bkYjS2njLi67`W%A5L&FYGx`O)wrMw3j%mKIbd$B zuyfVm6m@`J{C}@CU2HP9eM!yL0@fM82OK2*G9CcqX{0se324A5(JI$xp7giOoh-m$SnhRBI zMq(Rpd#EhSEw~`+r^D@HmNtPe99C+p&WCFT`)AyNd(jl`9HWw#Y*f6>B<5O-FokkT zGD!!)Q)M4iASVIiyio0H1bz}F7iBkoa`^XNaouJ=wP6^PY?mp~L4`-&3hq5ziHee9 zA@vo_y`3(q1=av^VwHTUy8&iT^xLTehyaPjR_bR}4uBQ7CPfO6nw!!xQcivGt*)94 zB8IG#pvi8^?YEC=D)Dv@caV9AK{FDHQ#;YYqh*ER6#2II-;S3lTn&tb+|DEk09PY% z3@sQOm+5}nCmqe~^e?w^?nI;CG}JtXZYW#zVPT$nd+eGj!aRGSjxoyaOcY>c5IC;# zK2EIJ?5me$lOW6r+tw;#iFPjmk5j ze7WR=ms-hidY=a<^u~iJ+?rRrA%-r;dNyf;xc0{}_^c0_P&8S1CdIekJFWut7aiLV z1Zs%`!T%rB_gMdb)b}`mbKDwxdHr=vhjO%foGy5OLC~A|W^p|2_t0~kz4uscuoUH1j>ueI z&|KE~`nei#;|%NK))UuiN19=_T+2Pg9f2Z32?|**2ZUK+LySa|; z)tA3s6w`?nb=^<4_?`J~p$})OG(6*;$7Y0fE}%qfK>35!P7%n6g5hqPiOKv5J%}-M zta(4TbF-?u_zON=&Ct+4pF0VMFVd~QKW=`L0?&Bd5h@jQZs#5QG2w_w#T58!HThSI zdn2MqVzHZtFTep{03?9v=?aeJ2*msd-~hP(e1}gW9oTyCU1cDTYB#9*&wtCF943A^iYakhW2HL~x= z%(;37w*>*Fn)6j(quQj9Lx%~KBi6r#O-i845Kp#3dMeaViz%cEy>ksgclc%#2&Mth zOU6ZYkB8mCDox~$&e5jMXJN4j(oD->H;|~VXm@PmhpHl zZJ^QTMW$C=db+NB_6(2tZSyOdSXf;(4mM1Cs?r#1t{*kpe5-hYH$)MiJ=R71WB785 zrZg8I6eI827nH0 zdhpfh$1v1u9lES*=}ld0YCkDm)fWdemO3z~Z(_5nVmTNKU0W79Hcs_o4#g++-0oJk zb6Lp7})KsRKG7o5jZeAkfVDLouZBx zbWI6eF%yV8S)MUV;X-|qK%z8KikeP|n-SrO2=GH)cyuD4^JBcY*PcPxLbnH~sUV+% zwjvhn9&zGEw#8%@mgf5)e~a=iC>Mu$YLLJ-I}G)%^#G=n3_>|ZbH%K!NZti_LS&4W z?X9>xs660wa2IM$nRq~Mekh-litJ1-!`95n3b~n%C9J$zIe0k$a#XPDg%IUikp`mz z$12sZ>q^*4FIYYxSCWF_dHWxCO4YP~aD7RiiOVbDxs_4*F7A-N6R?f?2z}|EPqfgu z6608m{&+Nl@`E2B_Pb)}*|PV7zU<NPgFuX0HaVXMOuwn&TeU0Y>sxNM6^pA6F zLdYP5`w??uQR^>UD044gOOm@xF}`AYhU-7CRWNRE*t?K6(x5}HHWXVjVbd%9@) zCSz`$8gK8}Rnsf)_TsegH0_kp#JmB~G!PP#mIRtiHR^ofsvK0K3r1dOCrq6WaSll8 ziq8jJUoAJj9u>Z*4-^xL!x)mG-~D#^K=)Qc0QV8R9_S$R}T0+a~JkD?oG{F3rY33V%UX_D3k+V-JE=XGIwte|p>n^_cIZDSyL& zYTRT~6W@w~;^~RHfg)DhtabRksQNaBqLmi)D)muBY9qpA5*VXbrMH z*L&69s>Y^UY3#Lv+1bK4Q3)I#Cn)&~Ekpzi`6B*GQ3OYI_wnm6mS*PO^EmQ?aPFBE z^@*fq5O<}OH8@u@OZNzX!ehQil;=c^Te8P71F0f-Spxkgo-;8=VMO9hr1*`h{Ieg`Px;znq-DW5&q^;Q zWQk=M`7m<|^~A1ESyV-%p!acKDV(}hU?-AFKi}80!vswR{ssTfHt(cfx6L;~u&1Nc zv^o3*TR^fo5ynSOQ>6XCrz71VO+d>%ede$D(ch|ZG^e_n_i&hgYFnxqVph9d_!*V) zB@lEZd5aksQgzV>l znFj9{kcl)aT}bDt8DTk8M|bA=%D9&`Q}L3jbcA5?do6LZL@k9~b#?MJzp+Y$?%o~# zQq6!1xduQqV~$D&t(72#TbWLbH7kZ#i8FKyh z$8+e88j?4h+3PTM15IoLX>mnInEMFl;`_O9YJanJZa4q6n9a2b!`7yRu){HG%*`F@ z@Hpguu*vW~ivJLdtA&t=VkweZjD|1^w8@tOVp*pFu*~NJdJ6!It;Ht{Z^z;Q+Z5!X z-cJDG-hqR+-bO4)M1!UPKPC-X!Q#!IwQKZ$3*MvK zuV!OW)klUfpD8LWdZF|IqSMtmmv{8k;tO%O5YH0`$f??avG?@SBc}n{N+>x#cBXaf zlCmS^SS^L|&Wr(w3P`RK#`gpdWL?4Vu2*`IAN29B?w`IQAx;SYybqP-)%XkFLA#}Q z@j})(cR#0qT9)=bbxjC`u2p0}jUh+j9&9(hN zucWG@I^j4mtL4lYvu{W8z0>tARRVN z7d@}1sXksZ<_kJuMpmbhT9(?q)tIg)Xwtc275<%h;74(qzu@#sX67F64-#BxF_Z~b z+c*tZ_$>|l5U__5$C;Z(RfsR1U~Q|d`$tI)>|WZ4LEwr8X4Kk66>pV5ZAD`N3@wrY zCUtxYt}Jc+f|?FY;OL^BIdv0}j>#NF#M%RWwyRw|ht7ZyxN9%DYx9kTsCNfYLSDq* z4JF(^yJA}Wq|64>b{|`}rHD~Si?icrlm?`T$r_F1E{IL9G1gpoHR|mPI9K zmHV}LUsB)tUgbXY6#i3%+sk7|Gb4_UK7`(Egf%;t-KvornxkP@Xm}(0Y@4J8E@jDq zW|Yi4K*R-nfTRjwHpXs|*9D-+B}5|h0ySZw_%MdRABEpfPkYJGUfT}YleGG{)^nm` z!3ViHdPf(xW#lwm1#1>%I@_E82 zDxTDeG5+56AbR(COtoTrPZp*BEBLmM=`T1ow|CCD-}w!9I%Be%f^cb>dAV)3X-)!O zNI@Qyk5)x>Ov!`Cleg{Q*-iT75cNP*cnhR1Mnf_=_{BAG+VtujgsK&U9NB+o69QEw zA1r3Rh-NeZS7xPUVqpQHpB`TemP-P9CnF(oua*4EA_$DxyU5jMZkk1M@FOrv;Eu+6 zuw(ApZX5F}z-+gk+{tn(M1H9O`9$yU5P7dJ!~1dGoERj!FFuejemJ`lqB3I{G&Nn7 zu}Z(2nn|<{sZErIEYgnrq#6Q0>3f2H8KUV7v-Qanc&t`G%pB}DHlZ5iZ%>dq?Ghfv3xG=R6q zGd@CD5j8TUXVs(EoW(U2tzRL&_} zvCePfO-A1uhBhRpBdf?NDOHA)blw>erURoaQyG_eZdPKZ1p)6#SuakyQ?l(aiJn3A z5k|eZ9Kr`!^r3uViR6}M__cJ_99B8~yak;~Ejb_OC~|b;E<{X9sqwTVx&pFz?Lie9 z8e$Ze_G%P5EEFc3b1XDZryc*4J!|P@M7dF)9KZmk7E?Jr?*<`Ne!AbNdYGP==}g#L1-}LEtCfUK5R(G3SjeCsFYM91f2d6S z3@Mbsw{|_xiy9*zo;cSY;VH<*Ip?R=PTuEywLGd>6gb){Xw*jGfBbNP;IcNQ(0A~M zo7O_$ZJE}7WNE7PgpCUx39p|bp0?X7rozVkpDjFsR znKr#!**<+324hBLTY3GdxZ_9y^UQg(Ee?N(Xb7*TODZY`(mmTiTW`I+8T7+iYe@8$ zLR=bi9-y{end38JH&jp4E|+*#i9LqC60$iW39%Ca9KkGC?$0<$ath9Jo@QBaRHNU# zxn{QBc_0;<@N8n)3Z$FrCvX`*r(;udr^~d6Yz2fELm+|+!B&?ssOB(1 zx^EiiR$?J@=^I>tWAsk^B7OoEyAL$^X$wyt?Mgi8gs`B@d{%$vNEj~X%=AaOJxPL% zGO?Xmcgi^;T5x2A7y5-PD~=Me%CBV+dsI1$WOrED7=)C%Xam1*)h}p$qx%@$MZqj!*cmdV~|P zmpuG#|C<;~2n$*m?;xRClt4;Dm({Sd1DS zOf_D+H54&vk1F`@B_BB*G|TnVSv5|%my$ggQ)}u{h~WMs+<}u}{Mc14VP(yjg)V0) zhMd5kysSpW(nCiBcfUwp%r~PrwRg3tgGBDbitVK1o*OZP5+AAEJ|?L20Ry3f3zKzf zJ!4^RZwdJ}(D}dl{X|{mJfGy`C!|LwW6QOL2xZK}9Jv6(Z09Td>uKA`jkf+Z zHUtYLrEql?8w7|jX5wgz4&3li`*ex&U6B0{du*KOh(#fo`LU0+v+;P23G-m8(>Jgx zs})^T5ECFhxf=gmi%f}&rwV+AI(>PqDn%D1arN;rBjc z?O3Nc#FQ}tDMZt)Sh-%ib{;==78$tV$@)F`5XQ!|Mfd}rG5R9BHiMVjey?*1zzwIA zky7rwi>9H!hR$2^@0%6NoZcdbw<1cs0d?6td=uA~%_NQvk{SzxB~#ZnahY*SPc}PV zq;&;_I=YOf*9$e4XuS;MdQo0K$$F((!2!cv=&9^CKu7uwGFMYthCKu(L@kh6`|2~5!TPcX{hf0{$rcsA6wOT|!8F^?nmivWSNBjAkFV zwn)i0(*TimjKQ3_@K9A=Ot()bPM(Tu>;bgjPPfS{ygVc>_n8(8-D_{(l6Xcxw}liBUK`LW95 z(&>s7**nNAUXZ-uv5-Q~g040poqoKEa(s@vl;0njMe+Eh@)Law;-J;8oGdkd=rug+ zb3D;FG&%Wt-=%+gHv3bcQ@wcUv5mkg1HT;nXN%2-xj(B3$%h8p$)xJ_ZzO-IYbQ6- zou4lf9Y#(~n?P_zz#hCq|I`%SbX&bp9zR z-(Cwae{|qB@qR~`J!T=pCGY~1J2JZy80?--2wF+xUuK{&y*`CscCZ8MI z6t%PO`byrTD?;;12ga(6H0Oe?TiA_LkC-P5L3!EUN9%YvC@;XDGq$5u=6MIXXa@Y zPrKRNVgHuk8cWN`D&>#Q7@JGRgQB;awWqt!7yk)O*UrzCB_^032xs&0OkSX_JC0a* z1vcyT--pH4KeZF!OBY93aK44KoK^1;f?fw-gvo&b25r+kWb{>-?SeaT{kZpPf(YlZ zOVebT8n`-5T>RbIJ;6g^vjtrgEKbpkL^7^Bk;|su|kF-Qh52_Di!%NcRHlw*m z1ls~WYP*0HIkl+5^;|2?vWFL@n?Z~?t{$8_9(KsyDT+0_EHW)=r7CAGrv#LbKTlgK z9fkSli2Lzl+~`MY#QP`gc$8=$NIrJ7%KHil(F+ljJomjXDyfdAOm_-etp_ry9Q@Z3 zGPsn@gmz!Z3x>WAcN5sIg!Y>v+pbF4fDaK1D63M-Idm6uXv3J}A`8Ae!|={qmTv-u zFz#H$tp2n!Z&VN)IT`Knh>tQALD1R`n!oCBl{bOh7{ zi~&>)qy<@zzRL_a0Wtvbg5L!NC<05E6bWL%#-=jg{~B@~+fyCebBgj>`cOZ(J$LrH z;_42-6Y#`S;C3bTkJfX@_dIKVHb1znb@qDU@*DYg?V|Aze%Hrd`!(y#mAVr9SVIu8 z!;f%-9Z`oJu_Jr;1G#n$)c8O2>)8H(`gP3ATx|cxEsL3h{r_#){q}|SOBwlkndV#F z)_k6B=~_4AoS+~h!xbS)qD&AY0s#iG7)Wt~S&>1ywFxVy!r|NZZxySO8c3UgVA?Cc zyEZS_5dCTkd}!5bPK|Fau}Zz{-SOtgZ|(hgdFWNlc$<0hw>akP%Y6F^`1r?MoT-Y6 zdPE8;r|oO$&bCtA8`K{?h0=oZ*mzx~8Q)fhAG)?fR{X{;qVp{>F89mvnL%WMCjImGal)1M#JlO^lAz;neXZ@#mljMqpQrDuLm*#aG(4zqHRw0^0M zv&I{46L6J~(J)VL7Nig2ph74nk{O&8qcBTU^(aAbzfb9OXv-#xwxI^sqk8a6Pz%~1@euU6e*Mxe^_T3 z6lyL?uH43Ft3=2xeHnrW}_-IXjYaMq}T3I(Mk_3wUT;gyWQkNoZNF;Cyc<4PWy zO&Y4Mcy;cV%DpY>K&txz_YXFTdh;+a*PGRG>N)KM61nqg-|7@Ui) zVTj|~g>*yxVg+dVq;(R0u8p`>1zoh-4Mn%c45P2h%*AXs^4C?^7t1kA3pj{3W5L^X zFS;F>_&TE5!oy5dqW<|!)JWNjPf|RRti-5ajL1Bhl=v{08%Pl%UklCPTd5Ln3U!9r zN)rw$6nAKKBpFfdz}1==JFnF5qIMhox?<9jR?gxtZ@W$OPL89i$@H8ztFYmsu_Jpx z!Yb{yo(qVGcctoZgO zuobyB)nmmk$)8CS_ys@kt%y%!>_X81y+G&S_{Q1eib9C>I4tOHKV1G{_5 z5}>|G9`meL%Zl5_DO_u+6FT2Xy@!c_z>KE`ffd~WH zYM@=I)1pRRV;G?|Q2bDw$jEo_P&*Q@2!pXY6BNZ9q+&~xL z#oEGm`8`1wYKS`lryzx}kqqz);9{6a`a*8jPy*WwM4fD6xJdRw&A;^P#mZWUcv#+As5jYFgL=uGyH#E0eFOYJeFXX8OTPG0DNE% zv7tC1UXV+udQuz@F#3PcLOnDQiVzt<$|@2J>AxwP7|4H8_yt5UL8LFCN888%qW7Rv z$U;NWN6>#@U-&6#A!4Ke(L0+MA(Fq)Bk)2Q@jKujs3`g=$OzvR<#Fn?+DM>NxKMLQ z8tXvpX!|I^lD}}1ppWy#(V<<$nV=JEAUlXNqGIcYdUs*9XlQHib^w(TQ4eR#|8INr zhhik6(mBUcxgjprj@2R3N%fvoFweUWCb?3TK(|OenczM0zlUvXRwPK(&S#FuY;i@C zgzbRjl4&LR#sW@<+J~TD={Gs$40mmX2xP`ky($ACOkXrDc??tOtV`KemBD?wG@-Gf z)CVlHFabQuOK;hJ{zA3vjkD#*c@ln(A1H=XzD1lS!ci+1jR%A>0qSA*EJAfcX+m8> zNx%d}?Ay`m5n7BsQzeB+p@c($MChHn3MhFldE7HH&uRxWXT;_{qR>D+xv(q1uw^8U zgZT1(Ro`-+p9!Pv=^*n1O1IRs^RLPLjTd#;+9KO^JR_jDsbVOpN1xOR(yT zeUe19#xI3wIprEAJTgi&y-5c`OR-@?Kl~{*uPUSk^b?W`?UmC2Km_)eSIq!=ebZA@-6v=`staDc&6lsIqDzrM|?5R)hO~x zz3G$xTjrHLZ#e|`L3fivXA0B<_dyxmriAl#(PT1q?>sqiV94M zAGxCQIUY~;Y$59z9M5lsKT$lTq&z1|K5DTpyaUv>$H8>>zsgJOf0ZEawk5|o6XayoiJb-&lRh7<%fRRuz5QzE_?wUhMj_TeSyXR3&P1 z-uB{n8^(6mL9_^8RC(j4f3(H{<7X1&{VPS?60qSD_G)vC{5t>s;g5xVyj{-sl$|9` zoZlM8ilvk*ID=*dsiSeEb39aEv+SM>Ho5Rh^_*HZnkDY^?Vb!b@wMXN?n4Sa&_!i` z&_x{xljUhICsV86z4&8C8rW>ZXl<|>8aVE_I9M8+J=>S4I;i`7(sXu_JCn`nxEX5Y z>PAXj6SWvt6D9q?j3O?qsW0!GBF|+=0j0AJFxcTsArLl43(3#+^5jD=QFc;dN6MtC zHoVrvY9rx*w>VL+5rpY6rUjWc_OM5(1v7B}Hx`9lP0m(PKB1IR#g{jYpivMppd-Xh zKdH205GQ7+Z0K!hAE+GY9a!^gBcw~|bZ4Y)(QJev$S&G}Zw`)(b7a5{F6QOMjD=J2 zqCJnYaKX!sbmi5(_X|^vR`MBk)Ff`BN!geGq;1rAm=C)2L8n@>^ks%`EKg2kD0mJB z>ffP$!djf~eP0-%wosHz6Lv01j~Na(rdTltvBLcfwL4A~0ue0?GAiPZQaYEkuV{o# z2;$6gSX7`yfG2S}*ew9W*Mtz86mhWIkrGiEk~);VGjh6+WJ7G?_v76o`x)Yd_@ThP z+Pk-ps}JJ&4RKwfB6IN1XsovEap4z9W0oIPx8nZUSY(_Xr36bVUA{wO&L>9T&oI|D zC1L{M(oM0Tc%6a^>$avMjJshJMLsclf&qs7562e) zbTZeQfH#6^^dhn|1#}Yac+Da5IjVu^x$r%kv@+@inuQc&ewnrzb4RqEtj`3&J?nYC z{o>!nv&a9{-djgSz5M^DIiFP z(w)*EDJ_lQcfH}g7w-FVKlgY4`kl);;xO~f$2{jbuX)YvPI*7Wt;gDFWX2DrgwwbX zm)#^e(=*ej=;d134sjORzezTw&zAJ{sf!)GTaGsL5K$u7!S+ze316prcjp9hB(+_>`&@q&ItYW1oL!z9fk)=-(50kf4aJL5YdV0+UD0w#U8n3D1xgx)+TemS88c)=gtvr2a3HR?t3ceQ{*KqT^c3URs!$vYC=v{iH`3a zvryd4WP?8=B2H-#2S*i(Yu(j-%xC4p1iQ)WR!}I#d%KE0{+ck6B6v{HsOGJ9)jfB0 zca3r2scfbA5$S1SxPF*qnt{w>nmv0&$-HjG{nLypozqkrrid5Z^Oxs`+e8o(oY7H6 zpHN#)ANwB`VtpBNY(OxJVNpfKyV-Tv(d~h*~{R=Cg#i04?w6A zwpWGZEtYa2xgD1npUg7K^i7qhY(X8b91^Uh2ybc6++8+hmfoA?Trrj!0rMxUn(kVG z-0lN*JjR1I#3l=934559B#WaHQ`DB8zKOD-uQjm&-9!ro z;rqvT+^v0v>IJ@mSKLyxzh3UjytPfFvBS4bb%J^rBD?&|wi1W;Y1G_{imTg?m}WBd z8TLjsR;8#F!ZtHA=3cIgKgw5)xQT$y02h-v! zu!_%LVjwNmyC~u4msW?484Ew#6CHY_5C~HThZYUmcYd3spwkXzG;^kEF(7Y zHs6JPY(YE}O~TB_6Bs~SbV}G^Xp`2quyJMAVW4QHjF5B@u_>T{UzzYy(E>dK&8B>j zRlN8;`)%~Rz`OdXoL5q~%W?_&S#y&3({13^3VD?l zM$l%z?P4=?89O>%b+WtIm|qWFD)>f)3qGvDP54&1bDOQ$$#?iAqQt#bREH=mmT~DC z^l(5FaeO85i(>66gf?wJca>#0Z_Rq$ z;w~^1U9vHxCuH!+Haoi^8;!a6-5DGQLgjAG9Qv3{mo^kyevXWomdjjR4DPo?x5$&T zTn=-@$G(OxWW*b?>FY!x-u3D;}f*AE|QOWoHBb>d`LRoNMPu{mzra4bOz^iQlhX)oow4=Zuf^Ws@wo1l^o z>DV|R=4NP_B6>DQSy!AAl|M;}@L5}76kI|(n{Jw{IX)ds?4Mno=N<;kZFJ`-t zzISkTQWT|lv`DSTB-+tE-AgN_3N!ODGz!uZWy-JilP(bx@$dF(%0)ekZjmVSB-U@8 z|KyWJzqI{jS)4PDk!7AHrK2v+D5U?5yMoIomzb4m))?kg3mutH8bOsFRgx;|9+t1W zw-bIg1cN;=@sKjs-7Bv}hPV`MkNEQ}msXwpQ_Cv_%X|j*sFNf?@!Dxw9*0lrH)^gtw2j)`EAvBRsn)A*_wN&8 zx{s=puS?` zd!clxR+7Uz2coxD_@AKj!b?>hlV6nMY*Lt~6YbFTn?K-dyn9RNp^geu&o(QE)0ytl5^(MrTo`$(!prOWQmuMh1g4qq?XQkz^=mEE z%y?7+c6BuHhPGRU?1DY>9)+X_5vk1)Ep%F{&*mJd(vk{G4)hKK4vGgDs~HS(5O+O$ z6nb9wDfJVQr#zu1vzHg)?&hk6RP^EMkUSC>C#KFpi9X&r3CVy!1GuuZ#fjC>K#WE~ z#7T-#s`9+|8^sA}o8+og#zv2djw;GHcJ1G<$e{O?*$3R#z+AiMc7?{7rM1F~4Xzm3 zvPcIAwGD+S67-ug4m;nxyyPG``U=0-olEMGk0LiYzGi=+s@Y>&F0UzJiCGT4M^AZz zSos&@$pj?G7vlLjB-b38^fh^k*qN5#ZNG)0^6YINBDQ4)lIRIC$rY2) zJA7%rzBp240N2Iw3GEY7ec=&7$!GDWhc()k=L|Nh7R?xSTiBJ#+}#~;F{zweFSW_; z;<#h#)|J{PCfN!D`uLgh1?6!k0E?B9ah*b!o`Tqp6}fU5q|xi!0C*oMQHcv5e2lRU zSR=!i*NvG$S=^@3S$tB`OJHAz8}h^eXRpm!)4sYza7UC-7^_bs;N1sXv|e) z%S(J&sBSxPqtZMpx5}|IUPnVvXpfZTw9(1Jlr^`Y7C!R^y)SuuQ!YEAR?t@NTicLo z?Ll7!d9d+TuG=1k?pz&rGDPAi4WaIe7rb5ek)5xW%d-gnbe+8ab)|KNj?fr$!vjg-5~+>VA=(1Ll)8m$M7)<*}p6qSCEWakWxj2xxDEVZ= zHR7YWgZ7Hvx5>ol$#2uri!(Qv7bA+2>7A;ifu5f|DlJCy_B}P+=AW8=OFROD`Z-6wH)B=6SOrUI&|P=YXmj}akH97SeE%%tRkbR&H z8zXw3oLQ^R;(BlB@X|9y#PnK&avVN?2*E2_UpWEe_?&dSG2{D@DfV}R6nj7!*sjk( zLhLC)+$lk>MY6)TRdBX*j?|4`7PT`XZn}l!P4OB*P>s`{-*7nEiiYPrBxMa*&Sgxh z!zOFMm|(N}f^qMeWJQ+o=E!sV_hG(OJOgUXnw0lOguRc)%BBw5ygE$Y%xR*a*2XTe zJda`Z3V3$pQq7m4cE$Wr^+A*DflF`B;;SObVdK2s+m0%Gela$;Xk={h9{Ai1U}<<= zDXdq^nk{gvr2zW_Vq?Y6OF20hN6q02VjoAq;iN%W@4oXr(@$=igPOxlF+tcBDucQz zB*v&zce==52Y$)YOF$ZM89=hM>sNHix#gHhcL6%eL!WUx>Qs6GI{tnK?xAiG=Q>=lPnX zKjPsAQ1WZCR_$sB+kT=5VHgqKB*Zt~C4rZc=k#a>MXJ86(V0r!=x1V&)Vjh<_jqZC zN~!E^WWgO4O@d;y>!jnVA)9%6g>UNj2O5uJTHGs(7TG@!@z)xAWk<~I+IMZ*UsL(A zl5zE8+ta~e%f5j6!Ap9)52oZguWZP6k{BHA^mlJ1E4$*ek9w;tx8yb+yjlFP!fD(Y z;2q?{h!cc7!P%CE9>RYk^`VTY#=)VI1O|IvfVyFrJk1RR0;D+5{vefEF5JsFaS7i) z7HcCab`d3wS9FBvi{LXcj9LFXMO?l|u)L1=Z^C0Z1=e}`v}A7R`RHF0gzBN)Djy1{ zloBRpvd35z0#o-aEM* zlx=#{9G5sj2^XspPa-HHm|yDIj4p<@(C5G1c<6X@jGj8oAVLAyG+9(s)sPdo$8MiY zoy+Dr zv!SuYi_KE3pTO?~NcNrWcuQq|Ap>JRfiayEDx{HQTo@sW?zt*MrT z>AUamwD4U(YgpAKt2yWxC;)Hj4 zK6-wQ!62A9wO1BD@fGVkfuw~o*%+d-%e};d;_qY#kG{-vK@O^uA9ZCH9f@?8TJz?b zljgY~{B{^4oQp?c-=+b>pHo(&RH|Vo}7s0FOGZyyH7m zz01X2g%EXUGSQoIX)kNnoVra(E^s2c0$DN0?$36LexGER-rezevSNQaVro9KkEWv< zRiIw#G@8G*k=#ktr8wU{&wgsDdUBu5ZDc2Ijca4Ws&@Agqi5DJ+h?)iO!&~Jyw?2D z(9v~L*!Y{SGMmjP;vnyz%Q&^r=7UW< z)hRI3nM>(fisccOKZ&eVs@@Sk&awa>SG$D@7a=^FpBeags;A+yxJG?WUYn*I7ONQF z$(|2=OTp7bdBfc0Qp#4g{#3$LM0W-@sQ;Q~2ak>!d#5AUA=TjLig-GD+Gz4YBXwpC z=EwDFMj-z?(bsY#AybV|hO9614g;1iBf4$TckZ%+K8_~#Mkb3}PZt~MGZb*-*+bGK z*8RTan7I2WrwYD(S;KsHc6(s)DY{&uf9Q_tw#mv(dv(r+?BA&ekrw zaDm5cU=|hXlzlt5xz}X5m@RntUhniPAcJHsrLH$+2VN8BL*?+~-fjHd1q=1kS>81) zIWP@damNhGODu`h#`aM?Gj-`OjkoOg)t}cgdwQHAKdLcBK9Fr`vRwvaT3!>Z&_=h7G6q?M(_#26AL* zSV+*zyo6Zyoaqw|e4;DH9TyO9*P@u2inNOvg((m#4jQz2Ch}r;=JCK`*%K=n<~$Bx ztc1VyEO6?xnDP-Etza@fvhHyUwkFwwI+{?Yq*#?0>Say2$Huk2VKo(E)xNx^a zqZMU`QB1B1MfNzU@GuTni<6JDouz|K7PXj}sJbS!8U1wAjS=sNwl+Wzx7JoS-$D~x zR=4F?d?NK_!5CR0Xe}jp{gWU+9+!oh8g zt#{4@R(O+K-Q#8A?$XtxD<^g*A6#1tHu_+L`>CSD5Db%QuY`PyGG9@CJ6KD2UI1ps zv~IootGA@@#gp=HmCPrHSYiqf*B@THgfq-|YJT-Czw4xYjfnB>V65yI{{2HM(AUFv zhI7|xb+fdEEO4l)ttf_Q={JK%?Uv_4vP&MUNO}9!*Ufvq3xaR;OWt>%^$dYj!E8of zP1&`Z;Kj2%n}!7RWH+W=T2kD>SmvmJl;64CgaE;q2b$s>Iwv#2aN;~#?|W#~O>SdsBqpGERa&9#XeEdTF#hc{W$Km_3pNP2xc!s>(pK08=b5EtUYi>52lTnvL z^@~KaNx2jpZr^wXeZ;)Q8aMj!V?5Yn-s2PBT79CZ_=Z*>bztaA#LLg6mr%b}@wYWUmz>e`=B*Tp zbM#A6uA9~JYtP7|=gN&?C|3r5Xo>T`tCLu1^+m1OB|F09`JvjdqI5zBEN0+snV^Fz z{?xJWo<#7+XuYAG7Oi-e<4M1xSOF?o(9rflcyW~Vv(N-z_i;Qox==3rh=d%?)@=w& z@9V+9gOSU*P|H3pZIL%J?51{!dPOnNh~5CEpx(llS>6pJ!XuZRWy+%MJN1;wK7ZMB z(=OkC6Ya5@uI~%7Dz-h1>%2YLfGb@anD|6;~P(EIvTI0 zP1xMqoN4&9Mjo*pD;JWfNZM8Kvh)rv_47A#ue&}h9BQB1=Q5OA%Vm5uItV=B7_vF$ zp323ug$X^0jZ2;v%g~xL;dB|~(ItI(%ijLr z+CB!<5i2s+bEgyBrn>k0ng0$s-|iiZ!5Unyn4>= zCV8>dho#~wfGM;Hf@X18zh(pH_1#e&N&!l%SmRvdq`9|Zh!N=+T-|#d>_cM5$p^=) z1dW_L_J`B!z1+y#UP=;b_+md}!SR>#8w=9oNp5a}W3Z^73~oMa#(xk|bU?I$&%l2D zxmD(gZi=aH?*K{d&TMc7YZg%>p+T?umu{S=ZmOP*6im0exjTwpRHucuIP#?hJFh18 z(1uFI6G~Ar4>EO;GT2ja6YA&_)=(b}xR;5tf`IG=+#+V~BU@JWg)-*&*^d=w+VM0V zmkX2$z?j~qD;wOjiP8xv>HLz%QooELdk;*fYng*HbZx-T0+(bIFuHrMfY0bIBO~^m z#~2o)lKl={pY?`cSg}@5l)l~p4g01aZ;k1Y9Tc$DB(maK=ba5jD#qg%x z$vc3b4twu;g5}$f-?m=PRKHBD8MB<`6Xhe-L3pi7b@MYCpOzteun~9C2UN3?w7Acu zzKPqI$_iWk+ZYlc#X-Swk4w~S*#~|yt0_V|oR7tZp6Ff=Aqwq)r_!gdP|);2XU(5) z-Ff?<>Z9J8%9j2!T!Lmd%)f&$XI8G(HQ>;ib%eh{bK{HE64?gkO zau~Qxzj?fXy1}w|w>*Pa>^%wc+brC4BR+a%MlfYHrm>xE(&M%%&*$*@jVkz5}==b!-w7_n~80|S9$s+ zF=j}dr7JL-m*Ghuhfu?Wn{LTtr*7m2y{u;LP7CjK5iq=x9LfE_HKvHmHI%(I&=`xk zFZ)zTT}@97V#*UjMqBZGbdqGM;?ooU)YFWYW@Thl3Z+vNot-Y_Z(JXJX~J4A>Mc)H zoIpJtf2?M5>rt&;1cQ2a`d<4Qp^T6IUh8h&Wa!4^8bhqnyjp3nBoF9qyz}pU<18uAnKUKZy$sQmp;}uqMW)s!bY-TbCe&5!m6xIcz;@#0FXsR~u6J`yQ z!mlgAN#p?#1aZ<8YI<^GNRXXCuW4x738n?N`3C!n5XhY(=Yzin=K59>yJW>ft>{$# zkS4%v`wb!YeD=O0{&kQ_bwx8MbrhD*nQPLEuT<38V;GZpa!DcuWOIcE{A@2Ci<2i2=Cl|i7gBsD&QR|i*oa9m+=Z?}<^4g&*J&nv%wDTEE!>jD5KwTS56bnh_`%1Y4FlHE z)$$f_vl^y5ZEs2DWFFmFMnyGvHanBlVo$q@K4?_N0~sxL51^RD{EF+~N_0ap zqQ%sivK!aLyE8}vn?#&Omm#OL4)fcKC#p^zjB$3$LuH5d9{rXY?u}UQbw;MTi)Ok= zu9J*-!Y0WWoZowbl%!fVocBbi+(`)3x`Q^FXby;9hsZZMS?{I=a?afx4Bna;V|K?A zAe{2=WWd`@U#D@ece_*bICxHu?Ns?I)#Ywns?&5f?QyDFMAxd>+~DUZ18rfClgQkK zH>oS0=(hLF|yin0G@yXZ>|110l!hezQ-zfNR6#V~h6jWhh_T}sn{K6A`bVVWhQ?OLqG*?} ziKKb2wkW9%m$xxk4pY^;?%E%tD+0)yRZ41b{;0q^ z4-Izo_)O(FPek3lzsx?pkP6{lzIdUm^I(d)dI!(GJ|o?`3hkT0i+|u{E5@YWIX*a^ zZq$bSpTqK3L7<9PRm-gKf9LxZ@*lEMFA3{L{sV7*2>Aa}sDoh$>;Dt&%NUqno}ION z8yETJ;9tVTp!?quR5O0gBFJ?u_X^OtP(B}iXKJLGH+N0IXYvN1yv}xO@c-TifYQ41 znTG#6-}H@3QBzOOB7ZKbE*9*49k}W7mh%h@VLH=}hZ7fbpJ5Y4y7O!-{me)`OXP*j z7Am`q7fDBE;BFP@8Jy3JG$Q?1JUJH*+*!Qw2SQi>EYJT=p!X8m$-4_DhTk##;uxU1 z&SQ}0oR??9<^tt^&i=Kc?$F~x4E{!@#|GGL6|(=il0PQ=Khj9E+8+KRJ|LUEUfdZ7 zT9|CP^#8#GC+J&uWMOqC5&*e%hE?2uwDvs40l>|-R554lI8SzQ4H~xm5c=PUpy7zp zi^9K71W;I!c-E+vyS5w?XDctZ>->;M!^Y3Nd6A_T;f7Q!isC(HZhZ#z^U;5yew=mj{y8cF9^3Z8oJv(MQ{Bn?zv%RCz$+qfM$)fbKBe-sAOz)L}clNUL2Zeab5G!NL+ zL{lg_J3hi5ywc@5>)!dqajs?=V@SdLOacHD)VcplX^NTq!WF~cfEVCZ2k*ZyZ#G@e zdU^J_1i6BE@UOT+gKb3^`7cDu^gLc(8P-KZ;i9qmbL!sRGd$CCe z^}O)Q*h0e|c$azx5$|!dW8;4?pPUQ(06@=>+gX%cFyhKCei~pcw0?M&^B;^u6zFCl#32io?QukA~Ab+;cR_A>XAz)#q$bsMTZmq4eQVQbGF7i`j#!f z!-eU%7eg_V;U9ImlF~Uo7mP&lGe|(LA7C6Ppd6ilPbR zZ~_$ppr1FEko!t%21DqIutPER^->ec8aYpX1Sway2BdDpljS$VoyILB6IYfv?lS_e3 z!Bz}vW-jdthpM?MsvEmn8uLMDM1*k#o%x-uZLN{g0M6D{Hun6^LNs6q%m~VlEPt;C z(g1!UL0AgW-22`D&{9wah{51c03R!e#h8r^1mNLg<>ujnu$k~M1K8QvIe={3KoE!p z#K+GL;s;xJS&$Sg_AWLEurrH|J?+mzew8B*wKs;F+aknvLvI1%)3*{6WsI z-dbA&e?W;uN)XAyFNWMKMef8R{|O_z5yZmA!@|a{4&vr#M)pWfj@0|i* z0m$6H_rO3|MqWuB`Nw@#1##qmY6!3m1Pq55NFvPyu&}cs(MSG927!e&2P*_->?{cU zuHDM~kIH|p{i97k`E=HN!C#`A-yZQjzCeP&KUVzC`Cl6xp>TU7Ov1?V@*DN9mA|9^ zDcbqPVa5*M$Cr$_u!Dm+grAp#lY`HMn~#N^7tF>2=HujL0dui)v4D_y3It{6;{&rH z(Lcv~POgj%(qbE9=&y1)Kwu~s%E^Ni$qQ!TfN(-tz$Qiz7GonLPCgz88yk-i$FFjK z$NP)ipYi%#+WHC3pKFmx5t)#IKQi(kk^VU(|NY;;IsEU-{vq){B|o6}JB9z?`a3B7 zp!pB3A5i?A!hdl69h831{0G+$DE?02Ke+x5N5-w)*ivRZ&EEZixCh6EH>LoIisam|; z^S1o;_Y(pV)1m(+4ZEJS5IlwE6*;F#ydAw>SElM-+@WA8dcP^D32 zZ)>9_7H&rB%$}CwVz2^s>VxP0rF$7gPuA@2yJJKevgK?{t+-oDMdf5t;0vSSqpYim z7M+LZcZXzuKJTgwhFjYU3VuHy>tJnTk9_~242MF@jS(<70K_gV{Ab6GWW;p@Iq!4a zhA1@mxyRaZ9j|B3OmyerEoQso_hllqbhnR#I zr#LU4gt!DBFR!Gq9`b;#2@LS_>84-aHE?nQRbem$a)tBrStWB<?^z;%+k_7(`p-UR^ diff --git a/fusion_claims/fusion_claims/static/src/scss/fusion_claims.scss b/fusion_claims/fusion_claims/static/src/scss/fusion_claims.scss deleted file mode 100644 index 6368370..0000000 --- a/fusion_claims/fusion_claims/static/src/scss/fusion_claims.scss +++ /dev/null @@ -1,872 +0,0 @@ -// Fusion Central - Backend Styles -// Copyright 2024-2025 Nexa Systems Inc. -// License OPL-1 - -.o_fusion_central { - // Settings page styling - .fc-settings-section { - margin-bottom: 20px; - - h5 { - color: #0077b6; - border-bottom: 2px solid #0077b6; - padding-bottom: 5px; - margin-bottom: 15px; - } - } - - // Status indicators - .fc-status-created { - color: #28a745; - font-weight: 500; - } - - .fc-status-pending { - color: #ffc107; - font-weight: 500; - } -} - -// ADP portion columns styling -.o_list_view { - .o_field_monetary.fc-adp-portion { - color: #0077b6; - font-weight: 500; - } - - .o_field_monetary.fc-client-portion { - color: #28a745; - font-weight: 500; - } -} - -// ============================================================================= -// STATUS BUTTONS: Theme-friendly (light + dark mode) -// Uses Odoo CSS variables with safe fallbacks. -// ============================================================================= - -// Good / confirmed / within period (green tint) -.fc-btn-status-good { - background-color: rgba(40, 167, 69, 0.12) !important; - color: #1e7e34 !important; - border: 1px solid rgba(40, 167, 69, 0.35) !important; - - &:hover, &:focus { - background-color: rgba(40, 167, 69, 0.22) !important; - color: #1e7e34 !important; - border-color: rgba(40, 167, 69, 0.5) !important; - } - - .fa { color: inherit !important; } -} - -// Bad / not confirmed / overdue (red tint) -.fc-btn-status-bad { - background-color: rgba(220, 53, 69, 0.12) !important; - color: #bd2130 !important; - border: 1px solid rgba(220, 53, 69, 0.35) !important; - - &:hover, &:focus { - background-color: rgba(220, 53, 69, 0.22) !important; - color: #bd2130 !important; - border-color: rgba(220, 53, 69, 0.5) !important; - } - - .fa { color: inherit !important; } -} - -// Dark mode overrides -html.dark, .o_dark { - .fc-btn-status-good { - background-color: rgba(40, 167, 69, 0.18) !important; - color: #6fcf87 !important; - border-color: rgba(40, 167, 69, 0.4) !important; - - &:hover, &:focus { - background-color: rgba(40, 167, 69, 0.28) !important; - color: #6fcf87 !important; - } - } - - .fc-btn-status-bad { - background-color: rgba(220, 53, 69, 0.18) !important; - color: #f08a93 !important; - border-color: rgba(220, 53, 69, 0.4) !important; - - &:hover, &:focus { - background-color: rgba(220, 53, 69, 0.28) !important; - color: #f08a93 !important; - } - } -} - -// Also support Odoo's color-scheme media query for dark mode -@media (prefers-color-scheme: dark) { - .o_web_client:not(.o_light) { - .fc-btn-status-good { - background-color: rgba(40, 167, 69, 0.18) !important; - color: #6fcf87 !important; - border-color: rgba(40, 167, 69, 0.4) !important; - - &:hover, &:focus { - background-color: rgba(40, 167, 69, 0.28) !important; - color: #6fcf87 !important; - } - } - - .fc-btn-status-bad { - background-color: rgba(220, 53, 69, 0.18) !important; - color: #f08a93 !important; - border-color: rgba(220, 53, 69, 0.4) !important; - - &:hover, &:focus { - background-color: rgba(220, 53, 69, 0.28) !important; - color: #f08a93 !important; - } - } - } -} - -// ============================================================================= -// SALE ORDER LINE LIST: Column width control -// Odoo 19 ignores the XML width attribute on list fields. -// We use CSS on th[data-name] with table-layout:fixed to force widths. -// Product column has NO explicit width so it absorbs all remaining space. -// ============================================================================= - -.o_field_one2many[name="order_line"] .o_list_table { - table-layout: fixed !important; - width: 100% !important; - - // ---- Product column: gets ALL remaining space (no width set) ---- - // Truncate long product names with ellipsis - th[data-name="product_template_id"], - td[name="product_template_id"], - th[data-name="product_id"], - td[name="product_id"] { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - - // ---- Serial Number: generous width ---- - th[data-name="x_fc_serial_number"] { width: 140px !important; } - - // ---- Quantity columns ---- - th[data-name="product_uom_qty"] { width: 55px !important; } - th[data-name="qty_delivered"] { width: 55px !important; } - th[data-name="qty_invoiced"] { width: 55px !important; } - - // ---- UoM ---- - th[data-name="product_uom_id"] { width: 50px !important; } - - // ---- Price / Discount / Tax / Subtotal ---- - th[data-name="price_unit"] { width: 80px !important; } - th[data-name="tax_ids"] { width: 70px !important; } - th[data-name="discount"] { width: 45px !important; } - th[data-name="price_subtotal"] { width: 90px !important; } - - // ---- ADP / Client Portion ---- - th[data-name="x_fc_adp_portion"] { width: 80px !important; } - th[data-name="x_fc_client_portion"] { width: 80px !important; } - - // ---- sale_margin optional columns ---- - th[data-name="purchase_price"] { width: 70px !important; } - th[data-name="margin"] { width: 65px !important; } - th[data-name="margin_percent"] { width: 55px !important; } - - // ---- Description (hidden by default, but set width in case user shows it) ---- - th[data-name="name"] { width: 120px !important; } - - // Tax tags: compact badges - td[name="tax_ids"] .badge { - font-size: 0.72em; - padding: 2px 4px; - } - - // All cells: allow text truncation - td { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } -} - -// Responsive: scale text on smaller screens -@media (max-width: 1400px) { - .o_field_one2many[name="order_line"] .o_list_table { - font-size: 0.9em; - } -} - -@media (max-width: 1200px) { - .o_field_one2many[name="order_line"] .o_list_table { - font-size: 0.85em; - } -} - -// Form view styling for ADP fields -.o_form_view { - .fc-adp-totals { - background-color: #f8f9fa; - border-left: 4px solid #0077b6; - padding: 10px; - margin: 10px 0; - - .fc-total-label { - font-weight: 600; - color: #495057; - } - - .fc-total-value { - font-size: 1.1em; - font-weight: 700; - } - - .fc-adp-value { - color: #0077b6; - } - - .fc-client-value { - color: #28a745; - } - } -} - -// ADP Summary Line Details - constrain product column width -.o_fc_line_details { - .o_list_table { - table-layout: fixed !important; - width: 100% !important; - - // Product column - first column - td:first-child, - th:first-child { - max-width: 300px !important; - width: 40% !important; - overflow: hidden !important; - text-overflow: ellipsis !important; - white-space: nowrap !important; - } - - // Other columns - auto size - td:not(:first-child), - th:not(:first-child) { - width: auto !important; - white-space: nowrap !important; - } - } -} - -// ============================================================================= -// CHATTER WIDTH CUSTOMIZATION -// 80%/20% split ONLY on desktop (>= 992px). -// On mobile/tablet, Odoo's default stacking (chatter below form) takes over. -// ONLY applies to main action forms, NOT modal dialogs/wizards. -// ============================================================================= - -@media (min-width: 992px) { - // Only apply to non-modal forms (forms in the main action area, not in dialogs) - .o_action_manager > .o_action > .o_form_view .o_form_renderer { - display: flex !important; - flex-wrap: nowrap !important; - - // Form content takes 80% of space - > .o_form_sheet_bg { - flex: 0 0 80% !important; - width: 80% !important; - min-width: 0 !important; - max-width: 80% !important; - } - - // Chatter container - 20% of screen - > .o-mail-ChatterContainer, - > .o-mail-Form-chatter, - > .o-aside { - flex: 0 0 20% !important; - width: 20% !important; - min-width: 20% !important; - max-width: 20% !important; - } - } - - // Additional backup selectors for chatter (non-modal only) - .o_action_manager .o-mail-ChatterContainer.o-aside { - flex: 0 0 20% !important; - width: 20% !important; - min-width: 20% !important; - max-width: 20% !important; - } - - // Force the form sheet content to expand within its container (non-modal only) - .o_action_manager .o_form_sheet_bg { - max-width: none !important; - } - - // Also target the inner form sheet (non-modal only) - .o_action_manager .o_form_sheet { - max-width: none !important; - width: 100% !important; - } -} - -// Make chatter content more compact (all screen sizes) -.o-mail-Thread { - .o-mail-Message { - padding: 6px 10px !important; - font-size: 0.9em; - } -} - -// Compact activity section -.o-mail-Activity { - padding: 4px 8px !important; -} - -// ============================================================================= -// Icon-only chatter topbar buttons (ALL screen sizes) -// "Send message" and "Log note" have RAW TEXT inside (no ). -// "WhatsApp" and "Activity" wrap text in . -// We use font-size:0 to hide text, then inject icons via ::before. -// ============================================================================= - -.o-mail-Chatter-topbar { - gap: 4px; - - // --- Send message (raw text, no span) -> envelope icon --- - .o-mail-Chatter-sendMessage { - font-size: 0 !important; - padding: 8px 12px !important; - min-width: auto; - line-height: 1; - - &::before { - font-family: "Font Awesome 5 Free", FontAwesome; - font-weight: 900; - font-size: 15px; - content: "\f0e0"; // fa-envelope - } - } - - // --- Log note (raw text, no span) -> edit icon --- - .o-mail-Chatter-logNote { - font-size: 0 !important; - padding: 8px 12px !important; - min-width: auto; - line-height: 1; - - &::before { - font-family: "Font Awesome 5 Free", FontAwesome; - font-weight: 900; - font-size: 15px; - content: "\f044"; // fa-edit / fa-pencil-square-o - } - } - - // --- WhatsApp (text in , target via hotkey) -> WhatsApp SVG --- - button[data-hotkey="shift+w"] { - > span { display: none !important; } - padding: 8px 12px !important; - min-width: auto; - line-height: 1; - - &::before { - content: ""; - display: inline-block; - width: 17px; - height: 17px; - -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z'/%3E%3C/svg%3E"); - mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z'/%3E%3C/svg%3E"); - -webkit-mask-size: contain; - mask-size: contain; - -webkit-mask-repeat: no-repeat; - mask-repeat: no-repeat; - background-color: currentColor; - } - } - - // --- Activity (text in ) -> calendar icon --- - .o-mail-Chatter-activity { - > span { display: none !important; } - padding: 8px 12px !important; - min-width: auto; - line-height: 1; - - &::before { - font-family: "Font Awesome 5 Free", FontAwesome; - font-weight: 900; - font-size: 15px; - content: "\f073"; // fa-calendar - } - } - - // --- Message Authorizer (text in ) -> custom SVG --- - .o-mail-Chatter-messageAuthorizer { - > span { display: none !important; } - padding: 8px 12px !important; - min-width: auto; - line-height: 1; - - &::before { - content: ""; - display: inline-block; - width: 17px; - height: 17px; - -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 50 50'%3E%3Cpath d='M 25 -0.03125 C 11.839844 -0.03125 10.148438 4.851563 10 5.40625 C 9.988281 5.453125 9.976563 5.484375 9.96875 5.53125 L 7.96875 21.5 C 7.929688 21.828125 8.070313 22.148438 8.3125 22.375 C 8.410156 22.464844 8.503906 22.546875 8.625 22.59375 C 8.363281 23.386719 8.015625 24.71875 7.75 27.03125 C 7.75 27.042969 7.75 27.050781 7.75 27.0625 C 7.304688 27.746094 7 28.65625 7 29.8125 C 7 32.0625 8.582031 33.878906 10.65625 34.40625 C 12.003906 37.898438 13.675781 41.625 15.90625 44.59375 C 18.230469 47.683594 21.238281 50 25 50 C 28.761719 50 31.769531 47.683594 34.09375 44.59375 C 36.324219 41.625 37.996094 37.898438 39.34375 34.40625 C 41.429688 33.886719 43 32.070313 43 29.8125 C 43 28.613281 42.699219 27.6875 42.25 27 C 41.984375 24.707031 41.636719 23.382813 41.375 22.59375 C 41.496094 22.546875 41.589844 22.464844 41.6875 22.375 C 41.929688 22.148438 42.074219 21.828125 42.03125 21.5 L 40.03125 5.53125 C 40.023438 5.484375 40.011719 5.453125 40 5.40625 C 39.851563 4.851563 38.160156 -0.03125 25 -0.03125 Z M 24 6 L 26 6 L 26 10 L 30 10 L 30 12 L 26 12 L 26 16 L 24 16 L 24 12 L 20 12 L 20 10 L 24 10 Z M 25 20.78125 C 29.371094 20.78125 34.777344 21.605469 38 22.15625 L 38 27.65625 L 39.15625 27.46875 C 39.15625 27.46875 39.628906 27.390625 40.0625 27.59375 C 40.496094 27.796875 41 28.15625 41 29.8125 C 41 31.300781 39.898438 32.449219 38.5 32.59375 L 37.90625 32.65625 L 37.6875 33.25 C 36.34375 36.785156 34.621094 40.554688 32.5 43.375 C 30.378906 46.195313 27.941406 48 25 48 C 22.058594 48 19.621094 46.195313 17.5 43.375 C 15.378906 40.554688 13.6875 36.785156 12.34375 33.25 L 12.125 32.65625 L 11.5 32.59375 C 10.097656 32.449219 9 31.300781 9 29.8125 C 9 28.234375 9.484375 27.878906 9.9375 27.65625 C 10.390625 27.433594 10.875 27.46875 10.875 27.46875 L 12 27.59375 L 12 22.15625 C 15.222656 21.605469 20.625 20.78125 25 20.78125 Z'/%3E%3C/svg%3E"); - mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 50 50'%3E%3Cpath d='M 25 -0.03125 C 11.839844 -0.03125 10.148438 4.851563 10 5.40625 C 9.988281 5.453125 9.976563 5.484375 9.96875 5.53125 L 7.96875 21.5 C 7.929688 21.828125 8.070313 22.148438 8.3125 22.375 C 8.410156 22.464844 8.503906 22.546875 8.625 22.59375 C 8.363281 23.386719 8.015625 24.71875 7.75 27.03125 C 7.75 27.042969 7.75 27.050781 7.75 27.0625 C 7.304688 27.746094 7 28.65625 7 29.8125 C 7 32.0625 8.582031 33.878906 10.65625 34.40625 C 12.003906 37.898438 13.675781 41.625 15.90625 44.59375 C 18.230469 47.683594 21.238281 50 25 50 C 28.761719 50 31.769531 47.683594 34.09375 44.59375 C 36.324219 41.625 37.996094 37.898438 39.34375 34.40625 C 41.429688 33.886719 43 32.070313 43 29.8125 C 43 28.613281 42.699219 27.6875 42.25 27 C 41.984375 24.707031 41.636719 23.382813 41.375 22.59375 C 41.496094 22.546875 41.589844 22.464844 41.6875 22.375 C 41.929688 22.148438 42.074219 21.828125 42.03125 21.5 L 40.03125 5.53125 C 40.023438 5.484375 40.011719 5.453125 40 5.40625 C 39.851563 4.851563 38.160156 -0.03125 25 -0.03125 Z M 24 6 L 26 6 L 26 10 L 30 10 L 30 12 L 26 12 L 26 16 L 24 16 L 24 12 L 20 12 L 20 10 L 24 10 Z M 25 20.78125 C 29.371094 20.78125 34.777344 21.605469 38 22.15625 L 38 27.65625 L 39.15625 27.46875 C 39.15625 27.46875 39.628906 27.390625 40.0625 27.59375 C 40.496094 27.796875 41 28.15625 41 29.8125 C 41 31.300781 39.898438 32.449219 38.5 32.59375 L 37.90625 32.65625 L 37.6875 33.25 C 36.34375 36.785156 34.621094 40.554688 32.5 43.375 C 30.378906 46.195313 27.941406 48 25 48 C 22.058594 48 19.621094 46.195313 17.5 43.375 C 15.378906 40.554688 13.6875 36.785156 12.34375 33.25 L 12.125 32.65625 L 11.5 32.59375 C 10.097656 32.449219 9 31.300781 9 29.8125 C 9 28.234375 9.484375 27.878906 9.9375 27.65625 C 10.390625 27.433594 10.875 27.46875 10.875 27.46875 L 12 27.59375 L 12 22.15625 C 15.222656 21.605469 20.625 20.78125 25 20.78125 Z'/%3E%3C/svg%3E"); - -webkit-mask-size: contain; - mask-size: contain; - -webkit-mask-repeat: no-repeat; - mask-repeat: no-repeat; - background-color: currentColor; - } - } - - // --- Mic button (already icon-only from fusion_notes) --- - .fusion-notes-mic-btn, - .o-mail-Chatter-voiceNote { - padding: 8px 12px !important; - } -} - -// ============================================================================= -// XML VIEWER STYLES -// ============================================================================= - -.xml-viewer-content { - overflow: auto; - background: #1e1e1e; - - .xml-code { - font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace; - font-size: 13px; - line-height: 1.5; - color: #d4d4d4; - background: transparent; - white-space: pre; - tab-size: 2; - } - - // Syntax highlighting colors (VS Code dark theme inspired) - .xml-tag { - color: #569cd6; - font-weight: 500; - } - - .xml-attr { - color: #9cdcfe; - } - - .xml-value { - color: #ce9178; - } -} - -// ============================================================================= -// ADP DOCUMENTS TILE LAYOUT -// ============================================================================= - -.fc-document-tiles { - display: flex; - flex-wrap: wrap; - gap: 16px; - padding: 16px 0; -} - -.fc-document-tile { - width: 220px; - min-width: 220px; - background: var(--o-bg-card, var(--bs-body-bg)); - border: 1px solid var(--o-border-color, var(--bs-border-color)); - border-radius: 8px; - overflow: hidden; - transition: all 0.2s ease; - cursor: pointer; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); - - &:hover { - border-color: var(--o-action, var(--bs-primary)); - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); - transform: translateY(-2px); - } - - // Preview area - .fc-tile-preview { - height: 140px; - display: flex; - align-items: center; - justify-content: center; - background: var(--o-bg-200, var(--bs-secondary-bg)); - border-bottom: 1px solid var(--o-border-color, var(--bs-border-color)); - position: relative; - - .fc-pdf-icon { - font-size: 48px; - color: var(--o-danger, var(--bs-danger)); - } - - .fc-xml-icon { - font-size: 48px; - color: var(--o-info, var(--bs-info)); - } - - .fc-empty-icon { - font-size: 48px; - opacity: 0.35; - } - - .fc-thumbnail { - max-width: 100%; - max-height: 100%; - object-fit: contain; - } - - .fc-upload-overlay { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0, 0, 0, 0.7); - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - opacity: 0; - transition: opacity 0.2s ease; - - i { - font-size: 32px; - color: white; - margin-bottom: 8px; - } - - span { - color: white; - font-size: 12px; - font-weight: 500; - } - } - } - - &.fc-tile-empty:hover .fc-upload-overlay { - opacity: 1; - } - - // Tile info area - .fc-tile-info { - padding: 12px; - text-align: center; - - .fc-tile-label { - font-size: 12px; - font-weight: 700; - text-transform: uppercase; - margin-bottom: 6px; - line-height: 1.3; - } - - .fc-tile-filename { - font-size: 11px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - - .fc-tile-empty-text { - font-size: 11px; - opacity: 0.5; - font-style: italic; - } - } - - // Actions bar - .fc-tile-actions { - display: flex; - justify-content: center; - border-top: 1px solid var(--o-border-color, var(--bs-border-color)); - background: var(--o-bg-100, var(--bs-tertiary-bg)); - padding: 8px; - - button { - flex: 1; - padding: 8px; - border: none; - background: transparent; - font-size: 14px; - cursor: pointer; - transition: all 0.15s ease; - - &:hover { - background: var(--o-action, var(--bs-primary)); - color: white; - } - - &:not(:last-child) { - border-right: 1px solid var(--o-border-color, var(--bs-border-color)); - } - } - } - - // Has file state - &.fc-tile-filled { - border-color: var(--o-success, var(--bs-success)); - } - - // Required field indicator - &:has(.o_required_modifier) { - .fc-tile-label::after { - content: " *"; - color: var(--o-danger, var(--bs-danger)); - font-weight: bold; - } - - &:not(:has(.o_field_binary[value])) { - border-color: var(--o-warning, var(--bs-warning)); - } - } -} - -// Section headers for document groups -.fc-doc-section { - margin-bottom: 24px; - - .fc-doc-section-header { - font-size: 14px; - font-weight: 600; - border-bottom: 2px solid var(--o-action, var(--bs-primary)); - padding-bottom: 8px; - margin-bottom: 12px; - display: flex; - align-items: center; - - i { - margin-right: 8px; - color: var(--o-action, var(--bs-primary)); - } - } -} - -// Style the upload field in tiles -.fc-tile-upload-field { - width: 100%; - - .o_select_file_button { - width: 100%; - border: none !important; - border-radius: 0 !important; - background: transparent !important; - font-size: 12px !important; - padding: 8px !important; - - &:hover { - background: var(--o-action, var(--bs-primary)) !important; - color: white !important; - } - } - - .o_file_name { - display: none !important; - } - - .o_input_file { - display: none !important; - } - - &.o_field_binary { - display: flex; - justify-content: center; - } - - .o_form_binary_progress { - width: 100%; - padding: 4px; - } -} - -// Fix button styling in tiles -.fc-document-tile { - .btn-link { - text-decoration: none !important; - - &:hover { - text-decoration: none !important; - } - - .fc-pdf-icon:hover { - opacity: 0.7; - transform: scale(1.1); - transition: all 0.2s ease; - } - } -} - -// ============================================================================= -// APPROVAL SCREENSHOTS GALLERY -// ============================================================================= - -.fc-gallery-section { - background: var(--o-bg-100, var(--bs-tertiary-bg)); - border: 2px solid var(--o-border-color, var(--bs-border-color)); - border-radius: 8px; - padding: 16px; - margin-top: 8px; - - .fc-gallery-header { - padding-bottom: 12px; - - .fc-tile-label { - font-size: 12px; - font-weight: 700; - text-transform: uppercase; - } - - .badge { - font-size: 11px; - } - - .btn { - font-size: 12px; - padding: 4px 10px; - } - } - - .fc-gallery-content { - padding-top: 8px; - - // Style the many2many_binary widget as a gallery - .o_field_many2many_binary { - display: flex !important; - flex-wrap: wrap !important; - gap: 12px !important; - justify-content: flex-start !important; - align-items: flex-start !important; - padding-top: 4px !important; - - // Each file item as a thumbnail card - .o_attachments { - display: flex !important; - flex-wrap: wrap !important; - gap: 12px !important; - align-items: flex-start !important; - - .o_attachment { - width: 80px !important; - height: 80px !important; - margin: 0 !important; - border-radius: 6px !important; - overflow: hidden !important; - box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1) !important; - transition: all 0.2s ease !important; - cursor: pointer !important; - position: relative !important; - border: 2px solid transparent !important; - - &:hover { - transform: scale(1.05) !important; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2) !important; - border-color: #0077b6 !important; - } - - // Image preview thumbnail - clicking opens in new tab - .o_image { - width: 100% !important; - height: 100% !important; - object-fit: cover !important; - } - - // File icon for non-images - .o_attachment_icon { - width: 100% !important; - height: 100% !important; - display: flex !important; - align-items: center !important; - justify-content: center !important; - background: #e9ecef !important; - - i { - font-size: 28px !important; - color: #6c757d !important; - } - } - - // Hide filename inside thumbnail - .o_attachment_name { - display: none !important; - } - - // Delete button styling - .o_attachment_delete { - position: absolute !important; - top: 2px !important; - right: 2px !important; - background: rgba(220, 53, 69, 0.9) !important; - color: white !important; - border-radius: 50% !important; - width: 18px !important; - height: 18px !important; - display: flex !important; - align-items: center !important; - justify-content: center !important; - font-size: 10px !important; - opacity: 0 !important; - transition: opacity 0.2s !important; - z-index: 5 !important; - } - - &:hover .o_attachment_delete { - opacity: 1 !important; - } - } - } - - // Upload button - inline compact style - .o_attach, - button.o_attach, - .o_select_file_button { - display: inline-flex !important; - align-items: center !important; - justify-content: center !important; - gap: 4px !important; - padding: 6px 12px !important; - border: 1px solid #28a745 !important; - border-radius: 4px !important; - background: white !important; - color: #28a745 !important; - font-size: 12px !important; - font-weight: 500 !important; - cursor: pointer !important; - transition: all 0.2s ease !important; - height: auto !important; - width: auto !important; - min-height: 32px !important; - margin-top: 4px !important; - - &:hover { - background: #28a745 !important; - color: white !important; - } - - i, .fa { - font-size: 12px !important; - margin: 0 !important; - } - } - } - } - - .fc-gallery-empty { - padding: 16px; - - .fa { - color: #adb5bd; - } - } -} - -// Google Places Autocomplete dropdown - ensure it appears above Odoo modals -.pac-container { - z-index: 100000 !important; -} - - diff --git a/fusion_claims/fusion_claims/static/src/xml/document_preview.xml b/fusion_claims/fusion_claims/static/src/xml/document_preview.xml deleted file mode 100644 index b9fc0b2..0000000 --- a/fusion_claims/fusion_claims/static/src/xml/document_preview.xml +++ /dev/null @@ -1,204 +0,0 @@ - - - - - -

      - - - - -
      - -
      -
      -
      - Loading... -
      -

      Loading document...

      -
      -
      - - -