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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# -*- coding: utf-8 -*-
##############################################################################
#
# Purchase - Computed Purchase Order Module for Odoo
# Copyright (C) 2016-Today: La Louve (<http://www.lalouve.net/>)
# @author Julien WESTE
# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, fields, api
from datetime import datetime, timedelta
class ShiftTicket(models.Model):
_inherit = 'event.event.ticket'
_name = 'shift.ticket'
_description = 'Shift Ticket'
SHIFT_TYPE_SELECTION = [
('standard', 'Standard'),
('ftop', 'FTOP'),
]
shift_type = fields.Selection(
selection=SHIFT_TYPE_SELECTION, string='Shift type',
compute='compute_shift_type', store=True)
name = fields.Char(translate=False)
shift_id = fields.Many2one(
'shift.shift', "Shift", required=True, ondelete='cascade')
event_id = fields.Many2one(required=False)
product_id = fields.Many2one(
default=lambda self: self._default_product_id(),
domain=[("shift_type_id", "!=", False)],)
registration_ids = fields.One2many(
'shift.registration', 'shift_ticket_id', 'Registrations')
date_begin = fields.Datetime(related="shift_id.date_begin", store=True)
begin_date_string = fields.Char(
string='Begin Date', compute='_compute_begin_date_fields', store=True,)
user_ids = fields.Many2many(
'res.partner', related="shift_id.user_ids", store=True)
user_id = fields.Many2one(
'res.partner', related="shift_id.user_id", store=True)
hide_in_member_space = fields.Boolean(
"Masquer dans l'Espace Membre", default=False,
compute="_compute_hide_in_member_space", store=True)
state = fields.Selection([
('draft', 'Unconfirmed'), ('cancel', 'Cancelled'),
('confirm', 'Confirmed'), ('done', 'Done')], related="shift_id.state",
store=True)
ticket_active = fields.Boolean(related="shift_id.active", store=True)
@api.multi
@api.depends('shift_id.shift_type_id.is_ftop')
def _compute_hide_in_member_space(self):
for ticket in self:
if ticket.shift_id.shift_type_id.is_ftop:
ticket.hide_in_member_space = True
else:
ticket.hide_in_member_space = False
@api.multi
@api.depends('date_begin')
def _compute_begin_date_fields(self):
for ticket in self:
ticket.begin_date_string = ticket.date_begin and datetime.strftime(
datetime.strptime(ticket.date_begin, "%Y-%m-%d %H:%M:%S") +
timedelta(hours=2), "%d/%m/%Y %H:%M:%S") or False
@api.model
def _default_product_id(self):
try:
product = self.env['ir.model.data'].get_object(
'coop_shift', 'product_product_event')
return product.id
except ValueError:
return False
seats_availability = fields.Selection(
compute='_compute_seats', store=False, required=False)
seats_reserved = fields.Integer(
compute='_compute_seats', store=False)
seats_available = fields.Integer(
compute='_compute_seats', store=False)
seats_unconfirmed = fields.Integer(
compute='_compute_seats', store=False)
seats_used = fields.Integer(
compute='_compute_seats', store=False)
@api.depends('product_id')
@api.multi
def compute_shift_type(self):
for ticket in self:
if ticket.product_id.id ==\
self.env.ref("coop_shift.product_product_shift_ftop").id:
ticket.shift_type = 'ftop'
else:
ticket.shift_type = 'standard'
@api.multi
@api.depends('seats_max', 'registration_ids.state')
def _compute_seats(self):
""" Determine reserved, available, reserved but unconfirmed and used
seats. """
# initialize fields to 0 + compute seats availability
for ticket in self:
ticket.seats_unconfirmed = ticket.seats_reserved =\
ticket.seats_used = ticket.seats_available = 0
# aggregate registrations by ticket and by state
if self.ids:
state_field = {
'draft': 'seats_reserved',
'open': 'seats_reserved',
'done': 'seats_used',
}
query = """ SELECT shift_ticket_id, state, count(shift_id)
FROM shift_registration
WHERE shift_ticket_id IN %s
AND state IN ('draft', 'open', 'done')
GROUP BY shift_ticket_id, state
"""
self._cr.execute(query, (tuple(self.ids),))
for shift_ticket_id, state, num in self._cr.fetchall():
ticket = self.browse(shift_ticket_id)
ticket[state_field[state]] += num
# compute seats_available
for ticket in self:
ticket.seats_available = ticket.seats_max - (
ticket.seats_reserved + ticket.seats_used)
@api.onchange('product_id')
def onchange_product_id(self):
price = self.product_id.list_price if self.product_id else 0
return {'value': {'price': price}}
@api.one
@api.constrains('registration_ids', 'seats_max')
def _check_seats_limit(self):
return True