def action_confirm(self): if self._uid != self.create_uid.id: raise Warning( _("You can't confirm purchase indent which is \ requested by %s!") % (self.create_uid.name)) if not self.indent_line: raise Warning(_('No Product Line(s) were found!')) check_pro_qty = [ line.id for line in self.indent_line if line.product_qty ] if not check_pro_qty: raise Warning(_("No Quantity were found for any line!")) self.check_duplicate_product() group_id = self.sudo().env.ref('purchase.group_purchase_manager') if not group_id.users: raise AccessError( _("Please contact your Administrator \n \ No user found under 'Purchase Manager'")) server_id = self.env['ir.mail_server'].search([]) if not server_id: raise AccessError(_("Please configure outgoing mail server")) email_to = ",".join( [user.email for user in group_id.users if user.email]) recipient_ids = [user.partner_id.id for user in group_id.users] if self.env.user.email: product_qty = ''' <table width=100%% border="0" style="font-family: 'Arial'; font-size: 12px;"> <tr> <td><b>''' + _("Product Name") + '''</b></td> <td><b>''' + _("Quantity") + '''</b></td> <td><b>''' + _("Expected Date") + '''</b></td> </tr>''' for line in self.indent_line: qty = (str(formatLang(self.env, line.product_qty, digits=2))) product_qty += '<tr>\ <td>' + str(line.product_id.name) + '</td>\ <td>' + qty + '</td>\ <td>' + str(line.expected_date) + '</td>\ </tr>' msg1 = '<p>Purchase Indent "%s" Confirmed by "%s" for following \ Products Details.</p>' % (self.name, self.env.user.name) msg1 += '<p> %s </p>' % (product_qty) create_values = { 'body_html': msg1, 'subject': 'Purchase Indent Confirmed by %s' % (self.env.user.name), 'email_from': self.env.user.email, 'email_to': email_to, 'model': 'purchase.indent', 'res_id': self.id, 'reply_to': '', 'recipient_ids': [(6, 0, recipient_ids)], } email_id = self.env['mail.mail'].create(create_values) email_id.send() else: raise AccessError(_("Please configure your email")) self.state = 'confirm'
def _search(self, args, offset=0, limit=None, order=None, count=False, access_rights_uid=None): if self._uid != SUPERUSER_ID and args: domain_fields = {term[0] for term in args if isinstance(term, (tuple, list))} if domain_fields.intersection(USER_PRIVATE_FIELDS): raise AccessError(_('Invalid search criterion')) return super(Users, self)._search(args, offset=offset, limit=limit, order=order, count=count, access_rights_uid=access_rights_uid)
def cancel(self): """ cancel one or more order.line, update order status and unlink existing cashmoves """ if self.user_has_groups("lunch.group_lunch_manager"): self.state = 'cancelled' self.cashmove.unlink() else: raise AccessError(_("Only your lunch manager cancels the orders."))
def order(self): """ The order_line is ordered to the vendor but isn't received yet """ if self.user_has_groups("lunch.group_lunch_manager"): self.state = 'ordered' else: raise AccessError( _("Only your lunch manager processes the orders."))
def write(self, values): employee_id = values.get('employee_id', False) if not self._check_state_access_right(values): raise AccessError( _('You cannot set a leave request as \'%s\'. Contact a human resource manager.' ) % values.get('state')) result = super(Holidays, self).write(values) self.add_follower(employee_id) return result
def check_access_rule(self, operation): """ Add Access rules of mail.message for non-employee user: - read: - raise if the type is comment and subtype NULL (internal note) """ if self.user_has_groups('base.group_public'): self.env.cr.execute( 'SELECT id FROM "%s" WHERE website_published IS FALSE AND id = ANY (%%s)' % (self._table), (self.ids, )) if self.env.cr.fetchall(): raise AccessError( _('The requested operation cannot be completed due to security restrictions. Please contact your system administrator.\n\n(Document type: %s, Operation: %s)' ) % (self._description, operation)) return super(MailMessage, self).check_access_rule(operation=operation)
def create(self, values): """ Override to avoid automatic logging of creation """ employee_id = values.get('employee_id', False) if not self._check_state_access_right(values): raise AccessError( _('You cannot set a leave request as \'%s\'. Contact a human resource manager.' ) % values.get('state')) if not values.get('department_id'): values.update({ 'department_id': self.env['hr.employee'].browse(employee_id).department_id.id }) holiday = super( Holidays, self.with_context(mail_create_nolog=True, mail_create_nosubscribe=True)).create(values) holiday.add_follower(employee_id) return holiday
def confirm(self): """ confirm one or more order line, update order status and create new cashmove """ if self.user_has_groups("lunch.group_lunch_manager"): if self.state != 'confirmed': values = { 'user_id': self.user_id.id, 'amount': -self.price, 'description': self.product_id.name, 'order_id': self.id, 'state': 'order', 'date': self.date, } self.env['lunch.cashmove'].create(values) self.state = 'confirmed' else: raise AccessError( _("Only your lunch manager sets the orders as received."))
def check_user(self, uid=None): if uid is None: uid = request.uid is_admin = request.env['res.users'].browse(uid)._is_admin() if not is_admin: raise AccessError(_("Only administrators can upload a module"))
def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True): groupby_fields = set([groupby] if isinstance(groupby, pycompat.string_types) else groupby) if groupby_fields.intersection(USER_PRIVATE_FIELDS): raise AccessError(_("Invalid 'group by' parameter")) return super(Users, self).read_group(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy)
def execute(self): self.ensure_one() if not self.env.user._is_superuser() and not self.env.user.has_group( 'base.group_system'): raise AccessError(_("Only administrators can change the settings")) self = self.with_context(active_test=False) classified = self._get_classified_fields() # default values fields IrDefault = self.env['ir.default'].sudo() for name, model, field in classified['default']: if isinstance(self[name], models.BaseModel): if self._fields[name].type == 'many2one': value = self[name].id else: value = self[name].ids else: value = self[name] IrDefault.set(model, field, value) # group fields: modify group / implied groups for name, groups, implied_group in classified['group']: if self[name]: groups.write({'implied_ids': [(4, implied_group.id)]}) else: groups.write({'implied_ids': [(3, implied_group.id)]}) implied_group.write({ 'users': [(3, user.id) for user in groups.mapped('users')] }) # other fields: execute method 'set_values' # Methods that start with `set_` are now deprecated for method in dir(self): if method.startswith('set_') and method is not 'set_values': _logger.warning( _('Methods that start with `set_` are deprecated. Override `set_values` instead (Method %s)' ) % method) self.set_values() # module fields: install/uninstall the selected modules to_install = [] to_uninstall_modules = self.env['ir.module.module'] lm = len('module_') for name, module in classified['module']: if self[name]: to_install.append((name[lm:], module)) else: if module and module.state in ('installed', 'to upgrade'): to_uninstall_modules += module if to_uninstall_modules: to_uninstall_modules.button_immediate_uninstall() self._install_modules(to_install) if to_install or to_uninstall_modules: # After the uninstall/install calls, the registry and environments # are no longer valid. So we reset the environment. self.env.reset() self = self.env()[self._name] # pylint: disable=next-method-called config = self.env['res.config'].next() or {} if config.get('type') not in ('ir.actions.act_window_close', ): return config # force client-side reload (update user menu and current view) return { 'type': 'ir.actions.client', 'tag': 'reload', }
def read(self, fields=None, load='_classic_read'): if self.search_count([('id', 'in', self._ids), ('name', '=', 'NOACCESS')]): raise AccessError('Sorry') return super(Category, self).read(fields=fields, load=load)
def web_settings_dashboard_data(self, **kw): if not request.env.user.has_group('base.group_erp_manager'): raise AccessError("Access Denied") installed_apps = request.env['ir.module.module'].search_count([ ('application', '=', True), ('state', 'in', ['installed', 'to upgrade', 'to remove']) ]) cr = request.cr cr.execute(""" SELECT count(*) FROM res_users WHERE active=true AND share=false """) active_count = cr.dictfetchall()[0].get('count') cr.execute(""" SELECT count(u.*) FROM res_users u WHERE active=true AND NOT exists(SELECT 1 FROM res_users_log WHERE create_uid=u.id) """) pending_count = cr.dictfetchall()[0].get('count') cr.execute(""" SELECT id, login FROM res_users u WHERE active=true AND NOT exists(SELECT 1 FROM res_users_log WHERE create_uid=u.id) ORDER BY id desc LIMIT 10 """) pending_users = cr.fetchall() # See update.py for this computation limit_date = datetime.now() - timedelta(15) enterprise_users = request.env['res.users'].search_count([ ("login_date", ">=", fields.Datetime.to_string(limit_date)), ('share', '=', False) ]) expiration_date = request.env['ir.config_parameter'].sudo().get_param( 'database.expiration_date') return { 'apps': { 'installed_apps': installed_apps, 'enterprise_users': enterprise_users, }, 'users_info': { 'active_users': active_count, 'pending_count': pending_count, 'pending_users': pending_users, 'user_form_view_id': request.env['ir.model.data'].xmlid_to_res_id( "base.view_users_form"), }, 'share': { 'server_version': release.version, 'expiration_date': expiration_date, 'debug': request.debug, }, 'company': { 'company_id': request.env.user.company_id.id, 'company_name': request.env.user.company_id.name } }
def check_access_rule(self, operation): """ Access rules of mail.message: - read: if - author_id == pid, uid is the author OR - uid is in the recipients (partner_ids) OR - uid has been notified (needaction) OR - uid is member of a listern channel (channel_ids.partner_ids) OR - uid have read access to the related document if model, res_id - otherwise: raise - create: if - no model, no res_id (private message) OR - pid in message_follower_ids if model, res_id OR - uid can read the parent OR - uid have write or create access on the related document if model, res_id, OR - otherwise: raise - write: if - author_id == pid, uid is the author, OR - uid is in the recipients (partner_ids) OR - uid has write or create access on the related document if model, res_id - otherwise: raise - unlink: if - uid has write or create access on the related document if model, res_id - otherwise: raise Specific case: non employee users see only messages with subtype (aka do not see internal logs). """ def _generate_model_record_ids(msg_val, msg_ids): """ :param model_record_ids: {'model': {'res_id': (msg_id, msg_id)}, ... } :param message_values: {'msg_id': {'model': .., 'res_id': .., 'author_id': ..}} """ model_record_ids = {} for id in msg_ids: vals = msg_val.get(id, {}) if vals.get('model') and vals.get('res_id'): model_record_ids.setdefault(vals['model'], set()).add(vals['res_id']) return model_record_ids if self._uid == SUPERUSER_ID: return # Non employees see only messages with a subtype (aka, not internal logs) if not self.env['res.users'].has_group('base.group_user'): self._cr.execute( '''SELECT DISTINCT message.id, message.subtype_id, subtype.internal FROM "%s" AS message LEFT JOIN "mail_message_subtype" as subtype ON message.subtype_id = subtype.id WHERE message.message_type = %%s AND (message.subtype_id IS NULL OR subtype.internal IS TRUE) AND message.id = ANY (%%s)''' % (self._table), ( 'comment', self.ids, )) if self._cr.fetchall(): raise AccessError( _('The requested operation cannot be completed due to security restrictions. Please contact your system administrator.\n\n(Document type: %s, Operation: %s)' ) % (self._description, operation)) # Read mail_message.ids to have their values message_values = dict((res_id, {}) for res_id in self.ids) if operation in ['read', 'write']: self._cr.execute( """ SELECT DISTINCT m.id, m.model, m.res_id, m.author_id, m.parent_id, COALESCE(partner_rel.res_partner_id, needaction_rel.res_partner_id), channel_partner.channel_id as channel_id FROM "%s" m LEFT JOIN "mail_message_res_partner_rel" partner_rel ON partner_rel.mail_message_id = m.id AND partner_rel.res_partner_id = %%(pid)s LEFT JOIN "mail_message_res_partner_needaction_rel" needaction_rel ON needaction_rel.mail_message_id = m.id AND needaction_rel.res_partner_id = %%(pid)s LEFT JOIN "mail_message_mail_channel_rel" channel_rel ON channel_rel.mail_message_id = m.id LEFT JOIN "mail_channel" channel ON channel.id = channel_rel.mail_channel_id LEFT JOIN "mail_channel_partner" channel_partner ON channel_partner.channel_id = channel.id AND channel_partner.partner_id = %%(pid)s WHERE m.id = ANY (%%(ids)s)""" % self._table, dict(pid=self.env.user.partner_id.id, ids=self.ids)) for mid, rmod, rid, author_id, parent_id, partner_id, channel_id in self._cr.fetchall( ): message_values[mid] = { 'model': rmod, 'res_id': rid, 'author_id': author_id, 'parent_id': parent_id, 'notified': any((message_values[mid].get('notified'), partner_id, channel_id)) } else: self._cr.execute( """SELECT DISTINCT id, model, res_id, author_id, parent_id FROM "%s" WHERE id = ANY (%%s)""" % self._table, (self.ids, )) for mid, rmod, rid, author_id, parent_id in self._cr.fetchall(): message_values[mid] = { 'model': rmod, 'res_id': rid, 'author_id': author_id, 'parent_id': parent_id } # Author condition (READ, WRITE, CREATE (private)) author_ids = [] if operation == 'read' or operation == 'write': author_ids = [ mid for mid, message in message_values.items() if message.get('author_id') and message.get('author_id') == self.env.user.partner_id.id ] elif operation == 'create': author_ids = [ mid for mid, message in message_values.items() if not message.get('model') and not message.get('res_id') ] # Parent condition, for create (check for received notifications for the created message parent) notified_ids = [] if operation == 'create': # TDE: probably clean me parent_ids = [ message.get('parent_id') for message in message_values.values() if message.get('parent_id') ] self._cr.execute( """SELECT DISTINCT m.id, partner_rel.res_partner_id, channel_partner.partner_id FROM "%s" m LEFT JOIN "mail_message_res_partner_rel" partner_rel ON partner_rel.mail_message_id = m.id AND partner_rel.res_partner_id = (%%s) LEFT JOIN "mail_message_mail_channel_rel" channel_rel ON channel_rel.mail_message_id = m.id LEFT JOIN "mail_channel" channel ON channel.id = channel_rel.mail_channel_id LEFT JOIN "mail_channel_partner" channel_partner ON channel_partner.channel_id = channel.id AND channel_partner.partner_id = (%%s) WHERE m.id = ANY (%%s)""" % self._table, ( self.env.user.partner_id.id, self.env.user.partner_id.id, parent_ids, )) not_parent_ids = [ mid[0] for mid in self._cr.fetchall() if any([mid[1], mid[2]]) ] notified_ids += [ mid for mid, message in message_values.items() if message.get('parent_id') in not_parent_ids ] # Recipients condition, for read and write (partner_ids) and create (message_follower_ids) other_ids = set(self.ids).difference(set(author_ids), set(notified_ids)) model_record_ids = _generate_model_record_ids(message_values, other_ids) if operation in ['read', 'write']: notified_ids = [ mid for mid, message in message_values.items() if message.get('notified') ] elif operation == 'create': for doc_model, doc_ids in model_record_ids.items(): followers = self.env['mail.followers'].sudo().search([ ('res_model', '=', doc_model), ('res_id', 'in', list(doc_ids)), ('partner_id', '=', self.env.user.partner_id.id), ]) fol_mids = [follower.res_id for follower in followers] notified_ids += [ mid for mid, message in message_values.items() if message.get('model') == doc_model and message.get('res_id') in fol_mids ] # CRUD: Access rights related to the document other_ids = other_ids.difference(set(notified_ids)) model_record_ids = _generate_model_record_ids(message_values, other_ids) document_related_ids = [] for model, doc_ids in model_record_ids.items(): DocumentModel = self.env[model] mids = DocumentModel.browse(doc_ids).exists() if hasattr(DocumentModel, 'check_mail_message_access'): DocumentModel.check_mail_message_access(mids.ids, operation) # ?? mids ? else: self.env['mail.thread'].check_mail_message_access( mids.ids, operation, model_name=model) document_related_ids += [ mid for mid, message in message_values.items() if message.get('model') == model and message.get('res_id') in mids.ids ] # Calculate remaining ids: if not void, raise an error other_ids = other_ids.difference(set(document_related_ids)) if not (other_ids and self.browse(other_ids).exists()): return raise AccessError( _('The requested operation cannot be completed due to security restrictions. Please contact your system administrator.\n\n(Document type: %s, Operation: %s)' ) % (self._description, operation))