class LeaveReportCalendar(models.Model): _name = "hr.leave.report.calendar" _description = 'Time Off Calendar' _auto = False _order = "start_datetime DESC, employee_id" name = fields.Char(string='Name', readonly=True) start_datetime = fields.Datetime(string='From', readonly=True) stop_datetime = fields.Datetime(string='To', readonly=True) tz = fields.Selection(_tz_get, string="Timezone", readonly=True) duration = fields.Float(string='Duration', readonly=True) employee_id = fields.Many2one('hr.employee', readonly=True) company_id = fields.Many2one('res.company', readonly=True) def init(self): tools.drop_view_if_exists(self._cr, 'hr_leave_report_calendar') self._cr.execute("""CREATE OR REPLACE VIEW hr_leave_report_calendar AS (SELECT row_number() OVER() AS id, ce.name AS name, ce.start_datetime AS start_datetime, ce.stop_datetime AS stop_datetime, ce.event_tz AS tz, ce.duration AS duration, hl.employee_id AS employee_id, em.company_id AS company_id FROM hr_leave hl LEFT JOIN calendar_event ce ON ce.id = hl.meeting_id LEFT JOIN hr_employee em ON em.id = hl.employee_id WHERE hl.state = 'validate'); """)
class MrpWorkorderLine(models.Model): _name = 'mrp.workorder.line' _inherit = ["mrp.abstract.workorder.line"] _description = "Workorder move line" raw_workorder_id = fields.Many2one('mrp.workorder', 'Component for Workorder', ondelete='cascade') finished_workorder_id = fields.Many2one('mrp.workorder', 'Finished Product for Workorder', ondelete='cascade') @api.model def _get_raw_workorder_inverse_name(self): return 'raw_workorder_id' @api.model def _get_finished_workoder_inverse_name(self): return 'finished_workorder_id' def _get_final_lots(self): return (self.raw_workorder_id or self.finished_workorder_id).finished_lot_id def _get_production(self): return (self.raw_workorder_id or self.finished_workorder_id).production_id
class SurveyLabel(models.Model): """ A suggested answer for a question """ _name = 'survey.label' _rec_name = 'value' _order = 'sequence,id' _description = 'Survey Label' question_id = fields.Many2one('survey.question', string='Question', ondelete='cascade') question_id_2 = fields.Many2one('survey.question', string='Question 2', ondelete='cascade') sequence = fields.Integer('Label Sequence order', default=10) value = fields.Char('Suggested value', translate=True, required=True) is_correct = fields.Boolean('Is a correct answer') answer_score = fields.Float( 'Score for this choice', help= "A positive score indicates a correct choice; a negative or null score indicates a wrong answer" ) @api.constrains('question_id', 'question_id_2') def _check_question_not_empty(self): """Ensure that field question_id XOR field question_id_2 is not null""" for label in self: if not bool(label.question_id) != bool(label.question_id_2): raise ValidationError( _("A label must be attached to only one question."))
class ProductAttributeCustomValue(models.Model): _name = "product.attribute.custom.value" _description = 'Product Attribute Custom Value' _order = 'custom_product_template_attribute_value_id, id' name = fields.Char("Name", compute='_compute_name') custom_product_template_attribute_value_id = fields.Many2one( 'product.template.attribute.value', string="Attribute Value", required=True, ondelete='restrict') sale_order_line_id = fields.Many2one('sale.order.line', string="Sales Order Line", required=True, ondelete='cascade') custom_value = fields.Char("Custom Value") @api.depends('custom_product_template_attribute_value_id.name', 'custom_value') def _compute_name(self): for record in self: name = (record.custom_value or '').strip() if record.custom_product_template_attribute_value_id.display_name: name = "%s: %s" % ( record.custom_product_template_attribute_value_id. display_name, name) record.name = name _sql_constraints = [( 'sol_custom_value_unique', 'unique(custom_product_template_attribute_value_id, sale_order_line_id)', "Only one Custom Value is allowed per Attribute Value per Sales Order Line." )]
class LinkTrackerClick(models.Model): _inherit = "link.tracker.click" mailing_trace_id = fields.Many2one('mailing.trace', string='Mail Statistics') mass_mailing_id = fields.Many2one('mailing.mailing', string='Mass Mailing') def _prepare_click_values_from_route(self, **route_values): click_values = super( LinkTrackerClick, self)._prepare_click_values_from_route(**route_values) if click_values.get('mailing_trace_id'): trace_sudo = self.env['mailing.trace'].sudo().browse( route_values['mailing_trace_id']).exists() if not trace_sudo: click_values['mailing_trace_id'] = False else: if not click_values.get('campaign_id'): click_values['campaign_id'] = trace_sudo.campaign_id.id if not click_values.get('mass_mailing_id'): click_values[ 'mass_mailing_id'] = trace_sudo.mass_mailing_id.id return click_values @api.model def add_click(self, code, **route_values): click = super(LinkTrackerClick, self).add_click(code, **route_values) if click and click.mailing_trace_id: click.mailing_trace_id.set_opened() click.mailing_trace_id.set_clicked() return click
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 ProductPackaging(models.Model): _name = "product.packaging" _description = "Product Packaging" _order = 'sequence' _check_company_auto = True name = fields.Char('Package Type', required=True) sequence = fields.Integer( 'Sequence', default=1, help="The first in the sequence is the default one.") product_id = fields.Many2one('product.product', string='Product', check_company=True) qty = fields.Float('Contained Quantity', help="Quantity of products contained in the packaging.") barcode = fields.Char( 'Barcode', copy=False, help= "Barcode used for packaging identification. Scan this packaging barcode from a transfer in the Barcode app to move all the contained units" ) product_uom_id = fields.Many2one('uom.uom', related='product_id.uom_id', readonly=True) company_id = fields.Many2one('res.company', 'Company', index=True)
class LunchCashMove(models.Model): """ Two types of cashmoves: payment (credit) or order (debit) """ _name = 'lunch.cashmove' _description = 'Lunch Cashmove' _order = 'date desc' currency_id = fields.Many2one( 'res.currency', default=lambda self: self.env.company.currency_id) user_id = fields.Many2one('res.users', 'User', default=lambda self: self.env.uid) date = fields.Date('Date', required=True, default=fields.Date.context_today) amount = fields.Float('Amount', required=True) description = fields.Text('Description') def name_get(self): return [(cashmove.id, '%s %s' % (_('Lunch Cashmove'), '#%d' % cashmove.id)) for cashmove in self] @api.model def get_wallet_balance(self, user, include_config=True): result = float_round(sum( move['amount'] for move in self.env['lunch.cashmove.report'].search_read([( 'user_id', '=', user.id)], ['amount'])), precision_digits=2) if include_config: result += user.company_id.lunch_minimum_threshold return result
class SliderFilter(models.Model): _name = "slider.filter" _order = "sequence asc" _description = "Slider Filter" name = fields.Char(string="Name", required=True, translate=True) sequence = fields.Integer(string='Sequence') website_published = fields.Boolean(string='Website Publish',default=True) filter_id = fields.Many2one('ir.filters', 'Filter', required=True,help="Product filter for slider items") slider_id = fields.Many2one('slider', string='Filter Product') def website_publish_button(self): """ Set slider filter published and unpublished on website :return: """ if self.website_published: self.write({'website_published': False}) else: self.write({'website_published': True}) @api.onchange('filter_id') def _onchange_filter_id(self): """ If selected Filter has no any product the raise the warning and remove that filter :return: """ if self.filter_id: domain = safe_eval(self.filter_id.domain) domain += ['|', ('website_id', '=', None), ('website_id', '=', self.slider_id.website_id.id), ('website_published', '=', True)] product_count = self.env['product.template'].sudo().search_count(domain) if product_count < 1: self.filter_id = False raise UserError(_('Sorry! You can not set filter which is content zero product.'))
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', domain= "['|', ('company_id', '=', False), ('company_id', '=', company_id)]") 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', default=lambda self: self.env.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 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) 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 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." ) 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 SMSTemplatePreview(models.TransientModel): _inherit = "sms.template" _name = "sms.template.preview" _description = "SMS Template Preview" @api.model def _selection_target_model(self): models = self.env['ir.model'].search([]) return [(model.model, model.name) for model in models] @api.model def _selection_languages(self): return self.env['res.lang'].get_installed() @api.model def default_get(self, fields): result = super(SMSTemplatePreview, self).default_get(fields) sms_template = self._context.get( 'default_sms_template_id') and self.env['sms.template'].browse( self._context['default_sms_template_id']) or False if sms_template and not result.get('res_id'): result['res_id'] = self.env[sms_template.model].search([], limit=1) return result sms_template_id = fields.Many2one( 'sms.template') # NOTE This should probably be required lang = fields.Selection(_selection_languages, string='Template Preview Language') model_id = fields.Many2one('ir.model', related="sms_template_id.model_id") res_id = fields.Integer(string='Record ID') resource_ref = fields.Reference(string='Record reference', selection='_selection_target_model', compute='_compute_resource_ref', inverse='_inverse_resource_ref') @api.depends('model_id', 'res_id') def _compute_resource_ref(self): for preview in self: if preview.model_id: preview.resource_ref = '%s,%s' % (preview.model_id.model, preview.res_id or 0) else: preview.resource_ref = False def _inverse_resource_ref(self): for preview in self: if preview.resource_ref: preview.res_id = preview.resource_ref.id @api.onchange('lang', 'resource_ref') def on_change_resource_ref(self): # Update res_id and body depending of the resource_ref if self.resource_ref: self.res_id = self.resource_ref.id if self.sms_template_id: template = self.sms_template_id.with_context(lang=self.lang) self.body = template._render_template( template.body, template.model, self.res_id or 0) if self.resource_ref else template.body
class Partner(models.Model): _inherit = 'res.partner' _check_company_auto = True property_stock_customer = fields.Many2one( 'stock.location', string="Customer Location", company_dependent=True, check_company=True, domain= "['|', ('company_id', '=', False), ('company_id', '=', allowed_company_ids[0])]", help= "The stock location used as destination when sending goods to this contact." ) property_stock_supplier = fields.Many2one( 'stock.location', string="Vendor Location", company_dependent=True, check_company=True, domain= "['|', ('company_id', '=', False), ('company_id', '=', allowed_company_ids[0])]", help= "The stock location used as source when receiving goods from this contact." ) picking_warn = fields.Selection(WARNING_MESSAGE, 'Stock Picking', help=WARNING_HELP, default='no-message') picking_warn_msg = fields.Text('Message for Stock Picking')
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') mobile = fields.Char(string='Mobile') name = fields.Char(string='Name', index=True) 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, 'mobile': self.mobile or self.editor_id.sale_order_id.partner_id.mobile, '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 EmployeeSkill(models.Model): _name = 'hr.employee.skill' _description = "Skill level for an employee" _rec_name = 'skill_id' _order = "skill_level_id" employee_id = fields.Many2one('hr.employee', required=True, ondelete='cascade') skill_id = fields.Many2one('hr.skill', required=True) skill_level_id = fields.Many2one('hr.skill.level', required=True) skill_type_id = fields.Many2one('hr.skill.type', required=True) level_progress = fields.Integer(related='skill_level_id.level_progress') _sql_constraints = [ ('_unique_skill', 'unique (employee_id, skill_id)', "Two levels for the same skill is not allowed"), ] @api.constrains('skill_id', 'skill_type_id') def _check_skill_type(self): for record in self: if record.skill_id not in record.skill_type_id.skill_ids: raise ValidationError(_("The skill %s and skill type %s doesn't match") % (record.skill_id.name, record.skill_type_id.name)) @api.constrains('skill_type_id', 'skill_level_id') def _check_skill_level(self): for record in self: if record.skill_level_id not in record.skill_type_id.skill_level_ids: raise ValidationError(_("The skill level %s is not valid for skill type: %s ") % (record.skill_level_id.name, record.skill_type_id.name))
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 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 ReportEventRegistrationQuestions(models.Model): _name = "event.question.report" _auto = False _description = 'Event Question Report' attendee_id = fields.Many2one(comodel_name='event.registration', string='Registration') question_id = fields.Many2one(comodel_name='event.question', string='Question') answer_id = fields.Many2one(comodel_name='event.answer', string='Answer') event_id = fields.Many2one(comodel_name='event.event', string='Event') def init(self): """ Event Question main report """ tools.drop_view_if_exists(self._cr, 'event_question_report') self._cr.execute(""" CREATE VIEW event_question_report AS ( SELECT att_answer.id as id, att_answer.event_registration_id as attendee_id, answer.question_id as question_id, answer.id as answer_id, question.event_id as event_id FROM event_registration_answer as att_answer LEFT JOIN event_answer as answer ON answer.id = att_answer.event_answer_id LEFT JOIN event_question as question ON question.id = answer.question_id GROUP BY attendee_id, event_id, question_id, answer_id, att_answer.id )""")
class StockAssignSerialNumbers(models.TransientModel): _name = 'stock.assign.serial' _description = 'Stock Assign Serial Numbers' def _default_next_serial_count(self): move = self.env['stock.move'].browse( self.env.context.get('default_move_id')) if move.exists(): filtered_move_lines = move.move_line_ids.filtered( lambda l: not l.lot_name and not l.lot_id) return len(filtered_move_lines) product_id = fields.Many2one('product.product', 'Product', related='move_id.product_id', required=True) move_id = fields.Many2one('stock.move', required=True) next_serial_number = fields.Char('First SN', required=True) next_serial_count = fields.Integer('Number of SN', default=_default_next_serial_count, required=True) @api.constrains('next_serial_count') def _check_next_serial_count(self): for wizard in self: if wizard.next_serial_count < 1: raise ValidationError( _("The number of Serial Numbers to generate must greater than zero." )) def generate_serial_numbers(self): self.ensure_one() self.move_id.next_serial = self.next_serial_number or "" return self.move_id._generate_serial_numbers( next_serial_count=self.next_serial_count)
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 MonetaryCustom(models.Model): _name = 'test_new_api.monetary_custom' _description = 'Monetary Related Custom' monetary_id = fields.Many2one('test_new_api.monetary_base') x_currency_id = fields.Many2one('res.currency', related='monetary_id.base_currency_id') x_amount = fields.Monetary(related='monetary_id.amount')
class AccountBankStatement(models.Model): _inherit = 'account.bank.statement' pos_session_id = fields.Many2one('pos.session', string="Session", copy=False) account_id = fields.Many2one('account.account', related='journal_id.default_debit_account_id', readonly=True) def check_confirm_bank(self): for bs in self: if bs.pos_session_id.state in ( 'opened', 'closing_control') and bs.state == 'open': raise UserError( _("You can't validate a bank statement that is used in an opened Session of a Point of Sale." )) return super(AccountBankStatement, self).check_confirm_bank() def unlink(self): for bs in self: if bs.pos_session_id: raise UserError( _("You cannot delete a bank statement used in an open Point of Sale session." )) return super(AccountBankStatement, self).unlink()
class MonetaryInherits(models.Model): _name = 'test_new_api.monetary_inherits' _description = 'Monetary Inherits' _inherits = {'test_new_api.monetary_base': 'monetary_id'} monetary_id = fields.Many2one('test_new_api.monetary_base', required=True, ondelete='cascade') currency_id = fields.Many2one('res.currency')
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') 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 Category(models.Model): _name = 'test_new_api.category' _description = 'Test New API Category' _order = 'name' _parent_store = True _parent_name = 'parent' name = fields.Char(required=True) color = fields.Integer('Color Index') parent = fields.Many2one('test_new_api.category', ondelete='cascade') parent_path = fields.Char(index=True) root_categ = fields.Many2one(_name, compute='_compute_root_categ') display_name = fields.Char(compute='_compute_display_name', inverse='_inverse_display_name') dummy = fields.Char(store=False) discussions = fields.Many2many('test_new_api.discussion', 'test_new_api_discussion_category', 'category', 'discussion') _sql_constraints = [ ('positive_color', 'CHECK(color >= 0)', 'The color code must be positive !') ] @api.depends('name', 'parent.display_name') # this definition is recursive def _compute_display_name(self): for cat in self: if cat.parent: cat.display_name = cat.parent.display_name + ' / ' + cat.name else: cat.display_name = cat.name @api.depends('parent') def _compute_root_categ(self): for cat in self: current = cat while current.parent: current = current.parent cat.root_categ = current def _inverse_display_name(self): for cat in self: names = cat.display_name.split('/') # determine sequence of categories categories = [] for name in names[:-1]: category = self.search([('name', 'ilike', name.strip())]) categories.append(category[0]) categories.append(cat) # assign parents following sequence for parent, child in zip(categories, categories[1:]): if parent and child: child.parent = parent # assign name of last category, and reassign display_name (to normalize it) cat.name = names[-1].strip() def _read(self, fields): # DLE P45: `test_31_prefetch`, # with self.assertRaises(AccessError): # cat1.name if self.search_count([('id', 'in', self._ids), ('name', '=', 'NOACCESS')]): raise AccessError('Sorry') return super(Category, self)._read(fields)
class Applicant(models.Model): _inherit = "hr.applicant" survey_id = fields.Many2one('survey.survey', related='job_id.survey_id', string="Survey", readonly=True) response_id = fields.Many2one('survey.user_input', "Response", ondelete="set null") def action_start_survey(self): self.ensure_one() # create a response and link it to this applicant if not self.response_id: response = self.survey_id._create_answer(partner=self.partner_id) self.response_id = response.id else: response = self.response_id # grab the token of the response and start surveying return self.survey_id.with_context( survey_token=response.token).action_start_survey() def action_print_survey(self): """ If response is available then print this response otherwise print survey form (print template of the survey) """ self.ensure_one() if not self.response_id: return self.survey_id.action_print_survey() else: response = self.response_id return self.survey_id.with_context( survey_token=response.token).action_print_survey()
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='Product Price', required=True) split_method = fields.Selection(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.split_method or 'equal' self.price_unit = self.product_id.standard_price or 0.0 accounts_data = self.product_id.product_tmpl_id.get_product_accounts() self.account_id = accounts_data['stock_input']
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 StockScrap(models.Model): _inherit = 'stock.scrap' production_id = fields.Many2one( 'mrp.production', 'Manufacturing Order', states={'done': [('readonly', True)]}, check_company=True) workorder_id = fields.Many2one( 'mrp.workorder', 'Work Order', states={'done': [('readonly', True)]}, help='Not to restrict or prefer quants, but informative.', check_company=True) @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)