sale_order_line.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. # -*- coding: utf-8 -*-
  2. # Part of Odoo. See LICENSE file for full copyright and licensing details.
  3. from odoo import api, fields, models, _
  4. from odoo.exceptions import ValidationError
  5. class SaleOrderLine(models.Model):
  6. _inherit = 'sale.order.line'
  7. event_booth_category_id = fields.Many2one('event.booth.category', string='Booths Category', ondelete='set null')
  8. event_booth_pending_ids = fields.Many2many(
  9. 'event.booth', string='Pending Booths', search='_search_event_booth_pending_ids',
  10. compute='_compute_event_booth_pending_ids', inverse='_inverse_event_booth_pending_ids',
  11. help='Used to create registration when providing the desired event booth.'
  12. )
  13. event_booth_registration_ids = fields.One2many(
  14. 'event.booth.registration', 'sale_order_line_id', string='Confirmed Registration')
  15. event_booth_ids = fields.One2many('event.booth', 'sale_order_line_id', string='Confirmed Booths')
  16. is_event_booth = fields.Boolean(compute='_compute_is_event_booth')
  17. @api.depends('product_id.type')
  18. def _compute_is_event_booth(self):
  19. for record in self:
  20. record.is_event_booth = record.product_id.detailed_type == 'event_booth'
  21. @api.depends('event_booth_ids')
  22. def _compute_name_short(self):
  23. wbooth = self.filtered(lambda line: line.event_booth_pending_ids)
  24. for record in wbooth:
  25. record.name_short = record.event_booth_pending_ids.event_id.name
  26. super(SaleOrderLine, self - wbooth)._compute_name_short()
  27. @api.depends('event_booth_registration_ids')
  28. def _compute_event_booth_pending_ids(self):
  29. for so_line in self:
  30. so_line.event_booth_pending_ids = so_line.event_booth_registration_ids.event_booth_id
  31. def _inverse_event_booth_pending_ids(self):
  32. for so_line in self:
  33. self.env['event.booth.registration'].create([{
  34. 'event_booth_id': booth.id,
  35. 'sale_order_line_id': so_line.id,
  36. 'partner_id': so_line.order_id.partner_id.id
  37. } for booth in so_line.event_booth_pending_ids])
  38. def _search_event_booth_pending_ids(self, operator, value):
  39. return [('event_booth_registration_ids.event_booth_id', operator, value)]
  40. @api.constrains('event_booth_registration_ids')
  41. def _check_event_booth_registration_ids(self):
  42. if len(self.event_booth_registration_ids.event_booth_id.event_id) > 1:
  43. raise ValidationError(_('Registrations from the same Order Line must belong to a single event.'))
  44. @api.onchange('product_id')
  45. def _onchange_product_id_booth(self):
  46. """We reset the event when the selected product doesn't belong to any pending booths."""
  47. if self.event_id and (not self.product_id or self.product_id not in self.event_booth_pending_ids.product_id):
  48. self.event_id = None
  49. @api.onchange('event_id')
  50. def _onchange_event_id_booth(self):
  51. """We reset the pending booths when the event changes to avoid inconsistent state."""
  52. if self.event_booth_pending_ids and (not self.event_id or self.event_id != self.event_booth_pending_ids.event_id):
  53. self.event_booth_pending_ids = None
  54. @api.depends('event_booth_pending_ids')
  55. def _compute_name(self):
  56. """Override to add the compute dependency.
  57. The custom name logic can be found below in _get_sale_order_line_multiline_description_sale.
  58. """
  59. super()._compute_name()
  60. def _update_event_booths(self, set_paid=False):
  61. for so_line in self.filtered('is_event_booth'):
  62. if so_line.event_booth_pending_ids and not so_line.event_booth_ids:
  63. unavailable = so_line.event_booth_pending_ids.filtered(lambda booth: not booth.is_available)
  64. if unavailable:
  65. raise ValidationError(
  66. _('The following booths are unavailable, please remove them to continue : %(booth_names)s',
  67. booth_names=''.join('\n\t- %s' % booth.display_name for booth in unavailable)))
  68. so_line.event_booth_registration_ids.sudo().action_confirm()
  69. if so_line.event_booth_ids and set_paid:
  70. so_line.event_booth_ids.sudo().action_set_paid()
  71. return True
  72. def _get_sale_order_line_multiline_description_sale(self):
  73. if self.event_booth_pending_ids:
  74. return self.event_booth_pending_ids._get_booth_multiline_description()
  75. return super()._get_sale_order_line_multiline_description_sale()
  76. def _get_display_price(self):
  77. if self.event_booth_pending_ids and self.event_id:
  78. company = self.event_id.company_id or self.env.company
  79. currency = company.currency_id
  80. pricelist = self.order_id.pricelist_id
  81. if pricelist.discount_policy == "with_discount":
  82. total_price = sum([booth.booth_category_id.with_context(pricelist=pricelist.id).price_reduce for booth in self.event_booth_pending_ids])
  83. else:
  84. total_price = sum([booth.price for booth in self.event_booth_pending_ids])
  85. return currency._convert(
  86. total_price, self.order_id.currency_id,
  87. self.order_id.company_id or self.env.company.id,
  88. self.order_id.date_order or fields.Date.today())
  89. return super()._get_display_price()