142 lines
4.9 KiB
Python
142 lines
4.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Copyright 2024-2026 Nexa Systems Inc.
|
|
# License OPL-1 (Odoo Proprietary License v1.0)
|
|
|
|
from odoo import api, fields, models
|
|
|
|
|
|
class ProductTemplate(models.Model):
|
|
_inherit = 'product.template'
|
|
|
|
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',
|
|
)
|
|
|
|
x_fc_equipment_type = fields.Selection([
|
|
('type_1_walker', 'Type 1 Walker'),
|
|
('type_2_mw', 'Type 2 MW'),
|
|
('type_2_pw', 'Type 2 PW'),
|
|
('type_2_walker', 'Type 2 Walker'),
|
|
('type_3_mw', 'Type 3 MW'),
|
|
('type_3_pw', 'Type 3 PW'),
|
|
('type_3_walker', 'Type 3 Walker'),
|
|
('type_4_mw', 'Type 4 MW'),
|
|
('type_5_mw', 'Type 5 MW'),
|
|
('ceiling_lift', 'Ceiling Lift'),
|
|
('mobility_scooter', 'Mobility Scooter'),
|
|
('patient_lift', 'Patient Lift'),
|
|
('transport_wheelchair', 'Transport Wheelchair'),
|
|
('standard_wheelchair', 'Standard Wheelchair'),
|
|
('power_wheelchair', 'Power Wheelchair'),
|
|
('cushion', 'Cushion'),
|
|
('backrest', 'Backrest'),
|
|
('stairlift', 'Stairlift'),
|
|
('others', 'Others'),
|
|
], string='Equipment Type')
|
|
|
|
x_fc_wheelchair_category = fields.Selection([
|
|
('type_1', 'Type 1'),
|
|
('type_2', 'Type 2'),
|
|
('type_3', 'Type 3'),
|
|
('type_4', 'Type 4'),
|
|
('type_5', 'Type 5'),
|
|
], string='Wheelchair Category')
|
|
|
|
x_fc_seat_width = fields.Char(string='Seat Width')
|
|
x_fc_seat_depth = fields.Char(string='Seat Depth')
|
|
x_fc_seat_height = fields.Char(string='Seat Height')
|
|
|
|
x_fc_storage_location = fields.Selection([
|
|
('warehouse', 'Warehouse'),
|
|
('westin_brampton', 'Westin Brampton'),
|
|
('mobility_etobicoke', 'Mobility Etobicoke'),
|
|
('scarborough_storage', 'Scarborough Storage'),
|
|
('client_loaned', 'Client/Loaned'),
|
|
('rented_out', 'Rented Out'),
|
|
], string='Storage Location')
|
|
|
|
x_fc_listing_type = fields.Selection([
|
|
('owned', 'Owned'),
|
|
('borrowed', 'Borrowed'),
|
|
], string='Listing Type')
|
|
|
|
x_fc_asset_number = fields.Char(string='Asset Number')
|
|
x_fc_package_info = fields.Text(string='Package Information')
|
|
|
|
x_fc_security_deposit_type = fields.Selection(
|
|
[
|
|
('fixed', 'Fixed Amount'),
|
|
('percentage', 'Percentage of Rental Price'),
|
|
],
|
|
string='Security Deposit Type',
|
|
)
|
|
x_fc_security_deposit_amount = fields.Float(
|
|
string='Security Deposit Amount',
|
|
digits='Product Price',
|
|
)
|
|
x_fc_security_deposit_percent = fields.Float(
|
|
string='Security Deposit (%)',
|
|
)
|
|
|
|
x_flm_current_location = fields.Char(
|
|
string='Current Location',
|
|
compute='_compute_current_location',
|
|
help='Current stock location of this loaner product based on inventory quants',
|
|
)
|
|
x_flm_serial_count = fields.Integer(
|
|
string='Serial Numbers',
|
|
compute='_compute_serial_count',
|
|
)
|
|
|
|
@api.depends('product_variant_ids')
|
|
def _compute_serial_count(self):
|
|
for tmpl in self:
|
|
tmpl.x_flm_serial_count = self.env['stock.lot'].sudo().search_count([
|
|
('product_id', 'in', tmpl.product_variant_ids.ids),
|
|
])
|
|
|
|
def action_view_serial_numbers(self):
|
|
self.ensure_one()
|
|
return {
|
|
'type': 'ir.actions.act_window',
|
|
'name': 'Serial Numbers',
|
|
'res_model': 'stock.lot',
|
|
'view_mode': 'list,form',
|
|
'domain': [('product_id', 'in', self.product_variant_ids.ids)],
|
|
'context': {'default_product_id': self.product_variant_ids[:1].id},
|
|
}
|
|
|
|
@api.depends('product_variant_ids')
|
|
def _compute_current_location(self):
|
|
for tmpl in self:
|
|
if not tmpl.x_fc_can_be_loaned:
|
|
tmpl.x_flm_current_location = False
|
|
continue
|
|
quants = self.env['stock.quant'].sudo().search([
|
|
('product_id', 'in', tmpl.product_variant_ids.ids),
|
|
('quantity', '>', 0),
|
|
('location_id.usage', '=', 'internal'),
|
|
], limit=5)
|
|
if quants:
|
|
locations = quants.mapped('location_id.complete_name')
|
|
tmpl.x_flm_current_location = ', '.join(set(locations))
|
|
else:
|
|
tmpl.x_flm_current_location = False
|