class SaleQuoteTemplate(models.Model): _name = "sale.quote.template" _description = "Sale Quotation Template" name = fields.Char('Quotation Template', required=True) website_description = fields.Html('Description', translate=html_translate, sanitize_attributes=False) quote_line = fields.One2many('sale.quote.line', 'quote_id', 'Quotation Template Lines', copy=True) note = fields.Text('Terms and conditions') options = fields.One2many('sale.quote.option', 'template_id', 'Optional Products Lines', copy=True) number_of_days = fields.Integer('Quotation Duration', help='Number of days for the validity date computation of the quotation') require_payment = fields.Selection([ (0, 'Online Signature'), (1, 'Online Payment')], default=0, string='Confirmation Mode', help="Choose how you want to confirm an order to launch the delivery process. You can either " "request a digital signature or an upfront payment. With a digital signature, you can " "request the payment when issuing the invoice.") mail_template_id = fields.Many2one( 'mail.template', 'Confirmation Mail', domain=[('model', '=', 'sale.order')], help="This e-mail template will be sent on confirmation. Leave empty to send nothing.") active = fields.Boolean(default=True, help="If unchecked, it will allow you to hide the quotation template without removing it.") @api.multi def open_template(self): self.ensure_one() return { 'type': 'ir.actions.act_url', 'target': 'self', 'url': '/quote/template/%d' % self.id }
class One2ManyMultiple(models.Model): _name = 'export.one2many.multiple' parent_id = fields.Many2one('export.one2many.recursive') const = fields.Integer(default=36) child1 = fields.One2many('export.one2many.child.1', 'parent_id') child2 = fields.One2many('export.one2many.child.2', 'parent_id')
class Documentation(models.Model): _name = 'forum.documentation.toc' _description = 'Documentation ToC' _inherit = ['website.seo.metadata'] _order = "parent_left" _parent_order = "sequence, name" _parent_store = True sequence = fields.Integer('Sequence') name = fields.Char('Name', required=True, translate=True) introduction = fields.Html('Introduction', translate=True) parent_id = fields.Many2one('forum.documentation.toc', string='Parent Table Of Content', ondelete='cascade') child_ids = fields.One2many('forum.documentation.toc', 'parent_id', string='Children Table Of Content') parent_left = fields.Integer(string='Left Parent', index=True) parent_right = fields.Integer(string='Right Parent', index=True) post_ids = fields.One2many('forum.post', 'documentation_toc_id', string='Posts') forum_id = fields.Many2one('forum.forum', string='Forum', required=True) @api.multi def name_get(self): res = [] for record in self: name = record.name if record.parent_id: name = record.parent_id.name + ' / ' + name res.append((record.id, name)) return res @api.constrains('parent_id') def _check_parent_id(self): if not self._check_recursion(): raise ValidationError(_('Error ! You cannot create recursive categories.'))
class Discussion(models.Model): _name = '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') messages = fields.One2many('test_new_api.message', 'discussion') 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 MaintenanceTeam(models.Model): _name = 'maintenance.team' _description = 'Maintenance Teams' name = fields.Char(required=True, translate=True) member_ids = fields.Many2many('res.users', 'maintenance_team_users_rel', string="Team Members") color = fields.Integer("Color Index", default=0) request_ids = fields.One2many('maintenance.request', 'maintenance_team_id', copy=False) equipment_ids = fields.One2many('maintenance.equipment', 'maintenance_team_id', copy=False) # For the dashboard only todo_request_ids = fields.One2many('maintenance.request', string="Requests", copy=False, compute='_compute_todo_requests') todo_request_count = fields.Integer(string="Number of Requests", compute='_compute_todo_requests') todo_request_count_date = fields.Integer( string="Number of Requests Scheduled", compute='_compute_todo_requests') todo_request_count_high_priority = fields.Integer( string="Number of Requests in High Priority", compute='_compute_todo_requests') todo_request_count_block = fields.Integer( string="Number of Requests Blocked", compute='_compute_todo_requests') todo_request_count_unscheduled = fields.Integer( string="Number of Requests Unscheduled", compute='_compute_todo_requests') @api.one @api.depends('request_ids.stage_id.done') def _compute_todo_requests(self): self.todo_request_ids = self.request_ids.filtered( lambda e: e.stage_id.done == False) self.todo_request_count = len(self.todo_request_ids) self.todo_request_count_date = len( self.todo_request_ids.filtered(lambda e: e.schedule_date != False)) self.todo_request_count_high_priority = len( self.todo_request_ids.filtered(lambda e: e.priority == '3')) self.todo_request_count_block = len( self.todo_request_ids.filtered( lambda e: e.kanban_state == 'blocked')) self.todo_request_count_unscheduled = len( self.todo_request_ids.filtered(lambda e: not e.schedule_date)) @api.one @api.depends('equipment_ids') def _compute_equipment(self): self.equipment_count = len(self.equipment_ids)
class Movie(models.Model): _name = 'test_new_api.creativework.movie' name = fields.Char() editions = fields.One2many('test_new_api.creativework.edition', 'res_id', domain=[('res_model', '=', _name)])
class ResCompany(models.Model): _inherit = 'res.company' resource_calendar_ids = fields.One2many('resource.calendar', 'company_id', 'Working Hours') resource_calendar_id = fields.Many2one('resource.calendar', 'Default Working Hours', ondelete='restrict') @api.model def _init_data_resource_calendar(self): for company in self.search([('resource_calendar_id', '=', False)]): company.resource_calendar_id = self.env[ 'resource.calendar'].create({ 'name': _('Standard 40 hours/week') }).id @api.model def create(self, values): if not values.get('resource_calendar_id'): values['resource_calendar_id'] = self.env[ 'resource.calendar'].create({ 'name': _('Standard 40 hours/week') }).id company = super(ResCompany, self).create(values) # calendar created from form view: no company_id set because record was still not created if not company.resource_calendar_id.company_id: company.resource_calendar_id.company_id = company.id return company
class LeadTest(models.Model): _name = "base.automation.lead.test" _description = "Action Rule Test" name = fields.Char(string='Subject', required=True, index=True) user_id = fields.Many2one('res.users', string='Responsible') state = fields.Selection([('draft', 'New'), ('cancel', 'Cancelled'), ('open', 'In Progress'), ('pending', 'Pending'), ('done', 'Closed')], string="Status", readonly=True, default='draft') active = fields.Boolean(default=True) partner_id = fields.Many2one('res.partner', string='Partner') date_action_last = fields.Datetime(string='Last Action', readonly=True) customer = fields.Boolean(related='partner_id.customer', readonly=True, store=True) line_ids = fields.One2many('base.automation.line.test', 'lead_id') priority = fields.Boolean() deadline = fields.Boolean(compute='_compute_deadline', store=True) is_assigned_to_admin = fields.Boolean(string='Assigned to admin user') @api.depends('priority') def _compute_deadline(self): for record in self: if not record.priority: record.deadline = False else: record.deadline = fields.Datetime.from_string( record.create_date) + relativedelta.relativedelta(days=3)
class Holidays(models.Model): _inherit = "hr.holidays" timesheet_ids = fields.One2many('account.analytic.line', 'holiday_id', string="Analytic Lines") def _validate_leave_request(self): """ Timesheet will be generated on leave validation only if a timesheet_project_id and a timesheet_task_id are set on the corresponding leave type. The generated timesheet will be attached to this project/task. """ # create the timesheet on the vacation project for holiday in self.filtered( lambda request: request.type == 'remove' and request. holiday_type == 'employee' and request.holiday_status_id. timesheet_project_id and request.holiday_status_id. timesheet_task_id): holiday_project = holiday.holiday_status_id.timesheet_project_id holiday_task = holiday.holiday_status_id.timesheet_task_id work_hours_data = [ item for item in holiday.employee_id.iter_work_hours_count( fields.Datetime.from_string(holiday.date_from), fields.Datetime.from_string(holiday.date_to)) ] for index, (day_date, work_hours_count) in enumerate(work_hours_data): self.env['account.analytic.line'].create({ 'name': "%s (%s/%s)" % (holiday.name or '', index + 1, len(work_hours_data)), 'project_id': holiday_project.id, 'task_id': holiday_task.id, 'account_id': holiday_project.analytic_account_id.id, 'unit_amount': work_hours_count, 'user_id': holiday.employee_id.user_id.id, 'date': fields.Date.to_string(day_date), 'holiday_id': holiday.id, 'employee_id': holiday.employee_id.id, }) return super(Holidays, self)._validate_leave_request() @api.multi def action_refuse(self): """ Remove the timesheets linked to the refused holidays """ result = super(Holidays, self).action_refuse() timesheets = self.sudo().mapped('timesheet_ids') timesheets.write({'holiday_id': False}) timesheets.unlink() return result
class EventType(models.Model): _inherit = 'event.type' use_questions = fields.Boolean('Questions to Attendees') question_ids = fields.One2many( 'event.question', 'event_type_id', string='Questions', copy=True)
class EventType(models.Model): _inherit = 'event.type' @api.model def _get_default_event_ticket_ids(self): product = self.env.ref('event_sale.product_product_event', raise_if_not_found=False) if not product: return False return [(0, 0, { 'name': _('Registration'), 'product_id': product.id, 'price': 0, })] use_ticketing = fields.Boolean('Ticketing') event_ticket_ids = fields.One2many('event.event.ticket', 'event_type_id', string='Tickets', default=_get_default_event_ticket_ids) @api.onchange('name') def _onchange_name(self): if self.name: self.event_ticket_ids.filtered( lambda ticket: ticket.name == _('Registration')).update( {'name': _('Registration for %s') % self.name})
class ResPartner(models.Model): _inherit = 'res.partner' sale_order_count = fields.Integer(compute='_compute_sale_order_count', string='# of Sales Order') sale_order_ids = fields.One2many('sale.order', 'partner_id', 'Sales Order') sale_warn = fields.Selection(WARNING_MESSAGE, 'Sales Order', default='no-message', help=WARNING_HELP, required=True) sale_warn_msg = fields.Text('Message for Sales Order') def _compute_sale_order_count(self): sale_data = self.env['sale.order'].read_group(domain=[ ('partner_id', 'child_of', self.ids) ], fields=['partner_id'], groupby=['partner_id']) # read to keep the child/parent relation while aggregating the read_group result in the loop partner_child_ids = self.read(['child_ids']) mapped_data = dict([(m['partner_id'][0], m['partner_id_count']) for m in sale_data]) for partner in self: # let's obtain the partner id and all its child ids from the read up there item = next(p for p in partner_child_ids if p['id'] == partner.id) partner_ids = [partner.id] + item.get('child_ids') # then we can sum for all the partner's child partner.sale_order_count = sum( mapped_data.get(child, 0) for child in partner_ids)
class Event(models.Model): _inherit = 'event.event' event_ticket_ids = fields.One2many('event.event.ticket', 'event_id', string='Event Ticket', copy=True) @api.onchange('event_type_id') def _onchange_type(self): super(Event, self)._onchange_type() if self.event_type_id.use_ticketing: self.event_ticket_ids = [(5, 0, 0)] + [(0, 0, { 'name': self.name and _('Registration for %s') % self.name or ticket.name, 'product_id': ticket.product_id.id, 'price': ticket.price, }) for ticket in self.event_type_id.event_ticket_ids] @api.multi def _is_event_registrable(self): self.ensure_one() if not self.event_ticket_ids: return True return all( self.event_ticket_ids.with_context( active_test=False).mapped(lambda t: t.product_id.active))
class HrSalaryRuleCategory(models.Model): _name = 'hr.salary.rule.category' _description = 'Salary Rule Category' name = fields.Char(required=True, translate=True) code = fields.Char(required=True) parent_id = fields.Many2one( 'hr.salary.rule.category', string='Parent', help= "Linking a salary category to its parent is used only for the reporting purpose." ) children_ids = fields.One2many('hr.salary.rule.category', 'parent_id', string='Children') note = fields.Text(string='Description') company_id = fields.Many2one( 'res.company', string='Company', default=lambda self: self.env['res.company']._company_default_get()) @api.constrains('parent_id') def _check_parent_id(self): if not self._check_recursion(): raise ValidationError( _('Error! You cannot create recursive hierarchy of Salary Rule Category.' ))
class EventQuestion(models.Model): _name = 'event.question' _rec_name = 'title' _order = 'sequence,id' title = fields.Char(required=True, translate=True) event_type_id = fields.Many2one('event.type', 'Event Type', ondelete='cascade') event_id = fields.Many2one('event.event', 'Event', ondelete='cascade') answer_ids = fields.One2many('event.answer', 'question_id', "Answers", required=True, copy=True) sequence = fields.Integer(default=10) is_individual = fields.Boolean('Ask each attendee', help="If True, this question will be asked for every attendee of a reservation. If " "not it will be asked only once and its value propagated to every attendees.") @api.constrains('event_type_id', 'event_id') def _constrains_event(self): if any(question.event_type_id and question.event_id for question in self): raise UserError(_('Question should belong to either event category or event but not both')) @api.model def create(self, vals): event_id = vals.get('event_id', False) if event_id: event = self.env['event.event'].browse([event_id]) if event.event_type_id.use_questions and event.event_type_id.question_ids: vals['answer_ids'] = vals.get('answer_ids', []) + [(0, 0, { 'name': answer.name, 'sequence': answer.sequence, }) for answer in event.event_type_id.question_ids.filtered(lambda question: question.title == vals.get('title')).mapped('answer_ids')] return super(EventQuestion, self).create(vals)
class IrExports(models.Model): _name = "ir.exports" _order = 'name' name = fields.Char(string='Export Name') resource = fields.Char(index=True) export_fields = fields.One2many('ir.exports.line', 'export_id', string='Export ID', copy=True)
class ProductCategory(models.Model): _name = "product.category" _description = "Product Category" _parent_name = "parent_id" _parent_store = True _parent_order = 'name' _rec_name = 'complete_name' _order = 'parent_left' name = fields.Char('Name', index=True, required=True, translate=True) complete_name = fields.Char('Complete Name', compute='_compute_complete_name', store=True) parent_id = fields.Many2one('product.category', 'Parent Category', index=True, ondelete='cascade') child_id = fields.One2many('product.category', 'parent_id', 'Child Categories') parent_left = fields.Integer('Left Parent', index=1) parent_right = fields.Integer('Right Parent', index=1) product_count = fields.Integer( '# Products', compute='_compute_product_count', help= "The number of products under this category (Does not consider the children categories)" ) @api.depends('name', 'parent_id.complete_name') def _compute_complete_name(self): for category in self: if category.parent_id: category.complete_name = '%s / %s' % ( category.parent_id.complete_name, category.name) else: category.complete_name = category.name def _compute_product_count(self): read_group_res = self.env['product.template'].read_group( [('categ_id', 'child_of', self.ids)], ['categ_id'], ['categ_id']) group_data = dict((data['categ_id'][0], data['categ_id_count']) for data in read_group_res) for categ in self: product_count = 0 for sub_categ_id in categ.search([('id', 'child_of', categ.id) ]).ids: product_count += group_data.get(sub_categ_id, 0) categ.product_count = product_count @api.constrains('parent_id') def _check_category_recursion(self): if not self._check_recursion(): raise ValidationError( _('Error ! You cannot create recursive categories.')) return True @api.model def name_create(self, name): return self.create({'name': name}).name_get()[0]
class ResCompany(models.Model): _inherit = "res.company" ldaps = fields.One2many('res.company.ldap', 'company', string='LDAP Parameters', copy=True, groups="base.group_system")
class ResUsers(models.Model): _inherit = 'res.users' resource_ids = fields.One2many( 'resource.resource', 'user_id', 'Resources') resource_calendar_id = fields.Many2one( 'resource.calendar', 'Default Working Hours', related='resource_ids.calendar_id')
class MailThread(models.AbstractModel): _inherit = 'mail.thread' _mail_post_token_field = 'access_token' # token field for external posts, to be overridden website_message_ids = fields.One2many('mail.message', 'res_id', string='Website Messages', domain=lambda self: [('model', '=', self._name), ('message_type', '=', 'comment')], auto_join=True, help="Website communication history")
class CrossoveredBudget(models.Model): _name = "crossovered.budget" _description = "Budget" _inherit = ['mail.thread'] name = fields.Char('Budget Name', required=True, states={'done': [('readonly', True)]}) creating_user_id = fields.Many2one('res.users', 'Responsible', default=lambda self: self.env.user) date_from = fields.Date('Start Date', required=True, states={'done': [('readonly', True)]}) date_to = fields.Date('End Date', required=True, states={'done': [('readonly', True)]}) state = fields.Selection([('draft', 'Draft'), ('cancel', 'Cancelled'), ('confirm', 'Confirmed'), ('validate', 'Validated'), ('done', 'Done')], 'Status', default='draft', index=True, required=True, readonly=True, copy=False, track_visibility='always') crossovered_budget_line = fields.One2many( 'crossovered.budget.lines', 'crossovered_budget_id', 'Budget Lines', states={'done': [('readonly', True)]}, copy=True) company_id = fields.Many2one('res.company', 'Company', required=True, default=lambda self: self.env['res.company']. _company_default_get('account.budget.post')) @api.multi def action_budget_confirm(self): self.write({'state': 'confirm'}) @api.multi def action_budget_draft(self): self.write({'state': 'draft'}) @api.multi def action_budget_validate(self): self.write({'state': 'validate'}) @api.multi def action_budget_cancel(self): self.write({'state': 'cancel'}) @api.multi def action_budget_done(self): self.write({'state': 'done'})
class report_paperformat(models.Model): _name = "report.paperformat" _description = "Allows customization of a report." name = fields.Char('Name', required=True) default = fields.Boolean('Default paper format ?') format = fields.Selection( [('A0', 'A0 5 841 x 1189 mm'), ('A1', 'A1 6 594 x 841 mm'), ('A2', 'A2 7 420 x 594 mm'), ('A3', 'A3 8 297 x 420 mm'), ('A4', 'A4 0 210 x 297 mm, 8.26 x 11.69 inches'), ('A5', 'A5 9 148 x 210 mm'), ('A6', 'A6 10 105 x 148 mm'), ('A7', 'A7 11 74 x 105 mm'), ('A8', 'A8 12 52 x 74 mm'), ('A9', 'A9 13 37 x 52 mm'), ('B0', 'B0 14 1000 x 1414 mm'), ('B1', 'B1 15 707 x 1000 mm'), ('B2', 'B2 17 500 x 707 mm'), ('B3', 'B3 18 353 x 500 mm'), ('B4', 'B4 19 250 x 353 mm'), ('B5', 'B5 1 176 x 250 mm, 6.93 x 9.84 inches'), ('B6', 'B6 20 125 x 176 mm'), ('B7', 'B7 21 88 x 125 mm'), ('B8', 'B8 22 62 x 88 mm'), ('B9', 'B9 23 33 x 62 mm'), ('B10', ':B10 16 31 x 44 mm'), ('C5E', 'C5E 24 163 x 229 mm'), ('Comm10E', 'Comm10E 25 105 x 241 mm, U.S. ' 'Common 10 Envelope'), ('DLE', 'DLE 26 110 x 220 mm'), ('Executive', 'Executive 4 7.5 x 10 inches, ' '190.5 x 254 mm'), ('Folio', 'Folio 27 210 x 330 mm'), ('Ledger', 'Ledger 28 431.8 x 279.4 mm'), ('Legal', 'Legal 3 8.5 x 14 inches, ' '215.9 x 355.6 mm'), ('Letter', 'Letter 2 8.5 x 11 inches, ' '215.9 x 279.4 mm'), ('Tabloid', 'Tabloid 29 279.4 x 431.8 mm'), ('custom', 'Custom')], 'Paper size', default='A4', help="Select Proper Paper size") margin_top = fields.Float('Top Margin (mm)', default=40) margin_bottom = fields.Float('Bottom Margin (mm)', default=20) margin_left = fields.Float('Left Margin (mm)', default=7) margin_right = fields.Float('Right Margin (mm)', default=7) page_height = fields.Integer('Page height (mm)', default=False) page_width = fields.Integer('Page width (mm)', default=False) orientation = fields.Selection([('Landscape', 'Landscape'), ('Portrait', 'Portrait')], 'Orientation', default='Landscape') header_line = fields.Boolean('Display a header line', default=False) header_spacing = fields.Integer('Header spacing', default=35) dpi = fields.Integer('Output DPI', required=True, default=90) report_ids = fields.One2many('ir.actions.report', 'paperformat_id', 'Associated reports', help="Explicitly associated reports") @api.constrains('format') def _check_format_or_page(self): if self.filtered(lambda x: x.format != 'custom' and (x.page_width or x.page_height)): raise ValidationError( _('Error ! You cannot select a format AND specific page width/height.' ))
class ProductTemplate(models.Model): _inherit = "product.template" bom_ids = fields.One2many('mrp.bom', 'product_tmpl_id', 'Bill of Materials') bom_count = fields.Integer('# Bill of Material', compute='_compute_bom_count') used_in_bom_count = fields.Integer('# of BoM Where is Used', compute='_compute_used_in_bom_count') mo_count = fields.Integer('# Manufacturing Orders', compute='_compute_mo_count') produce_delay = fields.Float( 'Manufacturing Lead Time', default=0.0, help= "Average delay in days to produce this product. In the case of multi-level BOM, the manufacturing lead times of the components will be added." ) def _compute_bom_count(self): read_group_res = self.env['mrp.bom'].read_group( [('product_tmpl_id', 'in', self.ids)], ['product_tmpl_id'], ['product_tmpl_id']) mapped_data = dict([(data['product_tmpl_id'][0], data['product_tmpl_id_count']) for data in read_group_res]) for product in self: product.bom_count = mapped_data.get(product.id, 0) @api.multi def _compute_used_in_bom_count(self): for template in self: template.used_in_bom_count = self.env['mrp.bom'].search_count([ ('bom_line_ids.product_id', 'in', template.product_variant_ids.ids) ]) @api.multi def action_used_in_bom(self): self.ensure_one() action = self.env.ref('mrp.mrp_bom_form_action').read()[0] action['domain'] = [('bom_line_ids.product_id', 'in', self.product_variant_ids.ids)] return action @api.one def _compute_mo_count(self): # TDE FIXME: directly use a read_group self.mo_count = sum( self.mapped('product_variant_ids').mapped('mo_count')) @api.multi def action_view_mos(self): product_ids = self.mapped('product_variant_ids').ids action = self.env.ref('mrp.act_product_mrp_production').read()[0] action['domain'] = [('product_id', 'in', product_ids)] action['context'] = {} return action
class MrpBom(models.Model): _name = 'mrp.bom' _description = 'Bill of Material' _inherit = 'mrp.bom' sub_products = fields.One2many('mrp.subproduct', 'bom_id', 'Byproducts', copy=True)
class ProductAttribute(models.Model): _name = "product.attribute" _description = "Product Attribute" _order = 'sequence, name' name = fields.Char('Name', required=True, translate=True) value_ids = fields.One2many('product.attribute.value', 'attribute_id', 'Values', copy=True) sequence = fields.Integer('Sequence', help="Determine the display order") attribute_line_ids = fields.One2many('product.attribute.line', 'attribute_id', 'Lines') create_variant = fields.Boolean( default=True, help= "Check this if you want to create multiple variants for this attribute." )
class OpeningAccountMoveWizard(models.TransientModel): _name = 'account.opening' company_id = fields.Many2one(comodel_name='res.company', required=True) opening_move_id = fields.Many2one( string='Opening Journal Entry', comodel_name='account.move', related='company_id.account_opening_move_id') currency_id = fields.Many2one(comodel_name='res.currency', related='opening_move_id.currency_id') opening_move_line_ids = fields.One2many(string='Opening Journal Items', related="opening_move_id.line_ids") journal_id = fields.Many2one(string='Journal', comodel_name='account.journal', required=True, related='opening_move_id.journal_id') date = fields.Date(string='Opening Date', required=True, related='opening_move_id.date') def validate(self): self.opening_move_id.post() @api.onchange('opening_move_line_ids') def opening_move_line_ids_changed(self): debit_diff, credit_diff = self.company_id.get_opening_move_differences( self.opening_move_line_ids) unaffected_earnings_account = self.company_id.get_unaffected_earnings_account( ) balancing_line = self.opening_move_line_ids.filtered( lambda x: x.account_id == unaffected_earnings_account) if balancing_line: if not self.opening_move_line_ids == balancing_line and ( debit_diff or credit_diff): balancing_line.debit = credit_diff balancing_line.credit = debit_diff else: self.opening_move_line_ids -= balancing_line elif debit_diff or credit_diff: balancing_line = self.env['account.move.line'].new({ 'name': _('Automatic Balancing Line'), 'move_id': self.company_id.account_opening_move_id.id, 'account_id': unaffected_earnings_account.id, 'debit': credit_diff, 'credit': debit_diff, 'company_id': self.company_id, }) self.opening_move_line_ids += balancing_line
class SaleOrderLine(models.Model): _inherit = "sale.order.line" linked_line_id = fields.Many2one('sale.order.line', string='Linked Order Line', domain="[('order_id', '!=', order_id)]", ondelete='cascade') option_line_ids = fields.One2many('sale.order.line', 'linked_line_id', string='Options Linked')
class Product(models.Model): _inherit = 'product.product' event_ticket_ids = fields.One2many('event.event.ticket', 'product_id', string='Event Tickets') @api.onchange('event_ok') def _onchange_event_ok(self): """ Redirection, inheritance mechanism hides the method on the model """ if self.event_ok: self.type = 'service'
class RestaurantFloor(models.Model): _name = 'restaurant.floor' name = fields.Char('Floor Name', required=True, help='An internal identification of the restaurant floor') pos_config_id = fields.Many2one('pos.config', string='Point of Sale') background_image = fields.Binary('Background Image', attachment=True, help='A background image used to display a floor layout in the point of sale interface') background_color = fields.Char('Background Color', help='The background color of the floor layout, (must be specified in a html-compatible format)', default='rgb(210, 210, 210)') table_ids = fields.One2many('restaurant.table', 'floor_id', string='Tables', help='The list of tables in this floor') sequence = fields.Integer('Sequence', help='Used to sort Floors', default=1)
class PortalWizard(models.TransientModel): """ A wizard to manage the creation/removal of portal users. """ _name = 'portal.wizard' _description = 'Portal Access Management' def _default_portal(self): return self.env['res.groups'].search([('is_portal', '=', True)], limit=1) portal_id = fields.Many2one( 'res.groups', domain=[('is_portal', '=', True)], required=True, string='Portal', default=_default_portal, help="The portal that users can be added in or removed from.") user_ids = fields.One2many('portal.wizard.user', 'wizard_id', string='Users') welcome_message = fields.Text( 'Invitation Message', help= "This text is included in the email sent to new users of the portal.") @api.onchange('portal_id') def onchange_portal_id(self): # for each partner, determine corresponding portal.wizard.user records partner_ids = self.env.context.get('active_ids', []) contact_ids = set() user_changes = [] for partner in self.env['res.partner'].sudo().browse(partner_ids): contact_partners = partner.child_ids or [partner] for contact in contact_partners: # make sure that each contact appears at most once in the list if contact.id not in contact_ids: contact_ids.add(contact.id) in_portal = False if contact.user_ids: in_portal = self.portal_id in contact.user_ids[ 0].groups_id user_changes.append((0, 0, { 'partner_id': contact.id, 'email': contact.email, 'in_portal': in_portal, })) self.user_ids = user_changes @api.multi def action_apply(self): self.ensure_one() self.user_ids.action_apply() return {'type': 'ir.actions.act_window_close'}