event_booth_sale/models/sale_order_line.py

121 lines
5.8 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError
class SaleOrderLine(models.Model):
_inherit = 'sale.order.line'
event_booth_category_id = fields.Many2one('event.booth.category', string='Booths Category', ondelete='set null')
event_booth_pending_ids = fields.Many2many(
'event.booth', string='Pending Booths', search='_search_event_booth_pending_ids',
compute='_compute_event_booth_pending_ids', inverse='_inverse_event_booth_pending_ids',
help='Used to create registration when providing the desired event booth.'
)
event_booth_registration_ids = fields.One2many(
'event.booth.registration', 'sale_order_line_id', string='Confirmed Registration')
event_booth_ids = fields.One2many('event.booth', 'sale_order_line_id', string='Confirmed Booths')
is_event_booth = fields.Boolean(compute='_compute_is_event_booth')
@api.depends('product_id.type')
def _compute_is_event_booth(self):
for record in self:
record.is_event_booth = record.product_id.detailed_type == 'event_booth'
@api.depends('event_booth_ids')
def _compute_name_short(self):
wbooth = self.filtered(lambda line: line.event_booth_pending_ids)
for record in wbooth:
record.name_short = record.event_booth_pending_ids.event_id.name
super(SaleOrderLine, self - wbooth)._compute_name_short()
@api.depends('event_booth_registration_ids')
def _compute_event_booth_pending_ids(self):
for so_line in self:
so_line.event_booth_pending_ids = so_line.event_booth_registration_ids.event_booth_id
def _inverse_event_booth_pending_ids(self):
""" This method will take care of creating the event.booth.registrations based on selected booths.
It will also unlink ones that are de-selected. """
for so_line in self:
existing_booths = so_line.event_booth_registration_ids.event_booth_id or self.env[
'event.booth']
selected_booths = so_line.event_booth_pending_ids
so_line.event_booth_registration_ids.filtered(
lambda reg: reg.event_booth_id not in selected_booths).unlink()
self.env['event.booth.registration'].create([{
'event_booth_id': booth.id,
'sale_order_line_id': so_line.id,
'partner_id': so_line.order_id.partner_id.id
} for booth in selected_booths - existing_booths])
def _search_event_booth_pending_ids(self, operator, value):
return [('event_booth_registration_ids.event_booth_id', operator, value)]
@api.constrains('event_booth_registration_ids')
def _check_event_booth_registration_ids(self):
if len(self.event_booth_registration_ids.event_booth_id.event_id) > 1:
raise ValidationError(_('Registrations from the same Order Line must belong to a single event.'))
@api.onchange('product_id')
def _onchange_product_id_booth(self):
"""We reset the event when the selected product doesn't belong to any pending booths."""
if self.event_id and (not self.product_id or self.product_id not in self.event_booth_pending_ids.product_id):
self.event_id = None
@api.onchange('event_id')
def _onchange_event_id_booth(self):
"""We reset the pending booths when the event changes to avoid inconsistent state."""
if self.event_booth_pending_ids and (not self.event_id or self.event_id != self.event_booth_pending_ids.event_id):
self.event_booth_pending_ids = None
@api.depends('event_booth_pending_ids')
def _compute_name(self):
"""Override to add the compute dependency.
The custom name logic can be found below in _get_sale_order_line_multiline_description_sale.
"""
super()._compute_name()
def _update_event_booths(self, set_paid=False):
for so_line in self.filtered('is_event_booth'):
if so_line.event_booth_pending_ids and not so_line.event_booth_ids:
unavailable = so_line.event_booth_pending_ids.filtered(lambda booth: not booth.is_available)
if unavailable:
raise ValidationError(
_('The following booths are unavailable, please remove them to continue : %(booth_names)s',
booth_names=''.join('\n\t- %s' % booth.display_name for booth in unavailable)))
so_line.event_booth_registration_ids.sudo().action_confirm()
if so_line.event_booth_ids and set_paid:
so_line.event_booth_ids.sudo().action_set_paid()
return True
def _get_sale_order_line_multiline_description_sale(self):
if self.event_booth_pending_ids:
return self.event_booth_pending_ids._get_booth_multiline_description()
return super()._get_sale_order_line_multiline_description_sale()
def _use_template_name(self):
""" We do not want configured description to get rewritten by template default"""
if self.event_booth_pending_ids:
return False
return super()._use_template_name()
def _get_display_price(self):
if self.event_booth_pending_ids and self.event_id:
company = self.event_id.company_id or self.env.company
pricelist = self.order_id.pricelist_id
if pricelist.discount_policy == "with_discount":
event_booths = self.event_booth_pending_ids.with_context(**self._get_pricelist_price_context())
total_price = sum(booth.booth_category_id.price_reduce for booth in event_booths)
else:
total_price = sum(booth.price for booth in self.event_booth_pending_ids)
return self._convert_to_sol_currency(total_price, company.currency_id)
return super()._get_display_price()