class MixedModel(models.Model): _name = 'test_new_api.mixed' _description = 'Test New API Mixed' number = fields.Float(digits=(10, 2), default=3.14) number2 = fields.Float(digits='New API Precision') date = fields.Date() moment = fields.Datetime() now = fields.Datetime(compute='_compute_now') lang = fields.Selection(string='Language', selection='_get_lang') reference = fields.Reference(string='Related Document', selection='_reference_models') comment1 = fields.Html(sanitize=False) comment2 = fields.Html(sanitize_attributes=True, strip_classes=False) comment3 = fields.Html(sanitize_attributes=True, strip_classes=True) comment4 = fields.Html(sanitize_attributes=True, strip_style=True) currency_id = fields.Many2one('res.currency', default=lambda self: self.env.ref('base.EUR')) amount = fields.Monetary() def _compute_now(self): # this is a non-stored computed field without dependencies for message in self: message.now = fields.Datetime.now() @api.model def _get_lang(self): return self.env['res.lang'].get_installed() @api.model def _reference_models(self): models = self.env['ir.model'].sudo().search([('state', '!=', 'manual')]) return [(model.model, model.name) for model in models if not model.model.startswith('ir.')]
class RestaurantTable(models.Model): _name = 'restaurant.table' _description = 'Restaurant Table' name = fields.Char('Table Name', required=True, help='An internal identification of a table') floor_id = fields.Many2one('restaurant.floor', string='Floor') shape = fields.Selection([('square', 'Square'), ('round', 'Round')], string='Shape', required=True, default='square') position_h = fields.Float('Horizontal Position', default=10, help="The table's horizontal position from the left side to the table's center, in pixels") position_v = fields.Float('Vertical Position', default=10, help="The table's vertical position from the top to the table's center, in pixels") width = fields.Float('Width', default=50, help="The table's width in pixels") height = fields.Float('Height', default=50, help="The table's height in pixels") seats = fields.Integer('Seats', default=1, help="The default number of customer served at this table.") color = fields.Char('Color', help="The table's color, expressed as a valid 'background' CSS property value") active = fields.Boolean('Active', default=True, help='If false, the table is deactivated and will not be available in the point of sale') @api.model def create_from_ui(self, table): """ create or modify a table from the point of sale UI. table contains the table's fields. If it contains an id, it will modify the existing table. It then returns the id of the table. """ if table.get('floor_id'): table['floor_id'] = table['floor_id'][0] table_id = table.pop('id', False) if table_id: self.browse(table_id).write(table) else: table_id = self.create(table).id return table_id
class BaseModel(models.Model): _name = 'test_performance.base' _description = 'Test Performance Base' name = fields.Char() value = fields.Integer(default=0) value_pc = fields.Float(compute="_value_pc", store=True) value_ctx = fields.Float(compute="_value_ctx") partner_id = fields.Many2one('res.partner', string='Customer') line_ids = fields.One2many('test_performance.line', 'base_id') total = fields.Integer(compute="_total", store=True) tag_ids = fields.Many2many('test_performance.tag') @api.depends('value') def _value_pc(self): for record in self: record.value_pc = float(record.value) / 100 @api.depends_context('key') def _value_ctx(self): self.env.cr.execute('SELECT 42') # one dummy query per batch for record in self: record.value_ctx = self.env.context.get('key') @api.depends('line_ids.value') def _total(self): for record in self: record.total = sum(line.value for line in record.line_ids)
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(attachment=False) date = fields.Date() datetime = fields.Datetime() 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 res_company(models.Model): _inherit = "res.company" account_check_printing_layout = fields.Selection(string="Check Layout", required=True, help="Select the format corresponding to the check paper you will be printing your checks on.\n" "In order to disable the printing feature, select 'None'.", selection=[ ('disabled', 'None'), ('action_print_check_top', 'check on top'), ('action_print_check_middle', 'check in middle'), ('action_print_check_bottom', 'check on bottom') ], default="action_print_check_top") account_check_printing_date_label = fields.Boolean('Print Date Label', default=True, help="This option allows you to print the date label on the check as per CPA. Disable this if your pre-printed check includes the date label.") account_check_printing_multi_stub = fields.Boolean('Multi-Pages Check Stub', help="This option allows you to print check details (stub) on multiple pages if they don't fit on a single page.") account_check_printing_margin_top = fields.Float('Check Top Margin', default=0.25, help="Adjust the margins of generated checks to make it fit your printer's settings.") account_check_printing_margin_left = fields.Float('Check Left Margin', default=0.25, help="Adjust the margins of generated checks to make it fit your printer's settings.") account_check_printing_margin_right = fields.Float('Right Margin', default=0.25, help="Adjust the margins of generated checks to make it fit your printer's settings.")
class test_model(models.Model): _name = 'test_converter.test_model' _description = 'Test Converter Model' char = fields.Char() integer = fields.Integer() float = fields.Float() numeric = fields.Float(digits=(16, 2)) many2one = fields.Many2one('test_converter.test_model.sub', group_expand='_gbf_m2o') binary = fields.Binary(attachment=False) date = fields.Date() datetime = fields.Datetime() selection_str = fields.Selection( [ ('A', u"Qu'il n'est pas arrivé à Toronto"), ('B', u"Qu'il était supposé arriver à Toronto"), ('C', u"Qu'est-ce qu'il fout ce maudit pancake, tabernacle ?"), ('D', u"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() # `base` module does not contains any model that implement the functionality # `group_expand`; test this feature here... @api.model def _gbf_m2o(self, subs, domain, order): sub_ids = subs._search([], order=order, access_rights_uid=SUPERUSER_ID) return subs.browse(sub_ids)
class PriceRule(models.Model): _name = "delivery.price.rule" _description = "Delivery Price Rules" _order = 'sequence, list_price, id' @api.depends('variable', 'operator', 'max_value', 'list_base_price', 'list_price', 'variable_factor') def _compute_name(self): for rule in self: name = 'if %s %s %s then' % (rule.variable, rule.operator, rule.max_value) if rule.list_base_price and not rule.list_price: name = '%s fixed price %s' % (name, rule.list_base_price) elif rule.list_price and not rule.list_base_price: name = '%s %s times %s' % (name, rule.list_price, rule.variable_factor) else: name = '%s fixed price %s plus %s times %s' % (name, rule.list_base_price, rule.list_price, rule.variable_factor) rule.name = name name = fields.Char(compute='_compute_name') sequence = fields.Integer(required=True, default=10) carrier_id = fields.Many2one('delivery.carrier', 'Carrier', required=True, ondelete='cascade') variable = fields.Selection([('weight', 'Weight'), ('volume', 'Volume'), ('wv', 'Weight * Volume'), ('price', 'Price'), ('quantity', 'Quantity')], required=True, default='weight') operator = fields.Selection([('==', '='), ('<=', '<='), ('<', '<'), ('>=', '>='), ('>', '>')], required=True, default='<=') max_value = fields.Float('Maximum Value', required=True) list_base_price = fields.Float(string='Sale Base Price', digits='Product Price', required=True, default=0.0) list_price = fields.Float('Sale Price', digits='Product Price', required=True, default=0.0) variable_factor = fields.Selection([('weight', 'Weight'), ('volume', 'Volume'), ('wv', 'Weight * Volume'), ('price', 'Price'), ('quantity', 'Quantity')], 'Variable Factor', required=True, default='weight')
class DecimalPrecisionTestModel(models.Model): _name = 'decimal.precision.test' _description = 'Decimal Precision Test' float = fields.Float() float_2 = fields.Float(digits=(16, 2)) float_4 = fields.Float(digits=(16, 4))
class ResourceCalendarAttendance(models.Model): _name = "resource.calendar.attendance" _description = "Work Detail" _order = 'week_type, dayofweek, hour_from' name = fields.Char(required=True) dayofweek = fields.Selection([('0', 'Monday'), ('1', 'Tuesday'), ('2', 'Wednesday'), ('3', 'Thursday'), ('4', 'Friday'), ('5', 'Saturday'), ('6', 'Sunday')], 'Day of Week', required=True, index=True, default='0') date_from = fields.Date(string='Starting Date') date_to = fields.Date(string='End Date') hour_from = fields.Float( string='Work from', required=True, index=True, help="Start and End time of working.\n" "A specific value of 24:00 is interpreted as 23:59:59.999999.") hour_to = fields.Float(string='Work to', required=True) calendar_id = fields.Many2one("resource.calendar", string="Resource's Calendar", required=True, ondelete='cascade') day_period = fields.Selection([('morning', 'Morning'), ('afternoon', 'Afternoon')], required=True, default='morning') resource_id = fields.Many2one('resource.resource', 'Resource') week_type = fields.Selection([('1', 'Odd week'), ('0', 'Even week')], 'Week Even/Odd', default=False) two_weeks_calendar = fields.Boolean( "Calendar in 2 weeks mode", related='calendar_id.two_weeks_calendar') display_type = fields.Selection([('line_section', "Section")], default=False, help="Technical field for UX purpose.") sequence = fields.Integer( default=10, help= "Gives the sequence of this line when displaying the resource calendar." ) @api.onchange('hour_from', 'hour_to') def _onchange_hours(self): # avoid negative or after midnight self.hour_from = min(self.hour_from, 23.99) self.hour_from = max(self.hour_from, 0.0) self.hour_to = min(self.hour_to, 23.99) self.hour_to = max(self.hour_to, 0.0) # avoid wrong order self.hour_to = max(self.hour_to, self.hour_from)
class GroupOperator(models.Model): _name = 'export.group_operator' _description = 'Export Group Operator' int_sum = fields.Integer(group_operator='sum') int_max = fields.Integer(group_operator='max') float_min = fields.Float(group_operator='min') float_avg = fields.Float(group_operator='avg') date_max = fields.Date(group_operator='max') bool_and = fields.Boolean(group_operator='bool_and') bool_or = fields.Boolean(group_operator='bool_or') many2one = fields.Many2one('export.integer') one2many = fields.One2many('export.group_operator.one2many', 'parent_id')
class LeadScoringFrequency(models.Model): _name = 'crm.lead.scoring.frequency' _description = 'Lead Scoring Frequency' variable = fields.Char('Variable', index=True) value = fields.Char('Value') won_count = fields.Float( 'Won Count', digits=(16, 1)) # Float because we add 0.1 to avoid zero Frequency issue lost_count = fields.Float( 'Lost Count', digits=(16, 1)) # Float because we add 0.1 to avoid zero Frequency issue team_id = fields.Many2one('crm.team', 'Sales Team')
class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' country_code = fields.Char(string="Company Country code", related='company_id.country_id.code', readonly=True) account_check_printing_layout = fields.Selection( related='company_id.account_check_printing_layout', string="Check Layout", readonly=False, help= "Select the format corresponding to the check paper you will be printing your checks on.\n" "In order to disable the printing feature, select 'None'.") account_check_printing_date_label = fields.Boolean( related='company_id.account_check_printing_date_label', string="Print Date Label", readonly=False, help= "This option allows you to print the date label on the check as per CPA. Disable this if your pre-printed check includes the date label." ) account_check_printing_multi_stub = fields.Boolean( related='company_id.account_check_printing_multi_stub', string='Multi-Pages Check Stub', readonly=False, help= "This option allows you to print check details (stub) on multiple pages if they don't fit on a single page." ) account_check_printing_margin_top = fields.Float( related='company_id.account_check_printing_margin_top', string='Check Top Margin', readonly=False, help= "Adjust the margins of generated checks to make it fit your printer's settings." ) account_check_printing_margin_left = fields.Float( related='company_id.account_check_printing_margin_left', string='Check Left Margin', readonly=False, help= "Adjust the margins of generated checks to make it fit your printer's settings." ) account_check_printing_margin_right = fields.Float( related='company_id.account_check_printing_margin_right', string='Check Right Margin', readonly=False, help= "Adjust the margins of generated checks to make it fit your printer's settings." )
class SurveyLabel(models.Model): """ A suggested answer for a question """ _name = 'survey.label' _rec_name = 'value' _order = 'sequence,id' _description = 'Survey Label' question_id = fields.Many2one('survey.question', string='Question', ondelete='cascade') question_id_2 = fields.Many2one('survey.question', string='Question 2', ondelete='cascade') sequence = fields.Integer('Label Sequence order', default=10) value = fields.Char('Suggested value', translate=True, required=True) is_correct = fields.Boolean('Is a correct answer') answer_score = fields.Float( 'Score for this choice', help= "A positive score indicates a correct choice; a negative or null score indicates a wrong answer" ) @api.constrains('question_id', 'question_id_2') def _check_question_not_empty(self): """Ensure that field question_id XOR field question_id_2 is not null""" for label in self: if not bool(label.question_id) != bool(label.question_id_2): raise ValidationError( _("A label must be attached to only one question."))
class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' inventory_availability = fields.Selection([ ('never', 'Sell regardless of inventory'), ('always', 'Show inventory on website and prevent sales if not enough stock'), ('threshold', 'Show inventory when below the threshold and prevent sales if not enough stock'), ('custom', 'Show product-specific notifications'), ], string='Inventory Availability', default='never') available_threshold = fields.Float(string='Availability Threshold') website_warehouse_id = fields.Many2one('stock.warehouse', related='website_id.warehouse_id', domain="[('company_id', '=', website_company_id)]", readonly=False) def set_values(self): super(ResConfigSettings, self).set_values() IrDefault = self.env['ir.default'].sudo() IrDefault.set('product.template', 'inventory_availability', self.inventory_availability) IrDefault.set('product.template', 'available_threshold', self.available_threshold if self.inventory_availability == 'threshold' else None) @api.model def get_values(self): res = super(ResConfigSettings, self).get_values() IrDefault = self.env['ir.default'].sudo() res.update(inventory_availability=IrDefault.get('product.template', 'inventory_availability') or 'never', available_threshold=IrDefault.get('product.template', 'available_threshold') or 5.0) return res @api.onchange('website_company_id') def _onchange_website_company_id(self): if self.website_warehouse_id.company_id != self.website_company_id: return {'value': {'website_warehouse_id': False}}
class LeaveReportCalendar(models.Model): _name = "hr.leave.report.calendar" _description = 'Time Off Calendar' _auto = False _order = "start_datetime DESC, employee_id" name = fields.Char(string='Name', readonly=True) start_datetime = fields.Datetime(string='From', readonly=True) stop_datetime = fields.Datetime(string='To', readonly=True) tz = fields.Selection(_tz_get, string="Timezone", readonly=True) duration = fields.Float(string='Duration', readonly=True) employee_id = fields.Many2one('hr.employee', readonly=True) company_id = fields.Many2one('res.company', readonly=True) def init(self): tools.drop_view_if_exists(self._cr, 'hr_leave_report_calendar') self._cr.execute("""CREATE OR REPLACE VIEW hr_leave_report_calendar AS (SELECT row_number() OVER() AS id, ce.name AS name, ce.start_datetime AS start_datetime, ce.stop_datetime AS stop_datetime, ce.event_tz AS tz, ce.duration AS duration, hl.employee_id AS employee_id, em.company_id AS company_id FROM hr_leave hl LEFT JOIN calendar_event ce ON ce.id = hl.meeting_id LEFT JOIN hr_employee em ON em.id = hl.employee_id WHERE hl.state = 'validate'); """)
class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' lock_confirmed_po = fields.Boolean( "Lock Confirmed Orders", default=lambda self: self.env.company.po_lock == 'lock') po_lock = fields.Selection(related='company_id.po_lock', string="Purchase Order Modification *", readonly=False) po_order_approval = fields.Boolean("Purchase Order Approval", default=lambda self: self.env.company. po_double_validation == 'two_step') po_double_validation = fields.Selection( related='company_id.po_double_validation', string="Levels of Approvals *", readonly=False) po_double_validation_amount = fields.Monetary( related='company_id.po_double_validation_amount', string="Minimum Amount", currency_field='company_currency_id', readonly=False) company_currency_id = fields.Many2one( 'res.currency', related='company_id.currency_id', string="Company Currency", readonly=True, help='Utility field to express amount currency') default_purchase_method = fields.Selection( [ ('purchase', 'Ordered quantities'), ('receive', 'Received quantities'), ], string="Bill Control", default_model="product.template", help="This default value is applied to any new product created. " "This can be changed in the product detail form.", default="receive") group_warning_purchase = fields.Boolean( "Purchase Warnings", implied_group='purchase.group_warning_purchase') module_account_3way_match = fields.Boolean( "3-way matching: purchases, receptions and bills") module_purchase_requisition = fields.Boolean("Purchase Agreements") module_purchase_product_matrix = fields.Boolean("Purchase Grid Entry") po_lead = fields.Float(related='company_id.po_lead', readonly=False) use_po_lead = fields.Boolean( string="Security Lead Time for Purchase", config_parameter='purchase.use_po_lead', help= "Margin of error for vendor lead times. When the system generates Purchase Orders for reordering products,they will be scheduled that many days earlier to cope with unexpected vendor delays." ) @api.onchange('use_po_lead') def _onchange_use_po_lead(self): if not self.use_po_lead: self.po_lead = 0.0 def set_values(self): super(ResConfigSettings, self).set_values() self.po_lock = 'lock' if self.lock_confirmed_po else 'edit' self.po_double_validation = 'two_step' if self.po_order_approval else 'one_step'
class PosOrder(models.Model): _inherit = 'pos.order' currency_rate = fields.Float( "Currency Rate", compute='_compute_currency_rate', store=True, digits=(12, 6), readonly=True, help= 'The rate of the currency to the currency of rate applicable at the date of the order' ) crm_team_id = fields.Many2one('crm.team', string="Sales Team") @api.model def _complete_values_from_session(self, session, values): values = super(PosOrder, self)._complete_values_from_session(session, values) values.setdefault('crm_team_id', session.config_id.crm_team_id.id) return values @api.depends('pricelist_id.currency_id', 'date_order', 'company_id') def _compute_currency_rate(self): for order in self: date_order = order.date_order or fields.Datetime.now() order.currency_rate = self.env[ 'res.currency']._get_conversion_rate( order.company_id.currency_id, order.pricelist_id.currency_id, order.company_id, date_order) def _prepare_invoice(self): invoice_vals = super(PosOrder, self)._prepare_invoice() invoice_vals['team_id'] = self.crm_team_id return invoice_vals
class User(models.Model): _inherit = ['res.users'] hours_last_month = fields.Float(related='employee_id.hours_last_month') hours_last_month_display = fields.Char( related='employee_id.hours_last_month_display') attendance_state = fields.Selection(related='employee_id.attendance_state') last_check_in = fields.Datetime( related='employee_id.last_attendance_id.check_in') last_check_out = fields.Datetime( related='employee_id.last_attendance_id.check_out') def __init__(self, pool, cr): """ Override of __init__ to add access rights. Access rights are disabled by default, but allowed on some specific fields defined in self.SELF_{READ/WRITE}ABLE_FIELDS. """ attendance_readable_fields = [ 'hours_last_month', 'hours_last_month_display', 'attendance_state', 'last_check_in', 'last_check_out' ] super(User, self).__init__(pool, cr) # duplicate list to avoid modifying the original reference type(self).SELF_READABLE_FIELDS = type( self).SELF_READABLE_FIELDS + attendance_readable_fields
class FloatModel(models.Model): _name = model('float') _description = 'Tests: Base Import Model Float' value = fields.Float() value2 = fields.Monetary() currency_id = fields.Many2one('res.currency')
class ProductPackaging(models.Model): _inherit = 'product.packaging' def _get_default_weight_uom(self): return self.env['product.template']._get_weight_uom_name_from_ir_config_parameter() height = fields.Integer('Height') width = fields.Integer('Width') length = fields.Integer('Length') max_weight = fields.Float('Max Weight', help='Maximum weight shippable in this packaging') shipper_package_code = fields.Char('Package Code') package_carrier_type = fields.Selection([('none', 'No carrier integration')], string='Carrier', default='none') weight_uom_name = fields.Char(string='Weight unit of measure label', compute='_compute_weight_uom_name', default=_get_default_weight_uom) _sql_constraints = [ ('positive_height', 'CHECK(height>=0)', 'Height must be positive'), ('positive_width', 'CHECK(width>=0)', 'Width must be positive'), ('positive_length', 'CHECK(length>=0)', 'Length must be positive'), ('positive_max_weight', 'CHECK(max_weight>=0.0)', 'Max Weight must be positive'), ] @api.onchange('package_carrier_type') def _onchange_carrier_type(self): carrier_id = self.env['delivery.carrier'].search([('delivery_type', '=', self.package_carrier_type)], limit=1) if carrier_id: self.shipper_package_code = carrier_id._get_default_custom_package_code() else: self.shipper_package_code = False def _compute_weight_uom_name(self): for packaging in self: packaging.weight_uom_name = self.env['product.template']._get_weight_uom_name_from_ir_config_parameter()
class CrmTeam(models.Model): _inherit = 'crm.team' pos_config_ids = fields.One2many('pos.config', 'crm_team_id', string="Point of Sales") pos_sessions_open_count = fields.Integer( string='Open POS Sessions', compute='_compute_pos_sessions_open_count') pos_order_amount_total = fields.Float( string="Session Sale Amount", compute='_compute_pos_order_amount_total') def _compute_pos_sessions_open_count(self): for team in self: team.pos_sessions_open_count = self.env[ 'pos.session'].search_count([('config_id.crm_team_id', '=', team.id), ('state', '=', 'opened')]) def _compute_pos_order_amount_total(self): for team in self: team.pos_order_amount_total = sum( self.env['report.pos.order'].search([ ('session_id', 'in', team.pos_config_ids.mapped('session_ids').filtered( lambda s: s.state == 'opened').ids) ]).mapped('price_total'))
class ProductPackaging(models.Model): _name = "product.packaging" _description = "Product Packaging" _order = 'sequence' _check_company_auto = True name = fields.Char('Package Type', required=True) sequence = fields.Integer( 'Sequence', default=1, help="The first in the sequence is the default one.") product_id = fields.Many2one('product.product', string='Product', check_company=True) qty = fields.Float('Contained Quantity', help="Quantity of products contained in the packaging.") barcode = fields.Char( 'Barcode', copy=False, help= "Barcode used for packaging identification. Scan this packaging barcode from a transfer in the Barcode app to move all the contained units" ) product_uom_id = fields.Many2one('uom.uom', related='product_id.uom_id', readonly=True) company_id = fields.Many2one('res.company', 'Company', index=True)
class LunchCashMove(models.Model): """ Two types of cashmoves: payment (credit) or order (debit) """ _name = 'lunch.cashmove' _description = 'Lunch Cashmove' _order = 'date desc' currency_id = fields.Many2one( 'res.currency', default=lambda self: self.env.company.currency_id) user_id = fields.Many2one('res.users', 'User', default=lambda self: self.env.uid) date = fields.Date('Date', required=True, default=fields.Date.context_today) amount = fields.Float('Amount', required=True) description = fields.Text('Description') def name_get(self): return [(cashmove.id, '%s %s' % (_('Lunch Cashmove'), '#%d' % cashmove.id)) for cashmove in self] @api.model def get_wallet_balance(self, user, include_config=True): result = float_round(sum( move['amount'] for move in self.env['lunch.cashmove.report'].search_read([( 'user_id', '=', user.id)], ['amount'])), precision_digits=2) if include_config: result += user.company_id.lunch_minimum_threshold return result
class FleetVehicleOdometer(models.Model): _name = 'fleet.vehicle.odometer' _description = 'Odometer log for a vehicle' _order = 'date desc' name = fields.Char(compute='_compute_vehicle_log_name', store=True) date = fields.Date(default=fields.Date.context_today) value = fields.Float('Odometer Value', group_operator="max") vehicle_id = fields.Many2one('fleet.vehicle', 'Vehicle', required=True) unit = fields.Selection(related='vehicle_id.odometer_unit', string="Unit", readonly=True) driver_id = fields.Many2one(related="vehicle_id.driver_id", string="Driver", readonly=False) @api.depends('vehicle_id', 'date') def _compute_vehicle_log_name(self): for record in self: name = record.vehicle_id.name if not name: name = str(record.date) elif record.date: name += ' / ' + str(record.date) record.name = name @api.onchange('vehicle_id') def _onchange_vehicle(self): if self.vehicle_id: self.unit = self.vehicle_id.odometer_unit
class LandedCostLine(models.Model): _name = 'stock.landed.cost.lines' _description = 'Stock Landed Cost Line' name = fields.Char('Description') cost_id = fields.Many2one('stock.landed.cost', 'Landed Cost', required=True, ondelete='cascade') product_id = fields.Many2one('product.product', 'Product', required=True) price_unit = fields.Float('Cost', digits='Product Price', required=True) split_method = fields.Selection(SPLIT_METHOD, string='Split Method', required=True) account_id = fields.Many2one('account.account', 'Account', domain=[('deprecated', '=', False)]) @api.onchange('product_id') def onchange_product_id(self): if not self.product_id: self.quantity = 0.0 self.name = self.product_id.name or '' self.split_method = self.split_method or 'equal' self.price_unit = self.product_id.standard_price or 0.0 accounts_data = self.product_id.product_tmpl_id.get_product_accounts() self.account_id = accounts_data['stock_input']
class CrmPartnerReportAssign(models.Model): """ CRM Lead Report """ _name = "crm.partner.report.assign" _auto = False _description = "CRM Partnership Analysis" partner_id = fields.Many2one('res.partner', 'Partner', required=False, readonly=True) grade_id = fields.Many2one('res.partner.grade', 'Grade', readonly=True) activation = fields.Many2one('res.partner.activation', 'Activation', index=True) user_id = fields.Many2one('res.users', 'User', readonly=True) date_review = fields.Date('Latest Partner Review') date_partnership = fields.Date('Partnership Date') country_id = fields.Many2one('res.country', 'Country', readonly=True) team_id = fields.Many2one('crm.team', 'Sales Team', readonly=True) nbr_opportunities = fields.Integer('# of Opportunity', readonly=True) turnover = fields.Float('Turnover', readonly=True) date = fields.Date('Invoice Account Date', readonly=True) _depends = { 'account.invoice.report': ['invoice_date', 'partner_id', 'price_subtotal', 'state', 'type'], 'crm.lead': ['partner_assigned_id'], 'res.partner': [ 'activation', 'country_id', 'date_partnership', 'date_review', 'grade_id', 'parent_id', 'team_id', 'user_id' ], } def init(self): """ CRM Lead Report @param cr: the current row, from the database cursor """ tools.drop_view_if_exists(self._cr, 'crm_partner_report_assign') self._cr.execute(""" CREATE OR REPLACE VIEW crm_partner_report_assign AS ( SELECT coalesce(i.id, p.id - 1000000000) as id, p.id as partner_id, (SELECT country_id FROM res_partner a WHERE a.parent_id=p.id AND country_id is not null limit 1) as country_id, p.grade_id, p.activation, p.date_review, p.date_partnership, p.user_id, p.team_id, (SELECT count(id) FROM crm_lead WHERE partner_assigned_id=p.id) AS nbr_opportunities, i.price_subtotal as turnover, i.invoice_date as date FROM res_partner p left join account_invoice_report i on (i.partner_id=p.id and i.type in ('out_invoice','out_refund') and i.state='open') )""")
class SaleReport(models.Model): _inherit = 'sale.report' margin = fields.Float('Margin') def _query(self, with_clause='', fields={}, groupby='', from_clause=''): fields['margin'] = ", SUM(l.margin / CASE COALESCE(s.currency_rate, 0) WHEN 0 THEN 1.0 ELSE s.currency_rate END) AS margin" return super(SaleReport, self)._query(with_clause, fields, groupby, from_clause)
class ReportProjectTaskUser(models.Model): _inherit = "report.project.task.user" hours_planned = fields.Float('Planned Hours', readonly=True) hours_effective = fields.Float('Effective Hours', readonly=True) remaining_hours = fields.Float('Remaining Hours', readonly=True) progress = fields.Float('Progress', group_operator='avg', readonly=True) def _select(self): return super(ReportProjectTaskUser, self)._select() + """, progress as progress, t.effective_hours as hours_effective, t.planned_hours - t.effective_hours - t.subtask_effective_hours as remaining_hours, planned_hours as hours_planned""" def _group_by(self): return super(ReportProjectTaskUser, self)._group_by() + """,
class TimesheetAttendance(models.Model): _name = 'hr.timesheet.attendance.report' _auto = False _description = 'Timesheet Attendance Report' user_id = fields.Many2one('res.users') date = fields.Date() total_timesheet = fields.Float() total_attendance = fields.Float() total_difference = fields.Float() def init(self): tools.drop_view_if_exists(self.env.cr, self._table) self._cr.execute("""CREATE OR REPLACE VIEW %s AS ( SELECT max(id) AS id, t.user_id, t.date, coalesce(sum(t.attendance), 0) AS total_attendance, coalesce(sum(t.timesheet), 0) AS total_timesheet, coalesce(sum(t.attendance), 0) - coalesce(sum(t.timesheet), 0) as total_difference FROM ( SELECT -hr_attendance.id AS id, resource_resource.user_id AS user_id, hr_attendance.worked_hours AS attendance, NULL AS timesheet, hr_attendance.check_in::date AS date FROM hr_attendance LEFT JOIN hr_employee ON hr_employee.id = hr_attendance.employee_id LEFT JOIN resource_resource on resource_resource.id = hr_employee.resource_id UNION ALL SELECT ts.id AS id, ts.user_id AS user_id, NULL AS attendance, ts.unit_amount AS timesheet, ts.date AS date FROM account_analytic_line AS ts WHERE ts.project_id IS NOT NULL ) AS t GROUP BY t.user_id, t.date ORDER BY t.date ) """ % self._table)
class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' currency_id = fields.Many2one('res.currency', related='company_id.currency_id') company_lunch_minimum_threshold = fields.Float( string="Maximum Allowed Overdraft", readonly=False, related='company_id.lunch_minimum_threshold')