class KnowledgeConfigSettings(models.TransientModel): """This class in needed to activate document management.""" _name = 'knowledge.config.settings' _inherit = 'res.config.settings' module_document = fields.Boolean( 'Manage documents', help='Document indexation, full text search of attachements.\n' '- This installs the module document.') module_document_page = fields.Boolean( 'Manage document pages (Wiki)', help='Provide document page and category as a wiki.\n' '- This installs the module document_page.') module_document_page_approval = fields.Boolean( 'Manage documents approval', help='Add workflow on documents per category.\n' '- This installs the module document_page_approval.') module_cmis_read = fields.Boolean( 'Attach files from an external DMS into eCore', help='Connect eCore with a CMIS compatible server to attach files\n' 'to an eCore record.\n' '- This installs the module cmis_read.') module_cmis_write = fields.Boolean( 'Store attachments in an external DMS instead of the eCore Filestore', help='Connect eCore with a CMIS compatible server to store files.\n' '- This installs the module cmis_write.')
class AccountAssetCategory(models.Model): _name = 'account.asset.category' _description = 'Asset category' active = fields.Boolean(default=True) name = fields.Char(required=True, index=True, string="Asset Type") account_analytic_id = fields.Many2one('account.analytic.account', string='Analytic Account') account_asset_id = fields.Many2one('account.account', string='Asset Account', required=True, domain=[('internal_type','=','other'), ('deprecated', '=', False)]) account_income_recognition_id = fields.Many2one('account.account', string='Recognition Income Account', domain=[('internal_type','=','other'), ('deprecated', '=', False)], oldname='account_expense_depreciation_id') account_depreciation_id = fields.Many2one('account.account', string='Depreciation Account', required=True, domain=[('internal_type','=','other'), ('deprecated', '=', False)]) journal_id = fields.Many2one('account.journal', string='Journal', required=True) company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env['res.company']._company_default_get('account.asset.category')) method = fields.Selection([('linear', 'Linear'), ('degressive', 'Degressive')], string='Computation Method', required=True, default='linear', help="Choose the method to use to compute the amount of depreciation lines.\n" " * Linear: Calculated on basis of: Gross Value / Number of Depreciations\n" " * Degressive: Calculated on basis of: Residual Value * Degressive Factor") method_number = fields.Integer(string='Number of Depreciations', default=5, help="The number of depreciations needed to depreciate your asset") method_period = fields.Integer(string='Period Length', default=1, help="State here the time between 2 depreciations, in months", required=True) method_progress_factor = fields.Float('Degressive Factor', default=0.3) method_time = fields.Selection([('number', 'Number of Depreciations'), ('end', 'Ending Date')], string='Time Method', required=True, default='number', help="Choose the method to use to compute the dates and number of depreciation lines.\n" " * Number of Depreciations: Fix the number of depreciation lines and the time between 2 depreciations.\n" " * Ending Date: Choose the time between 2 depreciations and the date the depreciations won't go beyond.") method_end = fields.Date('Ending date') prorata = fields.Boolean(string='Prorata Temporis', help='Indicates that the first depreciation entry for this asset have to be done from the purchase date instead of the first of January') open_asset = fields.Boolean(string='Post Journal Entries', help="Check this if you want to automatically confirm the assets of this category when created by invoices.") type = fields.Selection([('sale', 'Sale: Revenue Recognition'), ('purchase', 'Purchase: Asset')], required=True, index=True, default='purchase') @api.onchange('type') def onchange_type(self): if self.type == 'sale': self.prorata = True self.method_period = 1 else: self.method_period = 12
class HrEquipmentStage(models.Model): """ Model for case stages. This models the main stages of a Maintenance Request management flow. """ _name = 'hr.equipment.stage' _description = 'Maintenance Stage' _order = 'sequence, id' name = fields.Char('Name', required=True, translate=True) sequence = fields.Integer('Sequence', default=20) fold = fields.Boolean('Folded in Recruitment Pipe') done = fields.Boolean('Request Done')
class MailMessageSubtype(models.Model): """ Class holding subtype definition for messages. Subtypes allow to tune the follower subscription, allowing only some subtypes to be pushed on the Wall. """ _name = 'mail.message.subtype' _description = 'Message subtypes' _order = 'sequence, id' name = fields.Char( 'Message Type', required=True, translate=True, help='Message subtype gives a more precise type on the message, ' 'especially for system notifications. For example, it can be ' 'a notification related to a new record (New), or to a stage ' 'change in a process (Stage change). Message subtypes allow to ' 'precisely tune the notifications the user want to receive on its wall.' ) description = fields.Text( 'Description', translate=True, help='Description that will be added in the message posted for this ' 'subtype. If void, the name will be added instead.') internal = fields.Boolean( 'Internal Only', help= 'Messages with internal subtypes will be visible only by employees, aka members of base_user group' ) parent_id = fields.Many2one( 'mail.message.subtype', string='Parent', ondelete='set null', help= 'Parent subtype, used for automatic subscription. This field is not ' 'correctly named. For example on a project, the parent_id of project ' 'subtypes refers to task-related subtypes.') relation_field = fields.Char( 'Relation field', help='Field used to link the related model to the subtype model when ' 'using automatic subscription on a related document. The field ' 'is used to compute getattr(related_document.relation_field).') res_model = fields.Char( 'Model', help= "Model the subtype applies to. If False, this subtype applies to all models." ) default = fields.Boolean('Default', default=True, help="Activated by default when subscribing.") sequence = fields.Integer('Sequence', default=1, help="Used to order subtypes.") hidden = fields.Boolean('Hidden', help="Hide the subtype in the follower options")
class ChannelPartner(models.Model): _name = 'mail.channel.partner' _description = 'Last Seen Many2many' _table = 'mail_channel_partner' _rec_name = 'partner_id' partner_id = fields.Many2one('res.partner', string='Recipient', ondelete='cascade') channel_id = fields.Many2one('mail.channel', string='Channel', ondelete='cascade') seen_message_id = fields.Many2one('mail.message', string='Last Seen') fold_state = fields.Selection([('open', 'Open'), ('folded', 'Folded'), ('closed', 'Closed')], string='Conversation Fold State', default='open') is_minimized = fields.Boolean("Conversation is minimied") is_pinned = fields.Boolean("Is pinned on the interface", default=True)
class ResUsers(models.Model): _inherit = 'res.users' technical_features = fields.Boolean( compute='get_technical_features', inverse='set_technical_features') show_technical_features = fields.Boolean( string='Show field Technical Features', compute='get_show_technical_features', help=('Whether to display the technical features field in the user ' 'preferences.')) @api.multi @api.depends('groups_id') def get_show_technical_features(self): """ Only display the technical features checkbox in the user preferences if the user has access to them """ users = self.env.ref('base.group_no_one').users for user in self: user.show_technical_features = user in users @api.multi @api.depends('groups_id') def get_technical_features(self): """ Map user membership to boolean field value """ users = self.env.ref( 'base_technical_features.group_technical_features').users for user in self: user.technical_features = user in users @api.multi def set_technical_features(self): """ Map boolean field value to group membership, but checking access """ group = self.env.ref( 'base_technical_features.group_technical_features') for user in self: if self.env.ref('base.group_no_one') not in user.groups_id: raise AccessError( _('The user does not have access to technical ' 'features.')) if user.technical_features: self.sudo().write({'groups_id': [(4, group.id)]}) else: self.sudo().write({'groups_id': [(3, group.id)]}) def __init__(self, pool, cr): super(ResUsers, self).__init__(pool, cr) self.SELF_READABLE_FIELDS += [ 'technical_features', 'show_technical_features'] self.SELF_WRITEABLE_FIELDS.append('technical_features')
class website_config_settings(models.TransientModel): _inherit = 'website.config.settings' salesperson_id = fields.Many2one('res.users', related='website_id.salesperson_id', string='Salesperson') salesteam_id = fields.Many2one('crm.team', related='website_id.salesteam_id', string='Sales Team') module_delivery_dhl = fields.Boolean("DHL integration") module_delivery_fedex = fields.Boolean("Fedex integration") module_delivery_ups = fields.Boolean("UPS integration") module_delivery_usps = fields.Boolean("USPS integration") module_sale_ebay = fields.Boolean("eBay connector")
class AccountTaxCashBasis(models.Model): _inherit = 'account.tax' use_cash_basis = fields.Boolean('Use Cash Basis', help='Select this if the tax should use cash basis, which will \ create an entry for this tax on a given account during reconciliation') cash_basis_account = fields.Many2one('account.account', string='Tax Received Account', domain=[('deprecated', '=', False)], help='Account use when \ creating entry for tax cash basis')
class EventMailRegistration(models.Model): _name = 'event.mail.registration' _description = 'Registration Mail Scheduler' _rec_name = 'scheduler_id' _order = 'scheduled_date DESC' scheduler_id = fields.Many2one('event.mail', 'Mail Scheduler', required=True, ondelete='cascade') registration_id = fields.Many2one('event.registration', 'Attendee', required=True, ondelete='cascade') scheduled_date = fields.Datetime('Scheduled Time', compute='_compute_scheduled_date', store=True) mail_sent = fields.Boolean('Mail Sent') @api.one def execute(self): if self.registration_id.state in ['open', 'done'] and not self.mail_sent: self.scheduler_id.template_id.send_mail(self.registration_id.id) self.write({'mail_sent': True}) @api.one @api.depends('registration_id', 'scheduler_id.interval_unit', 'scheduler_id.interval_type') def _compute_scheduled_date(self): if self.registration_id: date_open = self.registration_id.date_open date_open_datetime = date_open and datetime.strptime(date_open, tools.DEFAULT_SERVER_DATETIME_FORMAT) or fields.datetime.now() self.scheduled_date = date_open_datetime + _INTERVALS[self.scheduler_id.interval_unit](self.scheduler_id.interval_nbr) else: self.scheduled_date = False
class lunch_order_line(models.TransientModel): _name = 'lunch.order.line.lucky' def _default_supplier(self): suppliers_obj = self.env['lunch.product'].search([]).mapped("supplier") return [(4, supplier.id) for supplier in suppliers_obj] product_id = fields.Many2one('lunch.product', 'Product', store=True) supplier_ids = fields.Many2many(comodel_name='res.partner', string='Vendor', domain=lambda self: [("id", "in", self.env['lunch.product'].search([]).mapped("supplier").ids)]) is_max_budget = fields.Boolean("I'm not feeling rich", help="Enable this option to set a maximal budget for your lucky order.", store=True) max_budget = fields.Float('Max Budget', store=True) @api.multi def random_pick(self): """ To pick a random product from the selected suppliers, and create an order with this one """ self.ensure_one() if self.is_max_budget: products_obj = self.env['lunch.product'].search([('supplier', "in", self.supplier_ids.ids), ('price', '<=', self.max_budget)]) else: products_obj = self.env['lunch.product'].search([('supplier', "in", self.supplier_ids.ids)]) if len(products_obj) != 0: random_product_obj = self.env['lunch.product'].browse([random.choice(products_obj.ids)]) order_line = self.env['lunch.order.line'].create({ 'product_id': random_product_obj.id, 'order_id': self._context['active_id'] }) else: raise UserError(_('No product is matching your request. Now you will starve to death.'))
class AccountReportGeneralLedger(models.TransientModel): _inherit = "account.common.account.report" _name = "account.report.general.ledger" _description = "General Ledger Report" initial_balance = fields.Boolean( string='Include Initial Balances', help= 'If you selected date, this field allow you to add a row to display the amount of debit/credit/balance that precedes the filter you\'ve set.' ) sortby = fields.Selection([('sort_date', 'Date'), ('sort_journal_partner', 'Journal & Partner')], string='Sort by', required=True, default='sort_date') journal_ids = fields.Many2many('account.journal', 'account_report_general_ledger_journal_rel', 'account_id', 'journal_id', string='Journals', required=True) def _print_report(self, data): data = self.pre_print_report(data) data['form'].update(self.read(['initial_balance', 'sortby'])[0]) if data['form'].get( 'initial_balance') and not data['form'].get('date_from'): raise UserError(_("You must define a Start Date")) return self.env['report'].with_context(landscape=True).get_action( self, 'account.report_generalledger', data=data)
class RecruitmentStage(models.Model): _name = "hr.recruitment.stage" _description = "Stage of Recruitment" _order = 'sequence' name = fields.Char("Stage name", required=True, translate=True) sequence = fields.Integer( "Sequence", default=1, help="Gives the sequence order when displaying a list of stages.") job_ids = fields.Many2many( 'hr.job', 'job_stage_rel', 'stage_id', 'job_id', string='Job Stages', default=lambda self: [(4, self._context['default_job_id'])] if self._context.get('default_job_id') else None) requirements = fields.Text("Requirements") template_id = fields.Many2one( 'mail.template', "Use template", 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." )
class Invite(models.TransientModel): """ Wizard to invite partners (or channels) and make them followers. """ _name = 'mail.wizard.invite' _description = 'Invite wizard' @api.model def default_get(self, fields): result = super(Invite, self).default_get(fields) user_name = self.env.user.name_get()[0][1] model = result.get('res_model') res_id = result.get('res_id') if self._context.get('mail_invite_follower_channel_only'): result['send_mail'] = False if 'message' in fields and model and res_id: model_name = self.env['ir.model'].search([('model', '=', self.pool[model]._name)]).name_get()[0][1] document_name = self.env[model].browse(res_id).name_get()[0][1] message = _('<div><p>Hello,</p><p>%s invited you to follow %s document: %s.</p></div>') % (user_name, model_name, document_name) result['message'] = message elif 'message' in fields: result['message'] = _('<div><p>Hello,</p><p>%s invited you to follow a new document.</p></div>') % user_name return result res_model = fields.Char('Related Document Model', required=True, select=1, help='Model of the followed resource') res_id = fields.Integer('Related Document ID', select=1, help='Id of the followed resource') partner_ids = fields.Many2many('res.partner', string='Recipients', help="List of partners that will be added as follower of the current document.") channel_ids = fields.Many2many('mail.channel', string='Channels', help='List of channels that will be added as listeners of the current document.', domain=[('channel_type', '=', 'channel')]) message = fields.Html('Message') send_mail = fields.Boolean('Send Email', default=True, help="If checked, the partners will receive an email warning they have been added in the document's followers.") @api.multi def add_followers(self): email_from = self.env['mail.message']._get_default_from() for wizard in self: Model = self.env[wizard.res_model] document = Model.browse(wizard.res_id) # filter partner_ids to get the new followers, to avoid sending email to already following partners new_partners = wizard.partner_ids - document.message_partner_ids new_channels = wizard.channel_ids - document.message_channel_ids document.message_subscribe(new_partners.ids, new_channels.ids) model_ids = self.env['ir.model'].search([('model', '=', wizard.res_model)]) model_name = model_ids.name_get()[0][1] # send an email if option checked and if a message exists (do not send void emails) if wizard.send_mail and wizard.message and not wizard.message == '<br>': # when deleting the message, cleditor keeps a <br> message = self.env['mail.message'].create({ 'subject': _('Invitation to follow %s: %s') % (model_name, document.name_get()[0][1]), 'body': wizard.message, 'record_name': document.name_get()[0][1], 'email_from': email_from, 'reply_to': email_from, 'model': wizard.res_model, 'res_id': wizard.res_id, 'no_auto_thread': True, }) new_partners.with_context(auto_delete=True)._notify(message, force_send=True, user_signature=True) message.unlink() return {'type': 'ir.actions.act_window_close'}
class Rating(models.Model): _inherit = 'rating.rating' # Add this related field to mail.message for performance reason # This field may one day be deplaced to another module (like 'website_rating') if it is required for # another usage not related to website_sale. website_published = fields.Boolean(related='message_id.website_published', store=True)
class SaasClient(models.AbstractModel): _name = 'saas_base.client' users_len = fields.Integer('Count users', readonly=True) max_users = fields.Char('Max users allowed', readonly=True) file_storage = fields.Integer('File storage (MB)', readonly=True) db_storage = fields.Integer('DB storage (MB)', readonly=True) total_storage_limit = fields.Integer('Total storage limit (MB)', readonly=True, default=0) expiration_datetime = fields.Datetime('Expiration', track_visibility='onchange') trial = fields.Boolean('Trial', help='indication of trial clients', default=False, readonly=True)
class ResPartnerIDtype(models.Model): _name = 'res.partner.idtype' _description = 'Identificacion Tipo de Documento' _order = 'sequence' name = fields.Char(required=True) code = fields.Char(required=True) sequence = fields.Integer() active = fields.Boolean(default=True) note = fields.Text() on_company = fields.Boolean(string=u'On Company?', default=True, help="Id type for use on Company") on_contact = fields.Boolean(string=u'On Contact?', default=True, help="Id type for use on Contacts") on_merchant = fields.Boolean(string=u'On Merchants?', default=True, help="Id type for use on Merchants")
class HrEquipmentCategory(models.Model): _name = 'hr.equipment.category' _inherits = {"mail.alias": "alias_id"} _inherit = ['mail.thread'] _description = 'Asset Category' @api.one @api.depends('equipment_ids') def _compute_fold(self): self.fold = False if self.equipment_count else True name = fields.Char('Category Name', required=True, translate=True) user_id = fields.Many2one('res.users', 'Responsible', track_visibility='onchange', default=lambda self: self.env.uid) color = fields.Integer('Color Index') note = fields.Text('Comments', translate=True) equipment_ids = fields.One2many('hr.equipment', 'category_id', string='Equipments', copy=False) equipment_count = fields.Integer(string="Equipment", compute='_compute_equipment_count') maintenance_ids = fields.One2many('hr.equipment.request', 'category_id', copy=False) maintenance_count = fields.Integer(string="Maintenance", compute='_compute_maintenance_count') alias_id = fields.Many2one( 'mail.alias', 'Alias', ondelete='cascade', required=True, help="Email alias for this equipment category. New emails will automatically " "create new maintenance request for this equipment category.") fold = fields.Boolean(string='Folded in Maintenance Pipe', compute='_compute_fold', store=True) @api.multi def _compute_equipment_count(self): equipment_data = self.env['hr.equipment'].read_group([('category_id', 'in', self.ids)], ['category_id'], ['category_id']) mapped_data = dict([(m['category_id'][0], m['category_id_count']) for m in equipment_data]) for category in self: category.equipment_count = mapped_data.get(category.id, 0) @api.multi def _compute_maintenance_count(self): maintenance_data = self.env['hr.equipment.request'].read_group([('category_id', 'in', self.ids)], ['category_id'], ['category_id']) mapped_data = dict([(m['category_id'][0], m['category_id_count']) for m in maintenance_data]) for category in self: category.maintenance_count = mapped_data.get(category.id, 0) @api.model def create(self, vals): self = self.with_context(alias_model_name='hr.equipment.request', alias_parent_model_name=self._name) category_id = super(HrEquipmentCategory, self).create(vals) category_id.alias_id.write({'alias_parent_thread_id': category_id.id, 'alias_defaults': {'category_id': category_id.id}}) return category_id @api.multi def unlink(self): for category in self: if category.equipment_ids or category.maintenance_ids: raise UserError(_("You cannot delete an equipment category containing equipments or maintenance requests.")) res = super(HrEquipmentCategory, self).unlink() return res
class DateRangeType(models.Model): _name = "date.range.type" @api.model def _default_company(self): return self.env['res.company']._company_default_get('date.range') name = fields.Char(required=True, translate=True) allow_overlap = fields.Boolean( help="If sets date range of same type must not overlap.", default=False) active = fields.Boolean( help="The active field allows you to hide the date range without " "removing it.", default=True) company_id = fields.Many2one( comodel_name='res.company', string='Company', select=1, default=_default_company) _sql_constraints = [ ('date_range_type_uniq', 'unique (name,company_id)', 'A date range type must be unique per company !')]
class SaasPortalCreateClient(models.TransientModel): _name = 'saas_portal.create_client' def _default_plan_id(self): return self._context.get('active_id') def _default_name(self): plan_id = self._default_plan_id() if plan_id: plan = self.env['saas_portal.plan'].browse(plan_id) return plan.generate_dbname(raise_error=False)[0] return '' name = fields.Char('Database name', required=True, default=_default_name) plan_id = fields.Many2one('saas_portal.plan', string='Plan', readonly=True, default=_default_plan_id) partner_id = fields.Many2one('res.partner', string='Partner') user_id = fields.Many2one('res.users', string='User') notify_user = fields.Boolean( help='Notify user by email when database will have been created', default=False) support_team_id = fields.Many2one( 'saas_portal.support_team', 'Support Team', default=lambda self: self.env.user.support_team_id) @api.onchange('user_id') def update_parter(self): if self.user_id: self.partner_id = self.user_id.partner_id @api.multi def apply(self): wizard = self[0] res = wizard.plan_id.create_new_database( dbname=wizard.name, partner_id=wizard.partner_id.id, user_id=self.user_id.id, notify_user=self.notify_user, support_team_id=self.support_team_id.id) client = self.env['saas_portal.client'].browse(res.get('id')) client.server_id.action_sync_server() return { 'type': 'ir.actions.act_window', 'view_type': 'form', 'view_mode': 'form', 'res_model': 'saas_portal.client', 'res_id': client.id, 'target': 'current', }
class HtmlFormFieldType(models.Model): _name = "html.form.field.type" _description = "HTML Form Field Type" name = fields.Char(string="Name") html_type = fields.Char(string="HTML Type", help="Internal Reference to this HTML type") data_type = fields.Char(string="Data Type", help="The eCore data type(ttype)") default = fields.Boolean( string="Default", help="Is this the default HTML type for this datatype?")
class AccountingAssertTest(models.Model): _name = "accounting.assert.test" _order = "sequence" name = fields.Char(string='Test Name', required=True, index=True, translate=True) desc = fields.Text(string='Test Description', index=True, translate=True) code_exec = fields.Text(string='Python code', required=True, default=CODE_EXEC_DEFAULT) active = fields.Boolean(default=True) sequence = fields.Integer(default=10)
class account_register_payments(models.TransientModel): _inherit = "account.register.payments" check_amount_in_words = fields.Char(string="Amount in Words") check_manual_sequencing = fields.Boolean( related='journal_id.check_manual_sequencing') # Note: a check_number == 0 means that it will be attributed when the check is printed check_number = fields.Integer( string="Check Number", readonly=True, copy=False, default=0, help= "Number of the check corresponding to this payment. If your pre-printed check are not already numbered, " "you can manage the numbering in the journal configuration page.") @api.onchange('journal_id') def _onchange_journal_id(self): if hasattr(super(account_register_payments, self), '_onchange_journal_id'): super(account_register_payments, self)._onchange_journal_id() if self.journal_id.check_manual_sequencing: self.check_number = self.journal_id.check_sequence_id.number_next_actual @api.onchange('amount') def _onchange_amount(self): if hasattr(super(account_register_payments, self), '_onchange_amount'): super(account_register_payments, self)._onchange_amount() # TODO: merge, refactor and complete the amount_to_text and amount_to_text_en classes check_amount_in_words = amount_to_text_en.amount_to_text(math.floor( self.amount), lang='en', currency='') check_amount_in_words = check_amount_in_words.replace( ' and Zero Cent', '') # Ugh decimals = self.amount % 1 if decimals >= 10**-2: check_amount_in_words += _(' and %s/100') % str( int(round(float_round(decimals * 100, precision_rounding=1)))) self.check_amount_in_words = check_amount_in_words def get_payment_vals(self): res = super(account_register_payments, self).get_payment_vals() if self.payment_method_id == self.env.ref( 'account_check_printing.account_payment_method_check'): res.update({ 'check_amount_in_words': self.check_amount_in_words, 'check_manual_sequencing': self.check_manual_sequencing, }) return res
class website_form_model_fields(models.Model): """ fields configuration for form builder """ _name = 'ir.model.fields' _inherit = 'ir.model.fields' def init(self, cr): # set all existing unset website_form_blacklisted fields to ``true`` # (so that we can use it as a whitelist rather than a blacklist) cr.execute('UPDATE ir_model_fields' ' SET website_form_blacklisted=true' ' WHERE website_form_blacklisted IS NULL') # add an SQL-level default value on website_form_blacklisted to that # pure-SQL ir.model.field creations (e.g. in _field_create) generate # the right default value for a whitelist (aka fields should be # blacklisted by default) cr.execute('ALTER TABLE ir_model_fields ' ' ALTER COLUMN website_form_blacklisted SET DEFAULT true') @api.model def formbuilder_whitelist(self, model, fields): """ :param str model: name of the model on which to whitelist fields :param list(str) fields: list of fields to whitelist on the model :return: nothing of import """ # postgres does *not* like ``in [EMPTY TUPLE]`` queries if not fields: return False # only allow users who can change the website structure if not self.env['res.users'].has_group('base.group_website_designer'): return False # the ORM only allows writing on custom fields and will trigger a # registry reload once that's happened. We want to be able to # whitelist non-custom fields and the registry reload absolutely # isn't desirable, so go with a method and raw SQL self.env.cr.execute( "UPDATE ir_model_fields" " SET website_form_blacklisted=false" " WHERE model=%s AND name in %s", (model, tuple(fields))) return True website_form_blacklisted = fields.Boolean( 'Blacklisted in web forms', default=True, select=True, # required=True, help='Blacklist this field for web forms')
class Project(models.Model): _inherit = "project.project" @api.one @api.depends('percentage_satisfaction_task') def _compute_percentage_satisfaction_project(self): self.percentage_satisfaction_project = self.percentage_satisfaction_task @api.one @api.depends('tasks.rating_ids.rating') def _compute_percentage_satisfaction_task(self): activity = self.tasks.rating_get_grades() self.percentage_satisfaction_task = activity['great'] * 100 / sum( activity.values()) if sum(activity.values()) else -1 percentage_satisfaction_task = fields.Integer( compute='_compute_percentage_satisfaction_task', string='% Happy', store=True, default=-1) percentage_satisfaction_project = fields.Integer( compute="_compute_percentage_satisfaction_project", string="% Happy", store=True, default=-1) is_visible_happy_customer = fields.Boolean( string="Customer Satisfaction", default=False, help= "Display informations about rating of the project on kanban and form view. This buttons will only be displayed if at least a rating exists." ) @api.multi def action_view_task_rating(self): """ return the action to see all the rating about the tasks of the project """ action = self.env['ir.actions.act_window'].for_xml_id( 'rating', 'action_view_rating') return dict(action, domain=[('rating', '!=', -1), ('res_id', 'in', self.tasks.ids), ('res_model', '=', 'project.task')]) @api.multi def action_view_all_rating(self): """ return the action to see all the rating about the all sort of activity of the project (tasks, issues, ...) """ return self.action_view_task_rating()
class SaasConfigParam(models.TransientModel): _name = 'saas.config.param' def _get_keys(self): return [ ('saas_client.max_users', 'Max Users'), ('saas_client.suspended', 'Suspended'), ('saas_client.total_storage_limit', 'Total storage limit'), ] key = fields.Selection(selection=_get_keys, string='Key', required=1, size=64) value = fields.Char('Value', required=1, size=64) config_id = fields.Many2one('saas.config', 'Config') hidden = fields.Boolean('Hidden parameter', default=True)
class HtmlFormField(models.Model): _name = "html.form.field" _description = "HTML Form Field" _order = "sequence asc" sequence = fields.Integer(string="Sequence") html_id = fields.Many2one('html.form', ondelete='cascade', string="HTML Form") model_id = fields.Many2one('ir.model', string="Model", readonly=True) model = fields.Char(related="model_id.model", string="Model Name", readonly=True) field_id = fields.Many2one( 'ir.model.fields', domain= "[('name','!=','create_date'),('name','!=','create_uid'),('name','!=','id'),('name','!=','write_date'),('name','!=','write_uid')]", string="Form Field") field_type = fields.Many2one('html.form.field.type', string="Field Type") field_label = fields.Char(string="Field Label") html_name = fields.Char(string="HTML Name") validation_format = fields.Char(string="Validation Format") setting_general_required = fields.Boolean(string="Required") setting_binary_file_type_filter = fields.Selection( [('image', 'Image'), ('audio', 'Audio')], string="File Type Filter") character_limit = fields.Integer(string="Character Limit", default="100") @api.model def create(self, values): sequence = self.env['ir.sequence'].get('sequence') values['sequence'] = sequence return super(HtmlFormField, self).create(values) @api.onchange('field_id') def _onchange_field_id(self): """Set the default field type, html_name and field label""" if self.field_id: self.field_type = self.env['html.form.field.type'].search([ ('data_type', '=', self.field_id.ttype), ('default', '=', True) ])[0].id self.html_name = self.field_id.name self.field_label = self.field_id.field_description
class Bank(models.Model): _description = 'Bank' _name = 'res.bank' _order = 'name' name = fields.Char(required=True) street = fields.Char() street2 = fields.Char() zip = fields.Char() city = fields.Char() state = fields.Many2one('res.country.state', 'Fed. State', domain="[('country_id', '=', country)]") country = fields.Many2one('res.country') email = fields.Char() phone = fields.Char() fax = fields.Char() active = fields.Boolean(default=True) bic = fields.Char('Bank Identifier Code', select=True, help="Sometimes called BIC or Swift.") @api.multi @api.depends('name', 'bic') def name_get(self): result = [] for bank in self: name = bank.name + (bank.bic and (' - ' + bank.bic) or '') result.append((bank.id, name)) return result @api.model def name_search(self, name, args=None, operator='ilike', limit=100): args = args or [] domain = [] if name: domain = [ '|', ('bic', '=ilike', name + '%'), ('name', operator, name) ] if operator in expression.NEGATIVE_TERM_OPERATORS: domain = ['&'] + domain banks = self.search(domain + args, limit=limit) return banks.name_get()
class ProjectTaskType(models.Model): _inherit = 'project.task.type' rating_template_id = fields.Many2one( 'mail.template', string='Rating Email Template', domain=[('model', '=', 'rating.rating')], help= "Select an email template. An email will be sent to the customer when the task reach this step." ) auto_validation_kanban_state = fields.Boolean( 'Auto Kanban state validation', default=False, help= "Automatically modify the kanban state when the customer reply to the feedback for this stage.\n" " * A great 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" )
class hr_employee(models.Model): _inherit = "hr.employee" newly_hired_employee = fields.Boolean( 'Newly hired employee', compute='_compute_newly_hired_employee', search='_search_newly_hired_employee') @api.multi def _compute_newly_hired_employee(self): read_group_result = self.env['hr.applicant'].read_group( [('emp_id', 'in', self.ids), ('job_id.state', '=', 'recruit')], ['emp_id'], ['emp_id']) result = dict((data['emp_id'], data['emp_id_count'] > 0) for data in read_group_result) for record in self: record.newly_hired_employee = result.get(record.id, False) def _search_newly_hired_employee(self, operator, value): applicants = self.env['hr.applicant'].search([('job_id.state', '=', 'recruit')]) return [('id', 'in', applicants.ids)] @api.multi def _broadcast_welcome(self): """ Broadcast the welcome message to all users in the employee company. """ self.ensure_one() IrModelData = self.env['ir.model.data'] channel_all_employees = IrModelData.xmlid_to_object( 'mail.channel_all_employees') template_new_employee = IrModelData.xmlid_to_object( 'hr_recruitment.hr_welcome_new_employee') if template_new_employee: MailTemplate = self.env['mail.template'] body_html = MailTemplate.render_template( template_new_employee.body_html, 'hr.employee', self.id) subject = MailTemplate.render_template( template_new_employee.subject, 'hr.employee', self.id) channel_all_employees.message_post(body=body_html, subject=subject, subtype='mail.mt_comment') return True
class SaasTagClient(models.TransientModel): _name = 'saas_portal.modify_backup' @api.model def _default_backup_strategy(self): client = self.env['saas_portal.client'].browse( self.env.context['active_id']) return client.backup backup = fields.Boolean('Backup on Modify', help="Backs up first before deleting or upgrading", default=_default_backup_strategy) @api.multi def apply(self): self.ensure_one() client = self.env['saas_portal.client'].browse( self.env.context['active_id']) client.write({'backup': self.backup}) return True