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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# -*- coding: utf-8 -*-
##############################################################################
#
# Author: Guewen Baconnier
# Copyright 2013 Camptocamp SA
#
# 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/>.
#
##############################################################################
"""
The checkpoint is a model containing records to be reviewed by the end
users. The connectors register records to verify so the user can check
them and flag them as reviewed.
A concrete use case is the import of new products from Magento. Once
they are imported, the user have to configure things like the supplier,
so they appears in this list.
"""
from openerp import models, fields, api, _
import logging
_logger = logging.getLogger(__name__)
class ConnectorCheckpoint(models.Model):
_name = 'connector.checkpoint'
_description = 'Connector Checkpoint'
_inherit = ['mail.thread', 'ir.needaction_mixin']
@api.model
def _reference_models(self):
models = self.env['ir.model'].search([('state', '!=', 'manual')])
return [(model.model, model.name)
for model in models
if not model.model.startswith('ir.')]
@api.depends('model_id', 'record_id')
def _compute_record(self):
for item in self:
if not (item.model_id and item.record_id):
item.record = None
continue
item.record = item.model_id.model + ',' + str(item.record_id)
@api.depends('model_id', 'record_id')
def _compute_name(self):
for item in self:
if item.message:
item.name = item.message
else:
model = self.env[item.model_id.model]
item.name = model.browse(item.record_id).display_name
@api.model
def _search_record(self, operator, value):
model_model = self.env['ir.model']
sql = "SELECT DISTINCT model_id FROM connector_checkpoint"
self.env.cr.execute(sql)
model_ids = [row[0] for row in self.env.cr.fetchall()]
models = model_model.browse(model_ids)
ids = set()
for model in models:
model_id = model.id
model_name = model.model
model_obj = self.env[model_name]
results = model_obj.name_search(name=value,
operator=operator)
res_ids = [res[0] for res in results]
checks = self.search([('model_id', '=', model_id),
('record_id', 'in', res_ids)])
ids.update(checks.ids)
if not ids:
return [('id', '=', '0')]
return [('id', 'in', tuple(ids))]
record = fields.Reference(
compute='_compute_record',
selection='_reference_models',
help="The record to review.",
readonly=True,
)
name = fields.Char(
compute='_compute_name',
search='_search_record',
string='Record Name',
help="Name of the record to review",
readonly=True,
)
record_id = fields.Integer(string='Record ID',
required=False,
readonly=True)
model_id = fields.Many2one(comodel_name='ir.model',
string='Model',
required=False,
readonly=True)
backend_id = fields.Reference(
string='Imported from',
selection='_reference_models',
readonly=True,
required=True,
help="The record has been imported from this backend",
select=True,
)
state = fields.Selection(
selection=[('need_review', 'Need Review'),
('reviewed', 'Reviewed')],
string='Status',
required=True,
readonly=True,
default='need_review',
)
message = fields.Char(
string='Message',
help="Review message",
readonly=True,
required=False,
)
_sql_constraints = [
('required_fields',
"CHECK (record_id IS NOT NULL OR message IS NOT NULL)",
_("Provide relation to a record or a message.")),
]
@api.multi
def reviewed(self):
return self.write({'state': 'reviewed'})
@api.multi
def _subscribe_users(self):
""" Subscribe all users having the 'Connector Manager' group """
group = self.env.ref('connector.group_connector_manager')
if not group:
return
users = self.env['res.users'].search([('groups_id', '=', group.id)])
self.message_subscribe_users(user_ids=users.ids)
@api.model
def create(self, vals):
record = super(ConnectorCheckpoint, self).create(vals)
record._subscribe_users()
if record.message:
msg = record.message
else:
msg = _('A %s needs a review.') % record.model_id.name
record.message_post(body=msg, subtype='mail.mt_comment',)
return record
@api.model
def create_from_name(self, model_name, record_id,
backend_model_name, backend_id, message=''):
model_model = self.env['ir.model']
model = model_model.search([('model', '=', model_name)], limit=1)
assert model, "The model %s does not exist" % model_name
backend = backend_model_name + ',' + str(backend_id)
return self.create({'model_id': model.id,
'record_id': record_id,
'backend_id': backend,
'message': message})
@api.model
def create_from_message(self, backend_model_name, backend_id, message):
backend = backend_model_name + ',' + str(backend_id)
return self.create({'message': message,
'backend_id': backend})
@api.model
def _needaction_domain_get(self):
""" Returns the domain to filter records that require an action
:return: domain or False is no action
"""
return [('state', '=', 'need_review')]
def add_checkpoint(session, model_name, record_id,
backend_model_name, backend_id, message=''):
_logger.warn(
"`add_checkpoint` is deprecated. "
"Please, use `backend_record.add_checkpoint`"
)
checkpoint_model = session.env['connector.checkpoint']
return checkpoint_model.create_from_name(model_name, record_id,
backend_model_name, backend_id,
message=message)
def add_checkpoint_message(session, backend_model_name, backend_id, message):
_logger.warn(
"`add_checkpoint_message` is deprecated. "
"Please, use `backend_record.add_checkpoint`"
)
checkpoint_model = session.env['connector.checkpoint']
return checkpoint_model.create_from_message(
backend_model_name, backend_id, message)
class connector_checkpoint_review(models.TransientModel):
_name = 'connector.checkpoint.review'
_description = 'Checkpoints Review'
@api.model
def _get_checkpoint_ids(self):
res = False
context = self.env.context
if (context.get('active_model') == 'connector.checkpoint' and
context.get('active_ids')):
res = context['active_ids']
return res
checkpoint_ids = fields.Many2many(
comodel_name='connector.checkpoint',
relation='connector_checkpoint_review_rel',
column1='review_id',
column2='checkpoint_id',
string='Checkpoints',
domain="[('state', '=', 'need_review')]",
default=_get_checkpoint_ids)
@api.multi
def review(self):
self.checkpoint_ids.reviewed()
return {'type': 'ir.actions.act_window_close'}