class ResConfigSettings(models.TransientModel): _inherit = "res.config.settings" google_drive_authorization_code = fields.Char( string='Authorization Code', config_parameter='google_drive_authorization_code') google_drive_uri = fields.Char( compute='_compute_drive_uri', string='URI', help="The URL to generate the authorization code from Google") @api.depends('google_drive_authorization_code') def _compute_drive_uri(self): google_drive_uri = self.env['google.service']._get_google_token_uri( 'drive', scope=self.env['google.drive.config'].get_google_scope()) for config in self: config.google_drive_uri = google_drive_uri def set_values(self): params = self.env['ir.config_parameter'].sudo() authorization_code_before = params.get_param( 'google_drive_authorization_code') super(ResConfigSettings, self).set_values() authorization_code = self.google_drive_authorization_code if authorization_code != authorization_code_before: refresh_token = (self.env['google.service'].generate_refresh_token( 'drive', authorization_code) if authorization_code else False) params.set_param('google_drive_refresh_token', refresh_token)
class Company(models.Model): _inherit = 'res.company' street_name = fields.Char('Street Name', compute='_compute_address', inverse='_inverse_street_name') street_number = fields.Char('House Number', compute='_compute_address', inverse='_inverse_street_number') street_number2 = fields.Char('Door Number', compute='_compute_address', inverse='_inverse_street_number2') def _get_company_address_fields(self, partner): address_fields = super(Company, self)._get_company_address_fields(partner) address_fields.update({ 'street_name': partner.street_name, 'street_number': partner.street_number, 'street_number2': partner.street_number2, }) return address_fields def _inverse_street_name(self): for company in self: company.partner_id.street_name = company.street_name def _inverse_street_number(self): for company in self: company.partner_id.street_number = company.street_number def _inverse_street_number2(self): for company in self: company.partner_id.street_number2 = company.street_number2
class PartnerTitle(models.Model): _name = 'res.partner.title' _order = 'name' _description = 'Partner Title' name = fields.Char(string='Title', required=True, translate=True) shortcut = fields.Char(string='Abbreviation', translate=True)
class IrActionsActClient(models.Model): _name = 'ir.actions.client' _description = 'Client Action' _inherit = 'ir.actions.actions' _table = 'ir_act_client' _sequence = 'ir_actions_id_seq' _order = 'name' name = fields.Char(string='Action Name', translate=True) type = fields.Char(default='ir.actions.client') tag = fields.Char(string='Client action tag', required=True, help="An arbitrary string, interpreted by the client" " according to its own needs and wishes. There " "is no central tag repository across clients.") target = fields.Selection([('current', 'Current Window'), ('new', 'New Window'), ('fullscreen', 'Full Screen'), ('main', 'Main action of Current Window')], default="current", string='Target Window') res_model = fields.Char( string='Destination Model', help="Optional model, mostly used for needactions.") context = fields.Char( string='Context Value', default="{}", required=True, help= "Context dictionary as Python expression, empty by default (Default: {})" ) params = fields.Binary(compute='_compute_params', inverse='_inverse_params', string='Supplementary arguments', help="Arguments sent to the client along with " "the view tag") params_store = fields.Binary(string='Params storage', readonly=True) @api.depends('params_store') def _compute_params(self): self_bin = self.with_context(bin_size=False, bin_size_params_store=False) for record, record_bin in pycompat.izip(self, self_bin): record.params = record_bin.params_store and safe_eval( record_bin.params_store, {'uid': self._uid}) def _inverse_params(self): for record in self: params = record.params record.params_store = repr(params) if isinstance(params, dict) else params def _get_default_form_view(self): doc = super(IrActionsActClient, self)._get_default_form_view() params = doc.find(".//field[@name='params']") params.getparent().remove(params) params_store = doc.find(".//field[@name='params_store']") params_store.getparent().remove(params_store) return doc
class ThemeAttachment(models.Model): _name = 'theme.ir.attachment' _description = 'Theme Attachments' name = fields.Char(required=True) key = fields.Char(required=True) url = fields.Char() copy_ids = fields.One2many('ir.attachment', 'theme_template_id', 'Attachment using a copy of me', copy=False, readonly=True) # TODO in master: add missing field: datas_fname @api.multi def _convert_to_base_model(self, website, **kwargs): self.ensure_one() new_attach = { 'key': self.key, 'public': True, 'res_model': 'ir.ui.view', 'type': 'url', 'name': self.name, 'url': self.url, 'website_id': website.id, 'theme_template_id': self.id, } return new_attach
class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' @api.model def get_uri(self): return "%s/auth_oauth/signin" % ( self.env['ir.config_parameter'].get_param('web.base.url')) auth_oauth_google_enabled = fields.Boolean( string='Allow users to sign in with Google') auth_oauth_google_client_id = fields.Char(string='Client ID') server_uri_google = fields.Char(string='Server uri') @api.model def get_values(self): res = super(ResConfigSettings, self).get_values() google_provider = self.env.ref('auth_oauth.provider_google', False) google_provider and res.update( auth_oauth_google_enabled=google_provider.enabled, auth_oauth_google_client_id=google_provider.client_id, server_uri_google=self.get_uri(), ) return res def set_values(self): super(ResConfigSettings, self).set_values() google_provider = self.env.ref('auth_oauth.provider_google', False) google_provider and google_provider.write( { 'enabled': self.auth_oauth_google_enabled, 'client_id': self.auth_oauth_google_client_id, })
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 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 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 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 RestaurantFloor(models.Model): _name = 'restaurant.floor' _description = '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 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 ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' plafond_secu = fields.Float(related='company_id.plafond_secu', string="Plafond de la Securite Sociale", readonly=False) nombre_employes = fields.Integer(related='company_id.nombre_employes', string="Nombre d'employes", readonly=False) cotisation_prevoyance = fields.Float(related='company_id.cotisation_prevoyance', string='Cotisation Patronale Prevoyance', readonly=False) org_ss = fields.Char(related='company_id.org_ss', string="Organisme de securite sociale", readonly=False) conv_coll = fields.Char(related='company_id.conv_coll', string="Convention collective", readonly=False)
class ResPartnerIndustry(models.Model): _description = 'Industry' _name = "res.partner.industry" _order = "name" name = fields.Char('Name', translate=True) full_name = fields.Char('Full Name', translate=True) active = fields.Boolean('Active', default=True)
class ResCompany(models.Model): _inherit = 'res.company' pad_server = fields.Char( help="Etherpad lite server. Example: beta.primarypad.com") pad_key = fields.Char('Pad Api Key', help="Etherpad lite api key.", groups="base.group_system")
class ResCompany(models.Model): _inherit = 'res.company' siret = fields.Char(related='partner_id.siret', string='SIRET', size=14, readonly=False) ape = fields.Char(string='APE')
class View(models.Model): _name = "report.layout" _description = 'Report Layout' view_id = fields.Many2one('ir.ui.view', 'Document Template', required=True) image = fields.Char(string="Preview image src") pdf = fields.Char(string="Preview pdf src")
class BaseLanguageImport(models.TransientModel): _name = "base.language.import" _description = "Language Import" name = fields.Char('Language Name', required=True) code = fields.Char('ISO Code', size=6, required=True, help="ISO Language and Country code, e.g. en_US") data = fields.Binary('File', required=True) filename = fields.Char('File Name', required=True) overwrite = fields.Boolean( 'Overwrite Existing Terms', help= "If you enable this option, existing translations (including custom ones) " "will be overwritten and replaced by those in this file") @api.multi def import_lang(self): this = self[0] this = this.with_context(overwrite=this.overwrite) self.env['res.lang'].load_lang(lang=self.code, lang_name=self.name) with TemporaryFile('wb+') as buf: try: buf.write(base64.decodestring(this.data)) # now we determine the file format buf.seek(0) fileformat = os.path.splitext(this.filename)[-1][1:].lower() tools.trans_load_data(this._cr, buf, fileformat, this.code, lang_name=this.name, context=this._context) except ProgrammingError as e: _logger.exception( 'File unsuccessfully imported, due to a malformed file.') with closing(sql_db.db_connect( self._cr.dbname).cursor()) as cr: raise UserError( _('File not imported due to a malformed file.\n\n' + 'This issue can be caused by duplicates entries who are referring to the same field. ' + 'Please check the content of the file you are trying to import.\n\n' + 'Technical Details:\n%s') % tools.ustr(e)) except Exception as e: _logger.exception( 'File unsuccessfully imported, due to format mismatch or a malformed file.' ) raise UserError( _('File not imported due to format mismatch or a malformed file. (Valid formats are .csv, .po, .pot)\n\n' + 'Technical Details:\n%s') % tools.ustr(e)) return True
class MassMailTest(models.Model): """ A very simple model only inheriting from mail.thread to test pure mass mailing features and base performances. """ _description = 'Simple Mass Mailing Model' _name = 'mass.mail.test' _inherit = ['mail.thread'] name = fields.Char() email_from = fields.Char()
class MailTestSimple(models.Model): """ A very simple model only inheriting from mail.thread when only communication history is necessary. """ _description = 'Simple Chatter Model' _name = 'mail.test.simple' _inherit = ['mail.thread'] name = fields.Char() email_from = fields.Char()
class Lead(models.Model): _inherit = 'crm.lead' reveal_ip = fields.Char(string='IP Address') reveal_iap_credits = fields.Integer(string='IAP Credits') reveal_rule_id = fields.Many2one('crm.reveal.rule', string='Lead Generation Rule', index=True) reveal_id = fields.Char(string='Reveal ID', index=True)
class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' pad_server = fields.Char(related='company_id.pad_server', string="Pad Server *", readonly=False) pad_key = fields.Char(related='company_id.pad_key', string="Pad Api Key *", readonly=False)
class HrContractAdvandageTemplate(models.Model): _name = 'hr.contract.advantage.template' _description = "Employee's Advantage on Contract" name = fields.Char('Name', required=True) code = fields.Char('Code', required=True) lower_bound = fields.Float('Lower Bound', help="Lower bound authorized by the employer for this advantage") upper_bound = fields.Float('Upper Bound', help="Upper bound authorized by the employer for this advantage") default_value = fields.Float('Default value for this advantage')
class HrRuleInput(models.Model): _name = 'hr.rule.input' _description = 'Salary Rule Input' name = fields.Char(string='Description', required=True) code = fields.Char(required=True, help="The code that can be used in the salary rules") input_id = fields.Many2one('hr.salary.rule', string='Salary Rule Input', required=True)
class Attachment(models.Model): _inherit = "ir.attachment" # related for backward compatibility with saas-6 website_url = fields.Char(string="Website URL", related='local_url', deprecated=True, readonly=False) key = fields.Char( help= 'Technical field used to resolve multiple attachments in a multi-website environment.' ) website_id = fields.Many2one('website') @api.model def create(self, vals): website = self.env['website'].get_current_website(fallback=False) if website and 'website_id' not in vals and 'not_force_website_id' not in self.env.context: vals['website_id'] = website.id return super(Attachment, self).create(vals) @api.model def get_serving_groups(self): return super(Attachment, self).get_serving_groups() + [ 'website.group_website_designer' ] @api.model def get_serve_attachment(self, url, extra_domain=None, extra_fields=None, order=None): website = self.env['website'].get_current_website() extra_domain = (extra_domain or []) + website.website_domain() order = ('website_id, %s' % order) if order else 'website_id' return super(Attachment, self).get_serve_attachment(url, extra_domain, extra_fields, order) @api.model def get_attachment_by_key(self, key, extra_domain=None, order=None): website = self.env['website'].get_current_website() extra_domain = (extra_domain or []) + website.website_domain() order = ('website_id, %s' % order) if order else 'website_id' return super(Attachment, self).get_attachment_by_key(key, extra_domain, order) def init(self): res = super(Attachment, self).init() # ir_http._xmlid_to_obj is using this index for multi-website tools.create_index(self._cr, 'ir_attachment_key_website_idx', self._table, ['key', 'website_id']) return res
class ResCompany(models.Model): _inherit = 'res.company' plafond_secu = fields.Float(string='Plafond de la Securite Sociale', digits=dp.get_precision('Payroll')) nombre_employes = fields.Integer(string='Nombre d\'employes') cotisation_prevoyance = fields.Float( string='Cotisation Patronale Prevoyance', digits=dp.get_precision('Payroll')) org_ss = fields.Char(string='Organisme de securite sociale') conv_coll = fields.Char(string='Convention collective')
class IrExports(models.Model): _name = "ir.exports" _description = '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 ProjectTaskType(models.Model): _name = 'project.task.type' _description = 'Task Stage' _order = 'sequence, id' def _get_default_project_ids(self): default_project_id = self.env.context.get('default_project_id') return [default_project_id] if default_project_id else None name = fields.Char(string='Stage Name', required=True, translate=True) description = fields.Text(translate=True) sequence = fields.Integer(default=1) project_ids = fields.Many2many('project.project', 'project_task_type_rel', 'type_id', 'project_id', string='Projects', default=_get_default_project_ids) legend_priority = fields.Char( string='Starred Explanation', translate=True, help='Explanation text to help users using the star on tasks or issues in this stage.') legend_blocked = fields.Char( 'Red Kanban Label', default=lambda s: _('Blocked'), translate=True, required=True, help='Override the default value displayed for the blocked state for kanban selection, when the task or issue is in that stage.') legend_done = fields.Char( 'Green Kanban Label', default=lambda s: _('Ready for Next Stage'), translate=True, required=True, help='Override the default value displayed for the done state for kanban selection, when the task or issue is in that stage.') legend_normal = fields.Char( 'Grey Kanban Label', default=lambda s: _('In Progress'), translate=True, required=True, help='Override the default value displayed for the normal state for kanban selection, when the task or issue is in that stage.') mail_template_id = fields.Many2one( 'mail.template', string='Email Template', domain=[('model', '=', 'project.task')], help="If set an email will be sent to the customer when the task or issue reaches this step.") fold = fields.Boolean(string='Folded in Kanban', help='This stage is folded in the kanban view when there are no records in that stage to display.') rating_template_id = fields.Many2one( 'mail.template', string='Rating Email Template', domain=[('model', '=', 'project.task')], help="If set and if the project's rating configuration is 'Rating when changing stage', then an email will be sent to the customer when the task reaches this step.") auto_validation_kanban_state = fields.Boolean('Automatic kanban status', default=False, help="Automatically modify the kanban state when the customer replies to the feedback for this stage.\n" " * A good feedback from the customer will update the kanban state to 'ready for the new stage' (green bullet).\n" " * A medium or a bad feedback will set the kanban state to 'blocked' (red bullet).\n") @api.multi def unlink(self): stages = self default_project_id = self.env.context.get('default_project_id') if default_project_id: shared_stages = self.filtered(lambda x: len(x.project_ids) > 1 and default_project_id in x.project_ids.ids) tasks = self.env['project.task'].with_context(active_test=False).search([('project_id', '=', default_project_id), ('stage_id', 'in', self.ids)]) if shared_stages and not tasks: shared_stages.write({'project_ids': [(3, default_project_id)]}) stages = self.filtered(lambda x: x not in shared_stages) return super(ProjectTaskType, stages).unlink()
class IndustryTag(models.Model): """ Industry Tags of Acquisition Rules """ _name = 'crm.reveal.industry' _description = 'Industry Tag' name = fields.Char(string='Tag Name', required=True, translate=True) reveal_id = fields.Char(required=True) color = fields.Integer(string='Color Index') _sql_constraints = [ ('name_uniq', 'unique (name)', 'Tag name already exists!'), ]
class ResBank(models.Model): _inherit = 'res.bank' l10n_ch_postal_chf = fields.Char( string='CHF ISR reference', help= 'The postal reference of the bank, used to generate ISR payment slips in CHF.' ) l10n_ch_postal_eur = fields.Char( string='EUR ISR reference', help= 'The postal reference of the bank, used to generate ISR payment slips in EUR.' )