Files
Odoo-Modules/Work in Progress/fusion_quotations/models/wc_assessment_line.py
gsinghpal fc3c966484 changes
2026-03-13 12:38:28 -04:00

98 lines
3.9 KiB
Python

# -*- coding: utf-8 -*-
from odoo import api, fields, models, _
class WheelchairAssessmentLine(models.Model):
_name = 'fusion.wc.assessment.line'
_description = 'Wheelchair Assessment Line Item'
_order = 'section_sequence, sequence, id'
assessment_id = fields.Many2one('fusion.wc.assessment', string='Assessment',
required=True, ondelete='cascade', index=True)
section_id = fields.Many2one('fusion.wc.section', string='Section', index=True)
section_sequence = fields.Integer(
related='section_id.sequence', store=True, string='Section Order')
sequence = fields.Integer(string='Sequence', default=10)
# Product
product_id = fields.Many2one('product.product', string='Product', index=True)
product_name = fields.Char(string='Description',
help='Can override product name with custom description')
quantity = fields.Float(string='Quantity', default=1.0)
# ADP info
adp_device_code = fields.Char(string='ADP Code')
adp_price = fields.Float(string='ADP Price', digits='Product Price')
unit_price = fields.Float(string='Selling Price', digits='Product Price')
# Build type (for seating items)
build_type = fields.Selection([
('modular', 'Modular'),
('custom_fabricated', 'Custom Fabricated'),
], string='Build Type')
# Clinical rationale (required for certain items)
clinical_rationale = fields.Text(string='Clinical Rationale')
# Computed pricing
subtotal = fields.Float(string='Subtotal',
compute='_compute_subtotal', store=True, digits='Product Price')
adp_portion = fields.Float(string='ADP Portion',
compute='_compute_portions', store=True, digits='Product Price')
client_portion = fields.Float(string='Client Portion',
compute='_compute_portions', store=True, digits='Product Price')
# Upcharge tracking
is_upcharge = fields.Boolean(string='Auto-Applied Upcharge', default=False)
upcharge_rule_id = fields.Many2one('fusion.wc.upcharge.rule',
string='Triggered By Rule')
upcharge_reason = fields.Char(string='Upcharge Reason')
# Section-specific measurements
width = fields.Float(string='Width', digits=(10, 2))
depth = fields.Float(string='Depth', digits=(10, 2))
height = fields.Float(string='Height', digits=(10, 2))
notes = fields.Text(string='Notes')
@api.depends('unit_price', 'quantity')
def _compute_subtotal(self):
for line in self:
line.subtotal = line.unit_price * line.quantity
@api.depends('subtotal', 'adp_price', 'quantity', 'assessment_id.client_type')
def _compute_portions(self):
"""Estimate ADP and client portions based on client type and ADP price."""
for line in self:
if not line.adp_price or not line.subtotal:
line.adp_portion = 0.0
line.client_portion = line.subtotal
continue
client_type = line.assessment_id.client_type or 'reg'
adp_base = line.adp_price * line.quantity
# Determine ADP coverage percentage
if client_type == 'reg':
# REG: 75% ADP, 25% client
adp_amount = adp_base * 0.75
else:
# ODS, ACS, OWP, etc.: 100% ADP
adp_amount = adp_base
# Client pays the rest (including anything above ADP price)
line.adp_portion = min(adp_amount, line.subtotal)
line.client_portion = line.subtotal - line.adp_portion
@api.onchange('product_id')
def _onchange_product_id(self):
"""Auto-fill ADP code and pricing from product."""
if self.product_id:
tmpl = self.product_id.product_tmpl_id
self.adp_device_code = tmpl.x_fc_adp_device_code or ''
self.adp_price = tmpl.x_fc_adp_price or 0.0
self.unit_price = self.product_id.lst_price
if not self.product_name:
self.product_name = self.product_id.display_name