This commit is contained in:
gsinghpal
2026-03-16 08:14:56 -04:00
parent fdca9518ab
commit e56974d46f
196 changed files with 19739 additions and 3471 deletions

View File

@@ -348,13 +348,13 @@ class AssessmentPortal(CustomerPortal):
vals = {
'signature_page_11': signature_data,
'signature_page_11_name': signer_name,
'signature_page_11_date': datetime.now(),
'signature_page_11_date': fields.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(),
'signature_page_12_date': fields.Datetime.now(),
}
else:
return {'success': False, 'error': 'Invalid signature type'}
@@ -1018,227 +1018,6 @@ class AssessmentPortal(CustomerPortal):
('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
# ==========================================================================