class BaseModuleUninstall(models.TransientModel): _name = "base.module.uninstall" _description = "Module Uninstall" show_all = fields.Boolean() module_id = fields.Many2one( 'ir.module.module', string="Module", required=True, domain=[('state', 'in', ['installed', 'to upgrade', 'to install'])], ondelete='cascade', readonly=True, ) module_ids = fields.Many2many('ir.module.module', string="Impacted modules", compute='_compute_module_ids') model_ids = fields.Many2many('ir.model', string="Impacted data models", compute='_compute_model_ids') def _get_modules(self): """ Return all the modules impacted by self. """ return self.module_id.downstream_dependencies(self.module_id) @api.depends('module_id', 'show_all') def _compute_module_ids(self): for wizard in self: modules = wizard._get_modules() wizard.module_ids = modules if wizard.show_all else modules.filtered( 'application') def _get_models(self): """ Return the models (ir.model) to consider for the impact. """ return self.env['ir.model'].search([('transient', '=', False)]) @api.depends('module_ids') def _compute_model_ids(self): ir_models = self._get_models() ir_models_xids = ir_models._get_external_ids() for wizard in self: if wizard.module_id: module_names = set(wizard._get_modules().mapped('name')) def lost(model): xids = ir_models_xids.get(model.id, ()) return xids and all( xid.split('.')[0] in module_names for xid in xids) # find the models that have all their XIDs in the given modules self.model_ids = ir_models.filtered(lost).sorted('name') @api.onchange('module_id') def _onchange_module_id(self): # if we select a technical module, show technical modules by default if not self.module_id.application: self.show_all = True def action_uninstall(self): modules = self.module_id return modules.button_immediate_uninstall()
class Discussion(models.Model): _name = 'test_new_api.discussion' _description = 'Test New API Discussion' name = fields.Char( string='Title', required=True, help="General description of what this discussion is about.") moderator = fields.Many2one('res.users') categories = fields.Many2many('test_new_api.category', 'test_new_api_discussion_category', 'discussion', 'category') participants = fields.Many2many('res.users', context={'active_test': False}) messages = fields.One2many('test_new_api.message', 'discussion', copy=True) message_concat = fields.Text(string='Message concatenate') important_messages = fields.One2many('test_new_api.message', 'discussion', domain=[('important', '=', True)]) very_important_messages = fields.One2many( 'test_new_api.message', 'discussion', domain=lambda self: self._domain_very_important()) emails = fields.One2many('test_new_api.emailmessage', 'discussion') important_emails = fields.One2many('test_new_api.emailmessage', 'discussion', domain=[('important', '=', True)]) def _domain_very_important(self): """Ensure computed O2M domains work as expected.""" return [("important", "=", True)] @api.onchange('name') def _onchange_name(self): # test onchange modifying one2many field values if self.env.context.get('generate_dummy_message' ) and self.name == '{generate_dummy_message}': # update body of existings messages and emails for message in self.messages: message.body = 'not last dummy message' for message in self.important_messages: message.body = 'not last dummy message' # add new dummy message message_vals = self.messages._add_missing_default_values({ 'body': 'dummy message', 'important': True }) self.messages |= self.messages.new(message_vals) self.important_messages |= self.messages.new(message_vals) @api.onchange('moderator') def _onchange_moderator(self): self.participants |= self.moderator @api.onchange('messages') def _onchange_messages(self): self.message_concat = "\n".join( ["%s:%s" % (m.name, m.body) for m in self.messages])
class ProductTemplate(models.Model): _inherit = "product.template" taxes_id = fields.Many2many('account.tax', 'product_taxes_rel', 'prod_id', 'tax_id', help="Default taxes used when selling the product.", string='Customer Taxes', domain=[('type_tax_use', '=', 'sale')], default=lambda self: self.env.company.account_sale_tax_id) supplier_taxes_id = fields.Many2many('account.tax', 'product_supplier_taxes_rel', 'prod_id', 'tax_id', string='Vendor Taxes', help='Default taxes used when buying the product.', domain=[('type_tax_use', '=', 'purchase')], default=lambda self: self.env.company.account_purchase_tax_id) property_account_income_id = fields.Many2one('account.account', company_dependent=True, string="Income Account", domain="['&', ('deprecated', '=', False), ('company_id', '=', current_company_id)]", help="Keep this field empty to use the default value from the product category.") property_account_expense_id = fields.Many2one('account.account', company_dependent=True, string="Expense Account", domain="['&', ('deprecated', '=', False), ('company_id', '=', current_company_id)]", help="Keep this field empty to use the default value from the product category. If anglo-saxon accounting with automated valuation method is configured, the expense account on the product category will be used.") def _get_product_accounts(self): return { 'income': self.property_account_income_id or self.categ_id.property_account_income_categ_id, 'expense': self.property_account_expense_id or self.categ_id.property_account_expense_categ_id } def _get_asset_accounts(self): res = {} res['stock_input'] = False res['stock_output'] = False return res def get_product_accounts(self, fiscal_pos=None): accounts = self._get_product_accounts() if not fiscal_pos: fiscal_pos = self.env['account.fiscal.position'] return fiscal_pos.map_accounts(accounts)
class SaleProductConfigurator(models.TransientModel): _name = 'sale.product.configurator' _description = 'Sale Product Configurator' product_template_id = fields.Many2one('product.template', string="Product", required=True, domain=[ ('sale_ok', '=', True), ('attribute_line_ids.value_ids', '!=', False) ]) quantity = fields.Integer('Quantity') pricelist_id = fields.Many2one('product.pricelist', 'Pricelist', readonly=True) product_template_attribute_value_ids = fields.Many2many( 'product.template.attribute.value', 'product_configurator_template_attribute_value_rel', string='Attribute Values', readonly=True) product_custom_attribute_value_ids = fields.Many2many( 'product.attribute.custom.value', 'product_configurator_custom_attribute_value_rel', string="Custom Values") product_no_variant_attribute_value_ids = fields.Many2many( 'product.template.attribute.value', 'product_configurator_no_variant_attribute_value_rel', string="Extra Values")
class PurchaseOrderLine(models.Model): _inherit = "purchase.order.line" product_template_id = fields.Many2one('product.template', string='Product Template', related="product_id.product_tmpl_id", domain=[('purchase_ok', '=', True)]) is_configurable_product = fields.Boolean( 'Is the product configurable?', related="product_template_id.has_configurable_attributes") product_template_attribute_value_ids = fields.Many2many( related='product_id.product_template_attribute_value_ids', readonly=True) product_no_variant_attribute_value_ids = fields.Many2many( 'product.template.attribute.value', string='Product attribute values that do not create variants', ondelete='restrict') def _get_product_purchase_description(self, product): name = super(PurchaseOrderLine, self)._get_product_purchase_description(product) for no_variant_attribute_value in self.product_no_variant_attribute_value_ids: name += "\n" + no_variant_attribute_value.attribute_id.name + ': ' + no_variant_attribute_value.name return name
class ModelB(models.Model): _name = 'test_new_api.model_b' _description = 'Model B' name = fields.Char() a_restricted_a_ids = fields.Many2many('test_new_api.model_a', relation='rel_model_a_model_b_1', ondelete='restrict') b_restricted_a_ids = fields.Many2many('test_new_api.model_a', relation='rel_model_a_model_b_2')
class StockWarnInsufficientQty(models.AbstractModel): _name = 'stock.warn.insufficient.qty' _description = 'Warn Insufficient Quantity' product_id = fields.Many2one('product.product', 'Product', required=True) location_id = fields.Many2one('stock.location', 'Location', domain="[('usage', '=', 'internal')]", required=True) quant_ids = fields.Many2many('stock.quant', compute='_compute_quant_ids') def _get_reference_document_company_id(self): raise NotImplementedError() @api.depends('product_id') def _compute_quant_ids(self): for quantity in self: quantity.quant_ids = self.env['stock.quant'].search([ ('product_id', '=', quantity.product_id.id), ('location_id.usage', '=', 'internal'), ('company_id', '=', quantity._get_reference_document_company_id().id) ]) def action_done(self): raise NotImplementedError()
class Tags(models.Model): _name = 'res.partner.tag' _description = 'Partner Tags - These tags can be used on website to find customers by sector, or ...' _inherit = 'website.published.mixin' @api.model def get_selection_class(self): classname = ['default', 'primary', 'success', 'warning', 'danger'] return [(x, str.title(x)) for x in classname] name = fields.Char('Category Name', required=True, translate=True) partner_ids = fields.Many2many('res.partner', 'res_partner_res_partner_tag_rel', 'tag_id', 'partner_id', string='Partners') classname = fields.Selection(get_selection_class, 'Class', default='default', help="Bootstrap class to customize the color", required=True) active = fields.Boolean('Active', default=True) def _default_is_published(self): return True
class Channel(models.Model): _inherit = 'mail.channel' subscription_department_ids = fields.Many2many( 'hr.department', string='HR Departments', help= 'Automatically subscribe members of those departments to the channel.') def _subscribe_users(self): """ Auto-subscribe members of a department to a channel """ super(Channel, self)._subscribe_users() for mail_channel in self: if mail_channel.subscription_department_ids: mail_channel.write({ 'channel_partner_ids': [(4, partner_id) for partner_id in mail_channel.mapped( 'subscription_department_ids.member_ids.user_id.partner_id' ).ids] }) def write(self, vals): res = super(Channel, self).write(vals) if vals.get('subscription_department_ids'): self._subscribe_users() return res
class Container(models.Model): _name = 'test_access_right.container' _description = 'Test Access Right Container' some_ids = fields.Many2many('test_access_right.some_obj', 'test_access_right_rel', 'container_id', 'some_id')
class StockImmediateTransfer(models.TransientModel): _name = 'stock.immediate.transfer' _description = 'Immediate Transfer' pick_ids = fields.Many2many('stock.picking', 'stock_picking_transfer_rel') def process(self): pick_to_backorder = self.env['stock.picking'] pick_to_do = self.env['stock.picking'] for picking in self.pick_ids: # If still in draft => confirm and assign if picking.state == 'draft': picking.action_confirm() if picking.state != 'assigned': picking.action_assign() if picking.state != 'assigned': raise UserError( _("Could not reserve all requested products. Please use the \'Mark as Todo\' button to handle the reservation manually." )) for move in picking.move_lines.filtered( lambda m: m.state not in ['done', 'cancel']): for move_line in move.move_line_ids: move_line.qty_done = move_line.product_uom_qty if picking._check_backorder(): pick_to_backorder |= picking continue pick_to_do |= picking # Process every picking that do not require a backorder, then return a single backorder wizard for every other ones. if pick_to_do: pick_to_do.action_done() if pick_to_backorder: return pick_to_backorder.action_generate_backorder_wizard() return False
class FleetVehicleModel(models.Model): _name = 'fleet.vehicle.model' _description = 'Model of a vehicle' _order = 'name asc' name = fields.Char('Model name', required=True) brand_id = fields.Many2one('fleet.vehicle.model.brand', 'Manufacturer', required=True, help='Manufacturer of the vehicle') vendors = fields.Many2many('res.partner', 'fleet_vehicle_model_vendors', 'model_id', 'partner_id', string='Vendors') manager_id = fields.Many2one( 'res.users', 'Fleet Manager', default=lambda self: self.env.uid, domain=lambda self: [('groups_id', 'in', self.env.ref('fleet.fleet_group_manager').id)]) image_128 = fields.Image(related='brand_id.image_128', readonly=False) @api.depends('name', 'brand_id') def name_get(self): res = [] for record in self: name = record.name if record.brand_id.name: name = record.brand_id.name + '/' + name res.append((record.id, name)) return res
class UtmCampaign(models.Model): # OLD crm.case.resource.type _name = 'utm.campaign' _description = 'UTM Campaign' name = fields.Char(string='Campaign Name', required=True, translate=True) user_id = fields.Many2one( 'res.users', string='Responsible', required=True, default=lambda self: self.env.uid) stage_id = fields.Many2one('utm.stage', string='Stage', ondelete='restrict', required=True, default=lambda self: self.env['utm.stage'].search([], limit=1), group_expand='_group_expand_stage_ids') tag_ids = fields.Many2many( 'utm.tag', 'utm_tag_rel', 'tag_id', 'campaign_id', string='Tags') is_website = fields.Boolean(default=False, help="Allows us to filter relevant Campaign") color = fields.Integer(string='Color Index') @api.model def _group_expand_stage_ids(self, stages, domain, order): """ Read group customization in order to display all the stages in the kanban view, even if they are empty """ stage_ids = stages._search([], order=order, access_rights_uid=SUPERUSER_ID) return stages.browse(stage_ids)
class ChooseDestinationLocation(models.TransientModel): _name = 'stock.package.destination' _description = 'Stock Package Destination' picking_id = fields.Many2one('stock.picking', required=True) move_line_ids = fields.Many2many('stock.move.line', 'Products', compute='_compute_move_line_ids', required=True) location_dest_id = fields.Many2one('stock.location', 'Destination location', required=True) filtered_location = fields.One2many(comodel_name='stock.location', compute='_filter_location') @api.depends('picking_id') def _compute_move_line_ids(self): for destination in self: destination.move_line_ids = destination.picking_id.move_line_ids.filtered( lambda l: l.qty_done > 0 and not l.result_package_id) @api.depends('move_line_ids') def _filter_location(self): for destination in self: destination.filtered_location = destination.move_line_ids.mapped( 'location_dest_id') def action_done(self): # set the same location on each move line and pass again in _put_in_pack for line in self.move_line_ids: line.location_dest_id = self.location_dest_id return self.picking_id.put_in_pack()
class AccountMoveLine(models.Model): _inherit = 'account.move.line' # Overload of fields defined in account analytic_account_id = fields.Many2one(compute="_compute_analytic_account", store=True, readonly=False) analytic_tag_ids = fields.Many2many(compute="_compute_analytic_account", store=True, readonly=False) @api.depends('product_id', 'account_id', 'partner_id', 'date_maturity') def _compute_analytic_account(self): for record in self: record.analytic_account_id = record.analytic_account_id or False record.analytic_tag_ids = record.analytic_tag_ids or False rec = self.env['account.analytic.default'].account_get( product_id=record.product_id.id, partner_id=record.partner_id.commercial_partner_id.id or record.move_id.partner_id.commercial_partner_id.id, account_id=record.account_id.id, user_id=record.env.uid, date=record.date_maturity, company_id=record.move_id.company_id.id) if rec: record.analytic_account_id = rec.analytic_id record.analytic_tag_ids = rec.analytic_tag_ids
class EventRegistration(models.Model): """ Store answers on attendees. """ _inherit = 'event.registration' answer_ids = fields.Many2many('event.answer', 'event_registration_answer', string='Answers')
class AccountAnalyticLine(models.Model): _name = 'account.analytic.line' _description = 'Analytic Line' _order = 'date desc, id desc' @api.model def _default_user(self): return self.env.context.get('user_id', self.env.user.id) name = fields.Char('Description', required=True) date = fields.Date('Date', required=True, index=True, default=fields.Date.context_today) amount = fields.Monetary('Amount', required=True, default=0.0) unit_amount = fields.Float('Quantity', default=0.0) product_uom_id = fields.Many2one('uom.uom', string='Unit of Measure', domain="[('category_id', '=', product_uom_category_id)]") product_uom_category_id = fields.Many2one(related='product_uom_id.category_id', readonly=True) account_id = fields.Many2one('account.analytic.account', 'Analytic Account', required=True, ondelete='restrict', index=True, domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]") partner_id = fields.Many2one('res.partner', string='Partner', domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]") user_id = fields.Many2one('res.users', string='User', default=_default_user) tag_ids = fields.Many2many('account.analytic.tag', 'account_analytic_line_tag_rel', 'line_id', 'tag_id', string='Tags', copy=True, domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]") company_id = fields.Many2one('res.company', string='Company', required=True, readonly=True, default=lambda self: self.env.company) currency_id = fields.Many2one(related="company_id.currency_id", string="Currency", readonly=True, store=True, compute_sudo=True) group_id = fields.Many2one('account.analytic.group', related='account_id.group_id', store=True, readonly=True, compute_sudo=True) @api.constrains('company_id', 'account_id') def _check_company_id(self): for line in self: if line.account_id.company_id and line.company_id.id != line.account_id.company_id.id: raise ValidationError(_('The selected account belongs to another company that the one you\'re trying to create an analytic item for'))
class StockBackorderConfirmation(models.TransientModel): _name = 'stock.backorder.confirmation' _description = 'Backorder Confirmation' pick_ids = fields.Many2many('stock.picking', 'stock_picking_backorder_rel') def _process(self, cancel_backorder=False): for confirmation in self: if cancel_backorder: for pick_id in confirmation.pick_ids: moves_to_log = {} for move in pick_id.move_lines: if float_compare(move.product_uom_qty, move.quantity_done, precision_rounding=move.product_uom. rounding) > 0: moves_to_log[move] = (move.quantity_done, move.product_uom_qty) pick_id._log_less_quantities_than_expected(moves_to_log) confirmation.pick_ids.with_context( cancel_backorder=cancel_backorder).action_done() def process(self): self._process() def process_cancel_backorder(self): self._process(cancel_backorder=True)
class ProductionLot(models.Model): _inherit = 'stock.production.lot' purchase_order_ids = fields.Many2many( 'purchase.order', string="Purchase Orders", compute='_compute_purchase_order_ids', readonly=True, store=False) purchase_order_count = fields.Integer( 'Purchase order count', compute='_compute_purchase_order_ids') @api.depends('name') def _compute_purchase_order_ids(self): for lot in self: stock_moves = self.env['stock.move.line'].search([ ('lot_id', '=', lot.id), ('state', '=', 'done') ]).mapped('move_id') stock_moves = stock_moves.search([ ('id', 'in', stock_moves.ids) ]).filtered(lambda move: move.picking_id.location_id.usage == 'supplier' and move.state == 'done') lot.purchase_order_ids = stock_moves.mapped( 'purchase_line_id.order_id') lot.purchase_order_count = len(lot.purchase_order_ids) def action_view_po(self): self.ensure_one() action = self.env.ref('purchase.purchase_form_action').read()[0] action['domain'] = [('id', 'in', self.mapped('purchase_order_ids.id'))] action['context'] = dict(self._context, create=False) return action
class ResUsers(models.Model): _inherit = 'res.users' last_lunch_location_id = fields.Many2one('lunch.location') favorite_lunch_product_ids = fields.Many2many( 'lunch.product', 'lunch_product_favorite_user_rel', 'user_id', 'product_id')
class AccountCommonReport(models.TransientModel): _name = "account.common.report" _description = "Account Common Report" company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env.company) journal_ids = fields.Many2many( 'account.journal', string='Journals', required=True, default=lambda self: self.env['account.journal'].search([( 'company_id', '=', self.company_id.id)])) date_from = fields.Date(string='Start Date') date_to = fields.Date(string='End Date') target_move = fields.Selection([ ('posted', 'All Posted Entries'), ('all', 'All Entries'), ], string='Target Moves', required=True, default='posted') @api.onchange('company_id') def _onchange_company_id(self): if self.company_id: self.journal_ids = self.env['account.journal'].search([ ('company_id', '=', self.company_id.id) ]) else: self.journal_ids = self.env['account.journal'].search([]) def _build_contexts(self, data): result = {} result['journal_ids'] = 'journal_ids' in data['form'] and data['form'][ 'journal_ids'] or False result['state'] = 'target_move' in data['form'] and data['form'][ 'target_move'] or '' result['date_from'] = data['form']['date_from'] or False result['date_to'] = data['form']['date_to'] or False result['strict_range'] = True if result['date_from'] else False result['company_id'] = data['form']['company_id'][0] or False return result def _print_report(self, data): raise NotImplementedError() def check_report(self): self.ensure_one() data = {} data['ids'] = self.env.context.get('active_ids', []) data['model'] = self.env.context.get('active_model', 'ir.ui.menu') data['form'] = self.read([ 'date_from', 'date_to', 'journal_ids', 'target_move', 'company_id' ])[0] used_context = self._build_contexts(data) data['form']['used_context'] = dict(used_context, lang=get_lang(self.env).code) return self.with_context(discard_logo_check=True)._print_report(data)
class LunchProduct(models.Model): """ Products available to order. A product is linked to a specific vendor. """ _name = 'lunch.product' _description = 'Lunch Product' _inherit = 'image.mixin' _order = 'name' name = fields.Char('Product Name', required=True) category_id = fields.Many2one('lunch.product.category', 'Product Category', required=True) description = fields.Text('Description') price = fields.Float('Price', digits='Account', required=True) supplier_id = fields.Many2one('lunch.supplier', 'Vendor', required=True) active = fields.Boolean(default=True) company_id = fields.Many2one('res.company', related='supplier_id.company_id', store=True) currency_id = fields.Many2one('res.currency', related='company_id.currency_id') new_until = fields.Date('New Until') favorite_user_ids = fields.Many2many('res.users', 'lunch_product_favorite_user_rel', 'product_id', 'user_id')
class BaseLanguageExport(models.TransientModel): _name = "base.language.export" _description = 'Language Export' @api.model def _get_languages(self): langs = self.env['res.lang'].get_installed() return [(NEW_LANG_KEY, _('New Language (Empty translation template)'))] + \ langs name = fields.Char('File Name', readonly=True) lang = fields.Selection(_get_languages, string='Language', required=True, default=NEW_LANG_KEY) format = fields.Selection([('csv', 'CSV File'), ('po', 'PO File'), ('tgz', 'TGZ Archive')], string='File Format', required=True, default='csv') modules = fields.Many2many('ir.module.module', 'rel_modules_langexport', 'wiz_id', 'module_id', string='Apps To Export', domain=[('state', '=', 'installed')]) data = fields.Binary('File', readonly=True, attachment=False) state = fields.Selection( [('choose', 'choose'), ('get', 'get')], # choose language or get the file default='choose') def act_getfile(self): this = self[0] lang = this.lang if this.lang != NEW_LANG_KEY else False mods = sorted(this.mapped('modules.name')) or ['all'] with contextlib.closing(io.BytesIO()) as buf: tools.trans_export(lang, mods, buf, this.format, self._cr) out = base64.encodestring(buf.getvalue()) filename = 'new' if lang: filename = tools.get_iso_codes(lang) elif len(mods) == 1: filename = mods[0] extension = this.format if not lang and extension == 'po': extension = 'pot' name = "%s.%s" % (filename, extension) this.write({'state': 'get', 'data': out, 'name': name}) return { 'type': 'ir.actions.act_window', 'res_model': 'base.language.export', 'view_mode': 'form', 'res_id': this.id, 'views': [(False, 'form')], 'target': 'new', }
class HrPlan(models.Model): _name = 'hr.plan' _description = 'plan' name = fields.Char('Name', required=True) plan_activity_type_ids = fields.Many2many('hr.plan.activity.type', string='Activities') active = fields.Boolean(default=True)
class ResCountryGroup(models.Model): _inherit = 'res.country.group' pricelist_ids = fields.Many2many('product.pricelist', 'res_country_group_pricelist_rel', 'res_country_group_id', 'pricelist_id', string='Pricelists')
class MultiLine(models.Model): _name = 'test_new_api.multi.line' _description = 'Test New API Multi Line' multi = fields.Many2one('test_new_api.multi', ondelete='cascade') name = fields.Char() partner = fields.Many2one('res.partner') tags = fields.Many2many('test_new_api.multi.tag')
class AccountAnalyticDefault(models.Model): _name = "account.analytic.default" _description = "Analytic Distribution" _rec_name = "analytic_id" _order = "sequence" sequence = fields.Integer(string='Sequence', help="Gives the sequence order when displaying a list of analytic distribution") analytic_id = fields.Many2one('account.analytic.account', string='Analytic Account') analytic_tag_ids = fields.Many2many('account.analytic.tag', string='Analytic Tags') product_id = fields.Many2one('product.product', string='Product', ondelete='cascade', help="Select a product which will use analytic account specified in analytic default (e.g. create new customer invoice or Sales order if we select this product, it will automatically take this as an analytic account)") partner_id = fields.Many2one('res.partner', string='Partner', ondelete='cascade', help="Select a partner which will use analytic account specified in analytic default (e.g. create new customer invoice or Sales order if we select this partner, it will automatically take this as an analytic account)") account_id = fields.Many2one('account.account', string='Account', ondelete='cascade', help="Select an accounting account which will use analytic account specified in analytic default (e.g. create new customer invoice or Sales order if we select this account, it will automatically take this as an analytic account)") user_id = fields.Many2one('res.users', string='User', ondelete='cascade', help="Select a user which will use analytic account specified in analytic default.") company_id = fields.Many2one('res.company', string='Company', ondelete='cascade', help="Select a company which will use analytic account specified in analytic default (e.g. create new customer invoice or Sales order if we select this company, it will automatically take this as an analytic account)") date_start = fields.Date(string='Start Date', help="Default start date for this Analytic Account.") date_stop = fields.Date(string='End Date', help="Default end date for this Analytic Account.") @api.constrains('analytic_id', 'analytic_tag_ids') def _check_account_or_tags(self): if any(not default.analytic_id and not default.analytic_tag_ids for default in self): raise ValidationError(_('An analytic default requires at least an analytic account or an analytic tag.')) @api.model def account_get(self, product_id=None, partner_id=None, account_id=None, user_id=None, date=None, company_id=None): domain = [] if product_id: domain += ['|', ('product_id', '=', product_id)] domain += [('product_id', '=', False)] if partner_id: domain += ['|', ('partner_id', '=', partner_id)] domain += [('partner_id', '=', False)] if account_id: domain += ['|', ('account_id', '=', account_id)] domain += [('account_id', '=', False)] if company_id: domain += ['|', ('company_id', '=', company_id)] domain += [('company_id', '=', False)] if user_id: domain += ['|', ('user_id', '=', user_id)] domain += [('user_id', '=', False)] if date: domain += ['|', ('date_start', '<=', date), ('date_start', '=', False)] domain += ['|', ('date_stop', '>=', date), ('date_stop', '=', False)] best_index = -1 res = self.env['account.analytic.default'] for rec in self.search(domain): index = 0 if rec.product_id: index += 1 if rec.partner_id: index += 1 if rec.account_id: index += 1 if rec.company_id: index += 1 if rec.user_id: index += 1 if rec.date_start: index += 1 if rec.date_stop: index += 1 if index > best_index: res = rec best_index = index return res
class Partner(models.Model): _inherit = 'res.partner' website_tag_ids = fields.Many2many('res.partner.tag', 'res_partner_res_partner_tag_rel', 'partner_id', 'tag_id', string='Website tags')
class SaleOrderLine(models.Model): _inherit = "sale.order.line" is_configurable_product = fields.Boolean( 'Is the product configurable?', related="product_template_id.has_configurable_attributes") product_template_attribute_value_ids = fields.Many2many( related='product_id.product_template_attribute_value_ids', readonly=True)
class FakeTicket(models.Model): """We want to simulate a record that would typically be accessed by a portal user, with a relational field to records that could not be accessed by a portal user. """ _name = 'test_access_right.ticket' _description = 'Fake ticket For Test Access Right' name = fields.Char() message_partner_ids = fields.Many2many(comodel_name='res.partner')