class GamificationBadgeUserWizard(models.TransientModel): _inherit = 'gamification.badge.user.wizard' employee_id = fields.Many2one('hr.employee', string='Employee', required=True) user_id = fields.Many2one('res.users', string='User', related='employee_id.user_id', store=False, readonly=True, compute_sudo=True) @api.multi def action_grant_badge(self): """Wizard action for sending a badge to a chosen employee""" if not self.user_id: raise UserError(_('You can send badges only to employees linked to a user.')) if self.env.uid == self.user_id.id: raise UserError(_('You can not send a badge to yourself.')) values = { 'user_id': self.user_id.id, 'sender_id': self.env.uid, 'badge_id': self.badge_id.id, 'employee_id': self.employee_id.id, 'comment': self.comment, } return self.env['gamification.badge.user'].create(values)._send_badge()
class FleetVehicleLogServices(models.Model): _name = 'fleet.vehicle.log.services' _inherits = {'fleet.vehicle.cost': 'cost_id'} _description = 'Services for vehicles' @api.model def default_get(self, default_fields): res = super(FleetVehicleLogServices, self).default_get(default_fields) service = self.env.ref('fleet.type_service_service_8', raise_if_not_found=False) res.update({ 'date': fields.Date.context_today(self), 'cost_subtype_id': service and service.id or False, 'cost_type': 'services' }) return res purchaser_id = fields.Many2one('res.partner', 'Purchaser', domain="['|',('customer','=',True),('employee','=',True)]") inv_ref = fields.Char('Invoice Reference') vendor_id = fields.Many2one('res.partner', 'Vendor', domain="[('supplier','=',True)]") # we need to keep this field as a related with store=True because the graph view doesn't support # (1) to address fields from inherited table and (2) fields that aren't stored in database cost_amount = fields.Float(related='cost_id.amount', string='Amount', store=True, readonly=False) notes = fields.Text() cost_id = fields.Many2one('fleet.vehicle.cost', 'Cost', required=True, ondelete='cascade') @api.onchange('vehicle_id') def _onchange_vehicle(self): if self.vehicle_id: self.odometer_unit = self.vehicle_id.odometer_unit self.purchaser_id = self.vehicle_id.driver_id.id
class LeadTest(models.Model): _name = "base.automation.lead.test" _description = "Automated 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 IrActionsActWindowView(models.Model): _name = 'ir.actions.act_window.view' _description = 'Action Window View' _table = 'ir_act_window_view' _rec_name = 'view_id' _order = 'sequence,id' sequence = fields.Integer() view_id = fields.Many2one('ir.ui.view', string='View') view_mode = fields.Selection(VIEW_TYPES, string='View Type', required=True) act_window_id = fields.Many2one('ir.actions.act_window', string='Action', ondelete='cascade') multi = fields.Boolean( string='On Multiple Doc.', help= "If set to true, the action will not be displayed on the right toolbar of a form view." ) @api.model_cr_context def _auto_init(self): res = super(IrActionsActWindowView, self)._auto_init() tools.create_unique_index(self._cr, 'act_window_view_unique_mode_per_action', self._table, ['act_window_id', 'view_mode']) return res
class HrContract(models.Model): _inherit = 'hr.contract' _description = 'Employee Contract' analytic_account_id = fields.Many2one('account.analytic.account', 'Analytic Account') journal_id = fields.Many2one('account.journal', 'Salary Journal')
class EventMenu(models.Model): _name = "website.event.menu" _description = "Website Event Menu" menu_id = fields.Many2one('website.menu', string='Menu', ondelete='cascade') event_id = fields.Many2one('event.event', string='Event', ondelete='cascade') menu_type = fields.Selection([('track', 'Event Tracks Menus'), ('track_proposal', 'Event Proposals Menus')])
class MrpSubProduct(models.Model): _name = 'mrp.subproduct' _description = 'Byproduct' product_id = fields.Many2one('product.product', 'Product', required=True) product_qty = fields.Float( 'Product Qty', default=1.0, digits=dp.get_precision('Product Unit of Measure'), required=True) product_uom_id = fields.Many2one('uom.uom', 'Unit of Measure', required=True) bom_id = fields.Many2one('mrp.bom', 'BoM', ondelete='cascade') operation_id = fields.Many2one('mrp.routing.workcenter', 'Produced at Operation') @api.onchange('product_id') def onchange_product_id(self): """ Changes UoM if product_id changes. """ if self.product_id: self.product_uom_id = self.product_id.uom_id.id @api.onchange('product_uom_id') def onchange_uom(self): res = {} if self.product_uom_id and self.product_id and self.product_uom_id.category_id != self.product_id.uom_id.category_id: res['warning'] = { 'title': _('Warning'), 'message': _('The unit of measure you chose is in a different category than the product unit of measure.') } self.product_uom_id = self.product_id.uom_id.id return res
class RecruitmentSource(models.Model): _name = "hr.recruitment.source" _description = "Source of Applicants" _inherits = {"utm.source": "source_id"} source_id = fields.Many2one('utm.source', "Source", ondelete='cascade', required=True) email = fields.Char(related='alias_id.display_name', string="Email", readonly=True) job_id = fields.Many2one('hr.job', "Job ID") alias_id = fields.Many2one('mail.alias', "Alias ID") @api.multi def create_alias(self): campaign = self.env.ref('hr_recruitment.utm_campaign_job') medium = self.env.ref('utm.utm_medium_email') for source in self: vals = { 'alias_parent_thread_id': source.job_id.id, 'alias_name': "%s+%s" % (source.job_id.alias_name or source.job_id.name, source.name), 'alias_defaults': { 'job_id': source.job_id.id, 'campaign_id': campaign.id, 'medium_id': medium.id, 'source_id': source.source_id.id, }, } source.alias_id = self.with_context(alias_model_name='hr.applicant', alias_parent_model_name='hr.job').env['mail.alias'].create(vals) source.name = source.source_id.name
class ModuleDependency(models.Model): _name = "ir.module.module.dependency" _description = "Module dependency" # the dependency name name = fields.Char(index=True) # the module that depends on it module_id = fields.Many2one('ir.module.module', 'Module', ondelete='cascade') # the module corresponding to the dependency, and its status depend_id = fields.Many2one('ir.module.module', 'Dependency', compute='_compute_depend') state = fields.Selection(DEP_STATES, string='Status', compute='_compute_state') @api.multi @api.depends('name') def _compute_depend(self): # retrieve all modules corresponding to the dependency names names = list(set(dep.name for dep in self)) mods = self.env['ir.module.module'].search([('name', 'in', names)]) # index modules by name, and assign dependencies name_mod = dict((mod.name, mod) for mod in mods) for dep in self: dep.depend_id = name_mod.get(dep.name) @api.one @api.depends('depend_id.state') def _compute_state(self): self.state = self.depend_id.state or 'unknown'
class ModuleExclusion(models.Model): _name = "ir.module.module.exclusion" _description = "Module exclusion" # the exclusion name name = fields.Char(index=True) # the module that excludes it module_id = fields.Many2one('ir.module.module', 'Module', ondelete='cascade') # the module corresponding to the exclusion, and its status exclusion_id = fields.Many2one('ir.module.module', 'Exclusion Module', compute='_compute_exclusion') state = fields.Selection(DEP_STATES, string='Status', compute='_compute_state') @api.multi @api.depends('name') def _compute_exclusion(self): # retrieve all modules corresponding to the exclusion names names = list(set(excl.name for excl in self)) mods = self.env['ir.module.module'].search([('name', 'in', names)]) # index modules by name, and assign dependencies name_mod = {mod.name: mod for mod in mods} for excl in self: excl.exclusion_id = name_mod.get(excl.name) @api.one @api.depends('exclusion_id.state') def _compute_state(self): self.state = self.exclusion_id.state or 'unknown'
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 FleetVehicleOdometer(models.Model): _name = 'fleet.vehicle.odometer' _description = 'Odometer log for a vehicle' _order = 'date desc' name = fields.Char(compute='_compute_vehicle_log_name', store=True) date = fields.Date(default=fields.Date.context_today) value = fields.Float('Odometer Value', group_operator="max") vehicle_id = fields.Many2one('fleet.vehicle', 'Vehicle', required=True) unit = fields.Selection(related='vehicle_id.odometer_unit', string="Unit", readonly=True) driver_id = fields.Many2one(related="vehicle_id.driver_id", string="Driver", readonly=False) @api.depends('vehicle_id', 'date') def _compute_vehicle_log_name(self): for record in self: name = record.vehicle_id.name if not name: name = str(record.date) elif record.date: name += ' / ' + str(record.date) record.name = name @api.onchange('vehicle_id') def _onchange_vehicle(self): if self.vehicle_id: self.unit = self.vehicle_id.odometer_unit
class LandedCostLine(models.Model): _name = 'stock.landed.cost.lines' _description = 'Stock Landed Cost Line' name = fields.Char('Description') cost_id = fields.Many2one('stock.landed.cost', 'Landed Cost', required=True, ondelete='cascade') product_id = fields.Many2one('product.product', 'Product', required=True) price_unit = fields.Float('Cost', digits=dp.get_precision('Product Price'), required=True) split_method = fields.Selection(product.SPLIT_METHOD, string='Split Method', required=True) account_id = fields.Many2one('account.account', 'Account', domain=[('deprecated', '=', False)]) @api.onchange('product_id') def onchange_product_id(self): if not self.product_id: self.quantity = 0.0 self.name = self.product_id.name or '' self.split_method = self.product_id.split_method or 'equal' self.price_unit = self.product_id.standard_price or 0.0 self.account_id = self.product_id.property_account_expense_id.id or self.product_id.categ_id.property_account_expense_categ_id.id
class EventQuestion(models.Model): _name = 'event.question' _rec_name = 'title' _order = 'sequence,id' _description = 'Event Question' 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 cannot belong to both the event category and itself.')) @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 and not vals.get('answer_ids'): vals['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 RecruitmentStage(models.Model): _name = "hr.recruitment.stage" _description = "Recruitment Stages" _order = 'sequence' name = fields.Char("Stage name", required=True, translate=True) sequence = fields.Integer( "Sequence", default=10, help="Gives the sequence order when displaying a list of stages.") job_id = fields.Many2one('hr.job', string='Job Specific', ondelete='cascade', help='Specific job that uses this stage. Other jobs will not use this stage.') requirements = fields.Text("Requirements") template_id = fields.Many2one( 'mail.template', "Automated Email", help="If set, a message is posted on the applicant using the template when the applicant is set to the stage.") fold = fields.Boolean( "Folded in Recruitment Pipe", help="This stage is folded in the kanban view when there are no records in that stage to display.") legend_blocked = fields.Char( 'Red Kanban Label', default=lambda self: _('Blocked'), translate=True, required=True) legend_done = fields.Char( 'Green Kanban Label', default=lambda self: _('Ready for Next Stage'), translate=True, required=True) legend_normal = fields.Char( 'Grey Kanban Label', default=lambda self: _('In Progress'), translate=True, required=True) @api.model def default_get(self, fields): if self._context and self._context.get('default_job_id') and not self._context.get('hr_recruitment_stage_mono', False): context = dict(self._context) context.pop('default_job_id') self = self.with_context(context) return super(RecruitmentStage, self).default_get(fields)
class AccountAnalyticGroup(models.Model): _name = 'account.analytic.group' _description = 'Analytic Categories' _parent_store = True _rec_name = 'complete_name' name = fields.Char(required=True) description = fields.Text(string='Description') parent_id = fields.Many2one('account.analytic.group', string="Parent", ondelete='cascade') parent_path = fields.Char(index=True) children_ids = fields.One2many('account.analytic.group', 'parent_id', string="Childrens") complete_name = fields.Char('Complete Name', compute='_compute_complete_name', store=True) company_id = fields.Many2one('res.company', string='Company') @api.depends('name', 'parent_id.complete_name') def _compute_complete_name(self): for group in self: if group.parent_id: group.complete_name = '%s / %s' % ( group.parent_id.complete_name, group.name) else: group.complete_name = group.name
class ProjectProductEmployeeMap(models.Model): _name = 'project.sale.line.employee.map' _description = 'Project Sales line, employee mapping' @api.model def _default_project_id(self): if self._context.get('active_id'): return self._context['active_id'] return False project_id = fields.Many2one('project.project', "Project", domain=[('billable_type', '!=', 'no')], required=True, default=_default_project_id) employee_id = fields.Many2one('hr.employee', "Employee", required=True) sale_line_id = fields.Many2one('sale.order.line', "Sale Order Item", domain=[('is_service', '=', True)], required=True) price_unit = fields.Float(related='sale_line_id.price_unit', readonly=True) _sql_constraints = [ ('uniqueness_employee', 'UNIQUE(project_id,employee_id)', 'An employee cannot be selected more than once in the mapping. Please remove duplicate(s) and try again.' ), ]
class ThemeMenu(models.Model): _name = 'theme.website.menu' _description = 'Website Theme Menu' name = fields.Char(required=True, translate=True) url = fields.Char(default='') page_id = fields.Many2one('theme.website.page', ondelete='cascade') new_window = fields.Boolean('New Window') sequence = fields.Integer() parent_id = fields.Many2one('theme.website.menu', index=True, ondelete="cascade") copy_ids = fields.One2many('website.menu', 'theme_template_id', 'Menu using a copy of me', copy=False, readonly=True) @api.multi def _convert_to_base_model(self, website, **kwargs): self.ensure_one() page_id = self.page_id.copy_ids.filtered( lambda x: x.website_id == website) parent_id = self.copy_ids.filtered(lambda x: x.website_id == website) new_menu = { 'name': self.name, 'url': self.url, 'page_id': page_id and page_id.id or False, 'new_window': self.new_window, 'sequence': self.sequence, 'parent_id': parent_id and parent_id.id or False, 'theme_template_id': self.id, } return new_menu
class EventTypeMail(models.Model): """ Template of event.mail to attach to event.type. Those will be copied upon all events created in that type to ease event creation. """ _name = 'event.type.mail' _description = 'Mail Scheduling on Event Category' event_type_id = fields.Many2one('event.type', string='Event Type', ondelete='cascade', required=True) interval_nbr = fields.Integer('Interval', default=1) interval_unit = fields.Selection([('now', 'Immediately'), ('hours', 'Hour(s)'), ('days', 'Day(s)'), ('weeks', 'Week(s)'), ('months', 'Month(s)')], string='Unit', default='hours', required=True) interval_type = fields.Selection([('after_sub', 'After each registration'), ('before_event', 'Before the event'), ('after_event', 'After the event')], string='Trigger', default="before_event", required=True) template_id = fields.Many2one( 'mail.template', string='Email Template', domain=[('model', '=', 'event.registration')], required=True, ondelete='restrict', help= 'This field contains the template of the mail that will be automatically sent' )
class LinkTracker(models.Model): _inherit = "link.tracker" mass_mailing_id = fields.Many2one('mail.mass_mailing', string='Mass Mailing') mass_mailing_campaign_id = fields.Many2one('mail.mass_mailing.campaign', string='Mass Mailing Campaign')
class LinkTrackerClick(models.Model): _inherit = "link.tracker.click" mail_stat_id = fields.Many2one('mail.mail.statistics', string='Mail Statistics') mass_mailing_id = fields.Many2one('mail.mass_mailing', string='Mass Mailing') mass_mailing_campaign_id = fields.Many2one('mail.mass_mailing.campaign', string='Mass Mailing Campaign') @api.model def add_click(self, code, ip, country_code, stat_id=False): res = super(LinkTrackerClick, self).add_click(code, ip, country_code, stat_id=stat_id) if stat_id: stat_sudo = self.env['mail.mail.statistics'].sudo().browse(stat_id) stat_sudo.set_opened() stat_sudo.set_clicked() return res def _get_click_values_from_route(self, route_values): click_values = super(LinkTrackerClick, self)._get_click_values_from_route(route_values) if route_values['stat_id']: mail_stat = self.env['mail.mail.statistics'].browse( route_values['stat_id']) click_values['mail_stat_id'] = mail_stat.id if mail_stat.mass_mailing_campaign_id: click_values[ 'mass_mailing_campaign_id'] = mail_stat.mass_mailing_campaign_id.id if mail_stat.mass_mailing_id: click_values['mass_mailing_id'] = mail_stat.mass_mailing_id.id return click_values
class LineTest(models.Model): _name = "base.automation.line.test" _description = "Automated Rule Line Test" name = fields.Char() lead_id = fields.Many2one('base.automation.lead.test', ondelete='cascade') user_id = fields.Many2one('res.users')
class grant_badge_wizard(models.TransientModel): """ Wizard allowing to grant a badge to a user""" _name = 'gamification.badge.user.wizard' _description = 'Gamification User Badge Wizard' user_id = fields.Many2one("res.users", string='User', required=True) badge_id = fields.Many2one("gamification.badge", string='Badge', required=True) comment = fields.Text('Comment') @api.multi def action_grant_badge(self): """Wizard action for sending a badge to a chosen user""" BadgeUser = self.env['gamification.badge.user'] uid = self.env.uid for wiz in self: if uid == wiz.user_id.id: raise exceptions.UserError(_('You can not grant a badge to yourself.')) #create the badge BadgeUser.create({ 'user_id': wiz.user_id.id, 'sender_id': uid, 'badge_id': wiz.badge_id.id, 'comment': wiz.comment, })._send_badge() return True
class RegistrationEditorLine(models.TransientModel): """Event Registration""" _name = "registration.editor.line" _description = 'Edit Attendee Line on Sales Confirmation' editor_id = fields.Many2one('registration.editor') sale_order_line_id = fields.Many2one('sale.order.line', string='Sales Order Line') event_id = fields.Many2one('event.event', string='Event', required=True) registration_id = fields.Many2one('event.registration', 'Original Registration') event_ticket_id = fields.Many2one('event.event.ticket', string='Event Ticket') email = fields.Char(string='Email') phone = fields.Char(string='Phone') name = fields.Char(string='Name', index=True) @api.multi def get_registration_data(self): self.ensure_one() return { 'event_id': self.event_id.id, 'event_ticket_id': self.event_ticket_id.id, 'partner_id': self.editor_id.sale_order_id.partner_id.id, 'name': self.name or self.editor_id.sale_order_id.partner_id.name, 'phone': self.phone or self.editor_id.sale_order_id.partner_id.phone, 'email': self.email or self.editor_id.sale_order_id.partner_id.email, 'origin': self.editor_id.sale_order_id.name, 'sale_order_id': self.editor_id.sale_order_id.id, 'sale_order_line_id': self.sale_order_line_id.id, }
class StockLocation(models.Model): _inherit = "stock.location" valuation_in_account_id = fields.Many2one( 'account.account', 'Stock Valuation Account (Incoming)', domain=[('internal_type', '=', 'other'), ('deprecated', '=', False)], help="Used for real-time inventory valuation. When set on a virtual location (non internal type), " "this account will be used to hold the value of products being moved from an internal location " "into this location, instead of the generic Stock Output Account set on the product. " "This has no effect for internal locations.") valuation_out_account_id = fields.Many2one( 'account.account', 'Stock Valuation Account (Outgoing)', domain=[('internal_type', '=', 'other'), ('deprecated', '=', False)], help="Used for real-time inventory valuation. When set on a virtual location (non internal type), " "this account will be used to hold the value of products being moved out of this location " "and into an internal location, instead of the generic Stock Output Account set on the product. " "This has no effect for internal locations.") def _should_be_valued(self): """ This method returns a boolean reflecting whether the products stored in `self` should be considered when valuating the stock of a company. """ self.ensure_one() if self.usage == 'internal' or (self.usage == 'transit' and self.company_id): return True return False
class StockScrap(models.Model): _inherit = 'stock.scrap' production_id = fields.Many2one( 'mrp.production', 'Manufacturing Order', states={'done': [('readonly', True)]}) workorder_id = fields.Many2one( 'mrp.workorder', 'Work Order', states={'done': [('readonly', True)]}, help='Not to restrict or prefer quants, but informative.') @api.onchange('workorder_id') def _onchange_workorder_id(self): if self.workorder_id: self.location_id = self.workorder_id.production_id.location_src_id.id @api.onchange('production_id') def _onchange_production_id(self): if self.production_id: self.location_id = self.production_id.move_raw_ids.filtered(lambda x: x.state not in ('done', 'cancel')) and self.production_id.location_src_id.id or self.production_id.location_dest_id.id def _prepare_move_values(self): vals = super(StockScrap, self)._prepare_move_values() if self.production_id: vals['origin'] = vals['origin'] or self.production_id.name if self.product_id in self.production_id.move_finished_ids.mapped('product_id'): vals.update({'production_id': self.production_id.id}) else: vals.update({'raw_material_production_id': self.production_id.id}) return vals def _get_origin_moves(self): return super(StockScrap, self)._get_origin_moves() or self.production_id and self.production_id.move_raw_ids.filtered(lambda x: x.product_id == self.product_id)
class HrPayslipLine(models.Model): _name = 'hr.payslip.line' _inherit = 'hr.salary.rule' _description = 'Payslip Line' _order = 'contract_id, sequence' slip_id = fields.Many2one('hr.payslip', string='Pay Slip', required=True, ondelete='cascade') salary_rule_id = fields.Many2one('hr.salary.rule', string='Rule', required=True) employee_id = fields.Many2one('hr.employee', string='Employee', required=True) contract_id = fields.Many2one('hr.contract', string='Contract', required=True, index=True) rate = fields.Float(string='Rate (%)', digits=dp.get_precision('Payroll Rate'), default=100.0) amount = fields.Float(digits=dp.get_precision('Payroll')) quantity = fields.Float(digits=dp.get_precision('Payroll'), default=1.0) total = fields.Float(compute='_compute_total', string='Total', digits=dp.get_precision('Payroll'), store=True) @api.depends('quantity', 'amount', 'rate') def _compute_total(self): for line in self: line.total = float(line.quantity) * line.amount * line.rate / 100 @api.model_create_multi def create(self, vals_list): for values in vals_list: if 'employee_id' not in values or 'contract_id' not in values: payslip = self.env['hr.payslip'].browse(values.get('slip_id')) values['employee_id'] = values.get('employee_id') or payslip.employee_id.id values['contract_id'] = values.get('contract_id') or payslip.contract_id and payslip.contract_id.id if not values['contract_id']: raise UserError(_('You must set a contract to create a payslip line.')) return super(HrPayslipLine, self).create(vals_list)
class ProductAttributeCustomValue(models.Model): _name = "product.attribute.custom.value" _rec_name = 'custom_value' _description = 'Product Attribute Custom Value' attribute_value_id = fields.Many2one('product.attribute.value', string='Attribute') sale_order_line_id = fields.Many2one('sale.order.line', string='Sale order line') custom_value = fields.Char('Custom value')
class CurrencyRate(models.Model): _name = "res.currency.rate" _description = "Currency Rate" _order = "name desc" name = fields.Date(string='Date', required=True, index=True, default=lambda self: fields.Date.today()) rate = fields.Float( digits=(12, 6), default=1.0, help='The rate of the currency to the currency of rate 1') currency_id = fields.Many2one('res.currency', string='Currency', readonly=True) company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id) _sql_constraints = [ ('unique_name_per_day', 'unique (name,currency_id,company_id)', 'Only one currency rate per day allowed!'), ('currency_rate_check', 'CHECK (rate>0)', 'The currency rate must be strictly positive.'), ] @api.model def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None): if operator in ['=', '!=']: try: date_format = '%Y-%m-%d' if self._context.get('lang'): lang_id = self.env['res.lang']._search( [('code', '=', self._context['lang'])], access_rights_uid=name_get_uid) if lang_id: date_format = self.browse(lang_id).date_format name = time.strftime('%Y-%m-%d', time.strptime(name, date_format)) except ValueError: try: args.append(('rate', operator, float(name))) except ValueError: return [] name = '' operator = 'ilike' return super(CurrencyRate, self)._name_search(name, args=args, operator=operator, limit=limit, name_get_uid=name_get_uid)
class StockTrackingLines(models.TransientModel): _name = 'stock.track.line' _description = 'Stock Track Line' product_id = fields.Many2one('product.product', 'Product', readonly=True) tracking = fields.Selection([('lot', 'Tracked by lot'), ('serial', 'Tracked by serial number')], readonly=True) wizard_id = fields.Many2one('stock.track.confirmation', readonly=True)