class res_company(models.Model): _inherit = "res.company" gengo_private_key = fields.Text(string="Gengo Private Key", copy=False, groups="base.group_system") gengo_public_key = fields.Text(string="Gengo Public Key", copy=False, groups="base.group_user") gengo_comment = fields.Text( string="Comments", groups="base.group_user", help= "This comment will be automatically be enclosed in each an every request sent to Gengo" ) gengo_auto_approve = fields.Boolean( string="Auto Approve Translation ?", groups="base.group_user", default=True, help="Jobs are Automatically Approved by Gengo.") gengo_sandbox = fields.Boolean( string="Sandbox Mode", help= "Check this box if you're using the sandbox mode of Gengo, mainly used for testing purpose." )
class AccountTaxTemplatePython(models.Model): _inherit = 'account.tax.template' amount_type = fields.Selection(selection_add=[('code', 'Python Code')]) python_compute = fields.Text( string='Python Code', default="result = price_unit * 0.10", help= "Compute the amount of the tax by setting the variable 'result'.\n\n" ":param base_amount: float, actual amount on which the tax is applied\n" ":param price_unit: float\n" ":param quantity: float\n" ":param product: product.product recordset singleton or None\n" ":param partner: res.partner recordset singleton or None") python_applicable = fields.Text( string='Applicable Code', default="result = True", help= "Determine if the tax will be applied by setting the variable 'result' to True or False.\n\n" ":param price_unit: float\n" ":param quantity: float\n" ":param product: product.product recordset singleton or None\n" ":param partner: res.partner recordset singleton or None") def _get_tax_vals(self, company, tax_template_to_tax): """ This method generates a dictionnary of all the values for the tax that will be created. """ self.ensure_one() res = super(AccountTaxTemplatePython, self)._get_tax_vals(company, tax_template_to_tax) res['python_compute'] = self.python_compute res['python_applicable'] = self.python_applicable return res
class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' gengo_private_key = fields.Text(string="Gengo Private Key", related="company_id.gengo_private_key", readonly=False) gengo_public_key = fields.Text(string="Gengo Public Key", related="company_id.gengo_public_key", readonly=False) gengo_comment = fields.Text(string="Comments", related="company_id.gengo_comment", help="This comment will be automatically be enclosed in each an every request sent to Gengo") gengo_auto_approve = fields.Boolean(string="Auto Approve Translation ?", related="company_id.gengo_auto_approve", readonly=False, help="Jobs are Automatically Approved by Gengo.") gengo_sandbox = fields.Boolean(string="Sandbox Mode", related="company_id.gengo_sandbox", readonly=False, help="Check this box if you're using the sandbox mode of Gengo, mainly used for testing purpose.")
class pos_cache(models.Model): _name = 'pos.cache' _description = 'Point of Sale Cache' cache = fields.Binary(attachment=True) product_domain = fields.Text(required=True) product_fields = fields.Text(required=True) config_id = fields.Many2one('pos.config', ondelete='cascade', required=True) compute_user_id = fields.Many2one('res.users', 'Cache compute user', required=True) @api.model def refresh_all_caches(self): self.env['pos.cache'].search([]).refresh_cache() @api.one def refresh_cache(self): Product = self.env['product.product'].sudo(self.compute_user_id.id) products = Product.search(self.get_product_domain()) prod_ctx = products.with_context( pricelist=self.config_id.pricelist_id.id, display_default_code=False, lang=self.compute_user_id.lang) res = prod_ctx.read(self.get_product_fields()) datas = { 'cache': base64.encodestring(json.dumps(res).encode('utf-8')), } self.write(datas) @api.model def get_product_domain(self): return literal_eval(self.product_domain) @api.model def get_product_fields(self): return literal_eval(self.product_fields) @api.model def get_cache(self, domain, fields): if not self.cache or domain != self.get_product_domain( ) or fields != self.get_product_fields(): self.product_domain = str(domain) self.product_fields = str(fields) self.refresh_cache() return json.loads(base64.decodestring(self.cache).decode('utf-8'))
class AccountingAssertTest(models.Model): _name = "accounting.assert.test" _description = '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 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 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 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 ConverterTest(models.Model): _name = 'web_editor.converter.test' _description = 'Web Editor Converter Test' # disable translation export for those brilliant field labels and values _translate = False char = fields.Char() integer = fields.Integer() float = fields.Float() numeric = fields.Float(digits=(16, 2)) many2one = fields.Many2one('web_editor.converter.test.sub') binary = fields.Binary() date = fields.Date() datetime = fields.Datetime() selection = fields.Selection([ (1, "réponse A"), (2, "réponse B"), (3, "réponse C"), (4, "réponse <D>"), ]) selection_str = fields.Selection([ ('A', "Qu'il n'est pas arrivé à Toronto"), ('B', "Qu'il était supposé arriver à Toronto"), ('C', "Qu'est-ce qu'il fout ce maudit pancake, tabernacle ?"), ('D', "La réponse D"), ], string=u"Lorsqu'un pancake prend l'avion à destination de Toronto et " u"qu'il fait une escale technique à St Claude, on dit:") html = fields.Html() text = fields.Text()
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 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 res_partner(models.Model): _name = 'res.partner' _inherit = 'res.partner' @api.multi def _compute_purchase_order_count(self): # retrieve all children partners and prefetch 'parent_id' on them all_partners = self.search([('id', 'child_of', self.ids)]) all_partners.read(['parent_id']) purchase_order_groups = self.env['purchase.order'].read_group( domain=[('partner_id', 'in', all_partners.ids)], fields=['partner_id'], groupby=['partner_id']) for group in purchase_order_groups: partner = self.browse(group['partner_id'][0]) while partner: if partner in self: partner.purchase_order_count += group['partner_id_count'] partner = partner.parent_id @api.multi def _compute_supplier_invoice_count(self): # retrieve all children partners and prefetch 'parent_id' on them all_partners = self.search([('id', 'child_of', self.ids)]) all_partners.read(['parent_id']) supplier_invoice_groups = self.env['account.invoice'].read_group( domain=[('partner_id', 'in', all_partners.ids), ('type', 'in', ['in_invoice', 'in_refund'])], fields=['partner_id'], groupby=['partner_id']) for group in supplier_invoice_groups: partner = self.browse(group['partner_id'][0]) while partner: if partner in self: partner.supplier_invoice_count += group['partner_id_count'] partner = partner.parent_id @api.model def _commercial_fields(self): return super(res_partner, self)._commercial_fields() property_purchase_currency_id = fields.Many2one( 'res.currency', string="Supplier Currency", company_dependent=True, help= "This currency will be used, instead of the default one, for purchases from the current partner" ) purchase_order_count = fields.Integer( compute='_compute_purchase_order_count', string='Purchase Order Count') supplier_invoice_count = fields.Integer( compute='_compute_supplier_invoice_count', string='# Vendor Bills') purchase_warn = fields.Selection(WARNING_MESSAGE, 'Purchase Order', help=WARNING_HELP, default="no-message") purchase_warn_msg = fields.Text('Message for Purchase Order')
class DeliveryCarrier(models.Model): _name = 'delivery.carrier' _inherit = ['delivery.carrier', 'website.published.multi.mixin'] website_description = fields.Text( related='product_id.description_sale', string='Description for Online Quotations', readonly=False)
class BadgeUser(models.Model): """User having received a badge""" _name = 'gamification.badge.user' _description = 'Gamification User Badge' _order = "create_date desc" _rec_name = "badge_name" user_id = fields.Many2one('res.users', string="User", required=True, ondelete="cascade", index=True) sender_id = fields.Many2one('res.users', string="Sender", help="The user who has send the badge") badge_id = fields.Many2one('gamification.badge', string='Badge', required=True, ondelete="cascade", index=True) challenge_id = fields.Many2one( 'gamification.challenge', string='Challenge originating', help="If this badge was rewarded through a challenge") comment = fields.Text('Comment') badge_name = fields.Char(related='badge_id.name', string="Badge Name", readonly=False) def _send_badge(self): """Send a notification to a user for receiving a badge Does not verify constrains on badge granting. The users are added to the owner_ids (create badge_user if needed) The stats counters are incremented :param ids: list(int) of badge users that will receive the badge """ template = self.env.ref('gamification.email_template_badge_received') for badge_user in self: self.env['mail.thread'].message_post_with_template( template.id, model=badge_user._name, res_id=badge_user.id, composition_mode='mass_mail', partner_ids=badge_user.user_id.partner_id.ids, ) return True @api.model def create(self, vals): self.env['gamification.badge'].browse( vals['badge_id']).check_granting() return super(BadgeUser, self).create(vals)
class MrpWorkcenterProductivity(models.Model): _name = "mrp.workcenter.productivity" _description = "Workcenter Productivity Log" _order = "id desc" _rec_name = "loss_id" production_id = fields.Many2one('mrp.production', string='Manufacturing Order', related='workorder_id.production_id', readonly='True') workcenter_id = fields.Many2one('mrp.workcenter', "Work Center", required=True) workorder_id = fields.Many2one('mrp.workorder', 'Work Order') user_id = fields.Many2one('res.users', "User", default=lambda self: self.env.uid) loss_id = fields.Many2one('mrp.workcenter.productivity.loss', "Loss Reason", ondelete='restrict', required=True) loss_type = fields.Selection("Effectiveness", related='loss_id.loss_type', store=True, readonly=False) description = fields.Text('Description') date_start = fields.Datetime('Start Date', default=fields.Datetime.now, required=True) date_end = fields.Datetime('End Date') duration = fields.Float('Duration', compute='_compute_duration', store=True) @api.depends('date_end', 'date_start') def _compute_duration(self): for blocktime in self: if blocktime.date_end: d1 = fields.Datetime.from_string(blocktime.date_start) d2 = fields.Datetime.from_string(blocktime.date_end) diff = d2 - d1 if (blocktime.loss_type not in ('productive', 'performance') ) and blocktime.workcenter_id.resource_calendar_id: r = blocktime.workcenter_id.get_work_days_data(d1, d2)['hours'] blocktime.duration = round(r * 60, 2) else: blocktime.duration = round(diff.total_seconds() / 60.0, 2) else: blocktime.duration = 0.0 @api.multi def button_block(self): self.ensure_one() self.workcenter_id.order_ids.end_all()
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 WebsiteResPartner(models.Model): _name = 'res.partner' _inherit = ['res.partner', 'website.seo.metadata', 'website.published.mixin'] website_description = fields.Html('Website Partner Full Description', strip_style=True, translate=html_translate) website_short_description = fields.Text('Website Partner Short Description', translate=True) @api.multi def _compute_website_url(self): super(WebsiteResPartner, self)._compute_website_url() for partner in self: partner.website_url = "/partners/%s" % slug(partner)
class ResCountry(models.Model): _inherit = 'res.country' street_format = fields.Text( help="Format to use for streets belonging to this country.\n\n" "You can use the python-style string pattern with all the fields of the street " "(for example, use '%(street_name)s, %(street_number)s' if you want to display " "the street name, followed by a comma and the house number)" "\n%(street_name)s: the name of the street" "\n%(street_number)s: the house number" "\n%(street_number2)s: the door number", default='%(street_number)s/%(street_number2)s %(street_name)s', required=True)
class Partner(models.Model): _inherit = 'res.partner' property_stock_customer = fields.Many2one( 'stock.location', string="Customer Location", company_dependent=True, 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, 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') # TDE FIXME: expand this message / help picking_warn_msg = fields.Text('Message for Stock Picking')
class Stage(models.Model): """ Model for case stages. This models the main stages of a document management flow. Main CRM objects (leads, opportunities, project issues, ...) will now use only stages, instead of state and stages. Stages are for example used to display the kanban view of records. """ _name = "crm.stage" _description = "CRM Stages" _rec_name = 'name' _order = "sequence, name, id" @api.model def default_get(self, fields): """ Hack : when going from the pipeline, creating a stage with a sales team in context should not create a stage for the current Sales Team only """ ctx = dict(self.env.context) if ctx.get('default_team_id') and not ctx.get('crm_team_mono'): ctx.pop('default_team_id') return super(Stage, self.with_context(ctx)).default_get(fields) name = fields.Char('Stage Name', required=True, translate=True) sequence = fields.Integer('Sequence', default=1, help="Used to order stages. Lower is better.") probability = fields.Float('Probability (%)', required=True, default=10.0, help="This percentage depicts the default/average probability of the Case for this stage to be a success") on_change = fields.Boolean('Change Probability Automatically', help="Setting this stage will change the probability automatically on the opportunity.") requirements = fields.Text('Requirements', help="Enter here the internal requirements for this stage (ex: Offer sent to customer). It will appear as a tooltip over the stage's name.") team_id = fields.Many2one('crm.team', string='Sales Team', ondelete='set null', help='Specific team that uses this stage. Other teams will not be able to see or use this stage.') legend_priority = fields.Text('Priority Management Explanation', translate=True, help='Explanation text to help users using the star and priority mechanism on stages or issues that are in this stage.') fold = fields.Boolean('Folded in Pipeline', help='This stage is folded in the kanban view when there are no records in that stage to display.') #This field for interface only team_count = fields.Integer('team_count', compute='_compute_team_count') @api.multi def _compute_team_count(self): for stage in self: stage.team_count = self.env['crm.team'].search_count([])
class SaleOrderTemplateOption(models.Model): _name = "sale.order.template.option" _description = "Quotation Template Option" sale_order_template_id = fields.Many2one('sale.order.template', 'Quotation Template Reference', ondelete='cascade', index=True, required=True) name = fields.Text('Description', required=True, translate=True) product_id = fields.Many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], required=True) price_unit = fields.Float('Unit Price', required=True, digits=dp.get_precision('Product Price')) discount = fields.Float('Discount (%)', digits=dp.get_precision('Discount')) uom_id = fields.Many2one('uom.uom', 'Unit of Measure ', required=True) quantity = fields.Float('Quantity', required=True, digits=dp.get_precision('Product UoS'), default=1) @api.onchange('product_id') def _onchange_product_id(self): if not self.product_id: return product = self.product_id self.price_unit = product.lst_price name = product.name if self.product_id.description_sale: name += '\n' + self.product_id.description_sale self.name = name self.uom_id = product.uom_id domain = { 'uom_id': [('category_id', '=', self.product_id.uom_id.category_id.id)] } return {'domain': domain} @api.onchange('uom_id') def _onchange_product_uom(self): if not self.product_id: return if not self.uom_id: self.price_unit = 0.0 return if self.uom_id.id != self.product_id.uom_id.id: self.price_unit = self.product_id.uom_id._compute_price( self.product_id.lst_price, self.uom_id)
class FleetVehicleLogFuel(models.Model): _name = 'fleet.vehicle.log.fuel' _description = 'Fuel log for vehicles' _inherits = {'fleet.vehicle.cost': 'cost_id'} @api.model def default_get(self, default_fields): res = super(FleetVehicleLogFuel, self).default_get(default_fields) service = self.env.ref('fleet.type_service_refueling', raise_if_not_found=False) res.update({ 'date': fields.Date.context_today(self), 'cost_subtype_id': service and service.id or False, 'cost_type': 'fuel' }) return res liter = fields.Float() price_per_liter = fields.Float() purchaser_id = fields.Many2one('res.partner', 'Purchaser', domain="['|',('customer','=',True),('employee','=',True)]") inv_ref = fields.Char('Invoice Reference', size=64) vendor_id = fields.Many2one('res.partner', 'Vendor', domain="[('supplier','=',True)]") notes = fields.Text() cost_id = fields.Many2one('fleet.vehicle.cost', 'Cost', required=True, ondelete='cascade') # 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 # (2) fields that aren't stored in database cost_amount = fields.Float(related='cost_id.amount', string='Amount', store=True, readonly=False) @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 @api.onchange('liter', 'price_per_liter', 'amount') def _onchange_liter_price_amount(self): # need to cast in float because the value receveid from web client maybe an integer (Javascript and JSON do not # make any difference between 3.0 and 3). This cause a problem if you encode, for example, 2 liters at 1.5 per # liter => total is computed as 3.0, then trigger an onchange that recomputes price_per_liter as 3/2=1 (instead # of 3.0/2=1.5) # If there is no change in the result, we return an empty dict to prevent an infinite loop due to the 3 intertwine # onchange. And in order to verify that there is no change in the result, we have to limit the precision of the # computation to 2 decimal liter = float(self.liter) price_per_liter = float(self.price_per_liter) amount = float(self.amount) if liter > 0 and price_per_liter > 0 and round(liter * price_per_liter, 2) != amount: self.amount = round(liter * price_per_liter, 2) elif amount > 0 and liter > 0 and round(amount / liter, 2) != price_per_liter: self.price_per_liter = round(amount / liter, 2) elif amount > 0 and price_per_liter > 0 and round(amount / price_per_liter, 2) != liter: self.liter = round(amount / price_per_liter, 2)
class WebsiteTwitterTweet(models.Model): _name = 'website.twitter.tweet' _description = 'Website Twitter' website_id = fields.Many2one('website', string='Website', ondelete='cascade') screen_name = fields.Char(string='Screen Name') tweet = fields.Text(string='Tweets') # Twitter IDs are 64-bit unsigned ints, so we need to store them in # unlimited precision NUMERIC columns, which can be done with a # float field. Used digits=(0,0) to indicate unlimited. # Using VARCHAR would work too but would have sorting problems. tweet_id = fields.Float(string='Tweet ID', digits=(0, 0)) # Twitter
class IrActionsActUrl(models.Model): _name = 'ir.actions.act_url' _description = 'Action URL' _table = 'ir_act_url' _inherit = 'ir.actions.actions' _sequence = 'ir_actions_id_seq' _order = 'name' name = fields.Char(string='Action Name', translate=True) type = fields.Char(default='ir.actions.act_url') url = fields.Text(string='Action URL', required=True) target = fields.Selection([('new', 'New Window'), ('self', 'This Window')], string='Action Target', default='new', required=True)
class HrContributionRegister(models.Model): _name = 'hr.contribution.register' _description = 'Contribution Register' company_id = fields.Many2one( 'res.company', string='Company', default=lambda self: self.env['res.company']._company_default_get()) partner_id = fields.Many2one('res.partner', string='Partner') name = fields.Char(required=True) register_line_ids = fields.One2many('hr.payslip.line', 'register_id', string='Register Line', readonly=True) note = fields.Text(string='Description')
class IrLogging(models.Model): _name = 'ir.logging' _description = 'Logging' _order = 'id DESC' # The _log_access fields are defined manually for the following reasons: # # - The entries in ir_logging are filled in with sql queries bypassing the orm. As the --log-db # cli option allows to insert ir_logging entries into a remote database, the one2many *_uid # fields make no sense in the first place but we will keep it for backward compatibility. # # - Also, when an ir_logging entry is triggered by the orm (when using --log-db) at the moment # it is making changes to the res.users model, the ALTER TABLE will aquire an exclusive lock # on res_users, preventing the ir_logging INSERT to be processed, hence the ongoing module # install/update will hang forever as the orm is blocked by the ir_logging query that will # never occur. create_uid = fields.Integer(string='Created by', readonly=True) create_date = fields.Datetime(string='Created on', readonly=True) write_uid = fields.Integer(string='Last Updated by', readonly=True) write_date = fields.Datetime(string='Last Updated on', readonly=True) name = fields.Char(required=True) type = fields.Selection([('client', 'Client'), ('server', 'Server')], required=True, index=True) dbname = fields.Char(string='Database Name', index=True) level = fields.Char(index=True) message = fields.Text(required=True) path = fields.Char(required=True) func = fields.Char(string='Function', required=True) line = fields.Char(required=True) @api.model_cr def init(self): super(IrLogging, self).init() self._cr.execute( "select 1 from information_schema.constraint_column_usage where table_name = 'ir_logging' and constraint_name = 'ir_logging_write_uid_fkey'" ) if self._cr.rowcount: # DROP CONSTRAINT unconditionally takes an ACCESS EXCLUSIVE lock # on the table, even "IF EXISTS" is set and not matching; disabling # the relevant trigger instead acquires SHARE ROW EXCLUSIVE, which # still conflicts with the ROW EXCLUSIVE needed for an insert self._cr.execute( "ALTER TABLE ir_logging DROP CONSTRAINT ir_logging_write_uid_fkey" )
class PortalWizard(models.TransientModel): """ A wizard to manage the creation/removal of portal users. """ _name = 'portal.wizard' _description = 'Grant Portal Access' def _default_user_ids(self): # for each partner, determine corresponding portal.wizard.user records partner_ids = self.env.context.get('active_ids', []) contact_ids = set() user_changes = [] for partner in self.env['res.partner'].sudo().browse(partner_ids): contact_partners = partner.child_ids | partner for contact in contact_partners: # make sure that each contact appears at most once in the list if contact.id not in contact_ids: contact_ids.add(contact.id) in_portal = False if contact.user_ids: in_portal = self.env.ref( 'base.group_portal' ) in contact.user_ids[0].groups_id user_changes.append((0, 0, { 'partner_id': contact.id, 'email': contact.email, 'in_portal': in_portal, })) return user_changes user_ids = fields.One2many('portal.wizard.user', 'wizard_id', string='Users', default=_default_user_ids) welcome_message = fields.Text( 'Invitation Message', help= "This text is included in the email sent to new users of the portal.") @api.multi def action_apply(self): self.ensure_one() self.user_ids.action_apply() return {'type': 'ir.actions.act_window_close'}
class MailShortcode(models.Model): """ Shortcode Canned Responses, allowing the user to defined shortcuts in its message. Should be applied before storing message in database. Emoji allowing replacing text with image for visual effect. Should be applied when the message is displayed (only for final rendering). These shortcodes are global and are available for every user. """ _name = 'mail.shortcode' _description = 'Canned Response / Shortcode' source = fields.Char( 'Shortcut', required=True, index=True, help="The shortcut which must be replaced in the Chat Messages") substitution = fields.Text( 'Substitution', required=True, index=True, help="The escaped html code replacing the shortcut") description = fields.Char('Description')
class ResPartner(models.Model): _inherit = 'res.partner' sale_order_count = fields.Integer(compute='_compute_sale_order_count', string='Sale Order Count') sale_order_ids = fields.One2many('sale.order', 'partner_id', 'Sales Order') sale_warn = fields.Selection(WARNING_MESSAGE, 'Sales Warnings', default='no-message', help=WARNING_HELP) sale_warn_msg = fields.Text('Message for Sales Order') def _compute_sale_order_count(self): # retrieve all children partners and prefetch 'parent_id' on them all_partners = self.with_context(active_test=False).search([ ('id', 'child_of', self.ids) ]) all_partners.read(['parent_id']) sale_order_groups = self.env['sale.order'].read_group( domain=[('partner_id', 'in', all_partners.ids)], fields=['partner_id'], groupby=['partner_id']) for group in sale_order_groups: partner = self.browse(group['partner_id'][0]) while partner: if partner in self: partner.sale_order_count += group['partner_id_count'] partner = partner.parent_id def can_edit_vat(self): ''' Can't edit `vat` if there is (non draft) issued SO. ''' can_edit_vat = super(ResPartner, self).can_edit_vat() if not can_edit_vat: return can_edit_vat SaleOrder = self.env['sale.order'] has_so = SaleOrder.search( [('partner_id', 'child_of', self.commercial_partner_id.id), ('state', 'in', ['sent', 'sale', 'done'])], limit=1) return can_edit_vat and not bool(has_so)
class MrpRouting(models.Model): """ Specifies routings of work centers """ _name = 'mrp.routing' _description = 'Routings' name = fields.Char('Routing', required=True) active = fields.Boolean( 'Active', default=True, help= "If the active field is set to False, it will allow you to hide the routing without removing it." ) code = fields.Char('Reference', copy=False, default=lambda self: _('New'), readonly=True) note = fields.Text('Description') operation_ids = fields.One2many('mrp.routing.workcenter', 'routing_id', 'Operations', copy=True, oldname='workcenter_lines') location_id = fields.Many2one( 'stock.location', 'Raw Materials Location', help= "Keep empty if you produce at the location where you find the raw materials. " "Set a location if you produce at a fixed location. This can be a partner location " "if you subcontract the manufacturing operations.") company_id = fields.Many2one('res.company', 'Company', default=lambda self: self.env['res.company']. _company_default_get('mrp.routing')) @api.model def create(self, vals): if 'code' not in vals or vals['code'] == _('New'): vals['code'] = self.env['ir.sequence'].next_by_code( 'mrp.routing') or _('New') return super(MrpRouting, self).create(vals)