update
This commit is contained in:
@@ -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
|
||||
# ==========================================================================
|
||||
|
||||
Reference in New Issue
Block a user