1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
# -*- coding: utf-8 -*-
from odoo import api, models, _
from odoo.exceptions import UserError
class SaleOrder(models.Model):
_inherit = "sale.order"
def _cart_find_product_line(self, product_id=None, line_id=None, **kwargs):
self.ensure_one()
lines = super(SaleOrder, self)._cart_find_product_line(product_id, line_id)
if line_id:
return lines
domain = [('id', 'in', lines.ids)]
if self.env.context.get("event_ticket_id"):
domain.append(('event_ticket_id', '=', self.env.context.get("event_ticket_id")))
return self.env['sale.order.line'].sudo().search(domain)
def _website_product_id_change(self, order_id, product_id, qty=0):
order = self.env['sale.order'].sudo().browse(order_id)
if self._context.get('pricelist') != order.pricelist_id.id:
self = self.with_context(pricelist=order.pricelist_id.id)
values = super(SaleOrder, self)._website_product_id_change(order_id, product_id, qty=qty)
event_ticket_id = None
if self.env.context.get("event_ticket_id"):
event_ticket_id = self.env.context.get("event_ticket_id")
else:
product = self.env['product.product'].browse(product_id)
if product.event_ticket_ids:
event_ticket_id = product.event_ticket_ids[0].id
if event_ticket_id:
ticket = self.env['event.event.ticket'].browse(event_ticket_id)
if product_id != ticket.product_id.id:
raise UserError(_("The ticket doesn't match with this product."))
values['product_id'] = ticket.product_id.id
values['event_id'] = ticket.event_id.id
values['event_ticket_id'] = ticket.id
if order.pricelist_id.discount_policy == 'without_discount':
values['price_unit'] = ticket.price
else:
values['price_unit'] = ticket.price_reduce
values['name'] = ticket._get_ticket_multiline_description()
# avoid writing related values that end up locking the product record
values.pop('event_ok', None)
return values
def _cart_update(self, product_id=None, line_id=None, add_qty=0, set_qty=0, **kwargs):
OrderLine = self.env['sale.order.line']
try:
if add_qty:
add_qty = float(add_qty)
except ValueError:
add_qty = 1
try:
if set_qty:
set_qty = float(set_qty)
except ValueError:
set_qty = 0
if line_id:
line = OrderLine.browse(line_id)
ticket = line.event_ticket_id
old_qty = int(line.product_uom_qty)
if ticket.id:
self = self.with_context(event_ticket_id=ticket.id, fixed_price=1)
else:
line = None
ticket = self.env['event.event.ticket'].search([('product_id', '=', product_id)], limit=1)
old_qty = 0
new_qty = set_qty if set_qty else (add_qty or 0 + old_qty)
# case: buying tickets for a sold out ticket
values = {}
if ticket and ticket.seats_limited and ticket.seats_available <= 0:
values['warning'] = _('Sorry, The %(ticket)s tickets for the %(event)s event are sold out.') % {
'ticket': ticket.name,
'event': ticket.event_id.name}
new_qty, set_qty, add_qty = 0, 0, -old_qty
# case: buying tickets, too much attendees
elif ticket and ticket.seats_limited and new_qty > ticket.seats_available:
values['warning'] = _('Sorry, only %(remaining_seats)d seats are still available for the %(ticket)s ticket for the %(event)s event.') % {
'remaining_seats': ticket.seats_available,
'ticket': ticket.name,
'event': ticket.event_id.name}
new_qty, set_qty, add_qty = ticket.seats_available, ticket.seats_available, 0
values.update(super(SaleOrder, self)._cart_update(product_id, line_id, add_qty, set_qty, **kwargs))
# removing attendees
if ticket and new_qty < old_qty:
attendees = self.env['event.registration'].search([
('state', '!=', 'cancel'),
('sale_order_id', 'in', self.ids), # To avoid break on multi record set
('event_ticket_id', '=', ticket.id),
], offset=new_qty, limit=(old_qty - new_qty), order='create_date asc')
attendees.action_cancel()
# adding attendees
elif ticket and new_qty > old_qty:
# do not do anything, attendees will be created at SO confirmation if not given previously
pass
return values
class SaleOrderLine(models.Model):
_inherit = "sale.order.line"
@api.depends('product_id.display_name', 'event_ticket_id.display_name')
def _compute_name_short(self):
""" If the sale order line concerns a ticket, we don't want the product name, but the ticket name instead.
"""
super(SaleOrderLine, self)._compute_name_short()
for record in self:
if record.event_ticket_id:
record.name_short = record.event_ticket_id.display_name
|