[REF] various: update tracking parameters

Purpose is to clean the use of tracking parameters on fields. Parameters are
merged and is now tracking=<int> or tracking=True.

This commit is linked to task ID 1903814 and PR #28430.
This commit is contained in:
Thibault Delavallée
2019-01-04 11:46:14 +00:00
parent 09ad56bcd6
commit b8197ff178
43 changed files with 161 additions and 161 deletions
+7 -7
View File
@@ -241,7 +241,7 @@ class AccountInvoice(models.Model):
('in_refund','Vendor Credit Note'),
], readonly=True, states={'draft': [('readonly', False)]}, index=True, change_default=True,
default=lambda self: self._context.get('type', 'out_invoice'),
track_visibility='always')
tracking=True)
refund_invoice_id = fields.Many2one('account.invoice', string="Invoice for which this invoice is the credit note")
number = fields.Char(related='move_id.name', store=True, readonly=True, copy=False)
@@ -259,7 +259,7 @@ class AccountInvoice(models.Model):
('paid', 'Paid'),
('cancel', 'Cancelled'),
], string='Status', index=True, readonly=True, default='draft',
track_visibility='onchange', copy=False,
tracking=True, copy=False,
help=" * The 'Draft' status is used when a user is encoding a new and unconfirmed Invoice.\n"
" * The 'Open' status is used when user creates invoice, an invoice number is generated. It stays in the open status till the user pays the invoice.\n"
" * The 'In Payment' status is used when payments have been registered for the entirety of the invoice in a journal configured to post entries at bank reconciliation only, and some of them haven't been reconciled with a bank statement line yet.\n"
@@ -279,7 +279,7 @@ class AccountInvoice(models.Model):
"means direct payment.")
partner_id = fields.Many2one('res.partner', string='Partner', change_default=True,
readonly=True, states={'draft': [('readonly', False)]},
track_visibility='always', help="You can find a contact by its Name, TIN, Email or Internal Reference.")
tracking=True, help="You can find a contact by its Name, TIN, Email or Internal Reference.")
vendor_bill_id = fields.Many2one('account.invoice', string='Vendor Bill',
help="Auto-complete from a past bill.")
payment_term_id = fields.Many2one('account.payment.term', string='Payment Terms', oldname='payment_term',
@@ -306,7 +306,7 @@ class AccountInvoice(models.Model):
amount_by_group = fields.Binary(string="Tax amount by group", compute='_amount_by_group', help="type: [(name, amount, base, formated amount, formated base)]")
amount_untaxed = fields.Monetary(string='Untaxed Amount',
store=True, readonly=True, compute='_compute_amount', track_visibility='always')
store=True, readonly=True, compute='_compute_amount', tracking=True)
amount_untaxed_signed = fields.Monetary(string='Untaxed Amount in Company Currency', currency_field='company_currency_id',
store=True, readonly=True, compute='_compute_amount')
amount_tax = fields.Monetary(string='Tax',
@@ -321,7 +321,7 @@ class AccountInvoice(models.Model):
help="Total amount in the currency of the company, negative for credit notes.")
currency_id = fields.Many2one('res.currency', string='Currency',
required=True, readonly=True, states={'draft': [('readonly', False)]},
default=_default_currency, track_visibility='always')
default=_default_currency, tracking=True)
company_currency_id = fields.Many2one('res.currency', related='company_id.currency_id', string="Company Currency", readonly=True)
journal_id = fields.Many2one('account.journal', string='Journal',
required=True, readonly=True, states={'draft': [('readonly', False)]},
@@ -345,7 +345,7 @@ class AccountInvoice(models.Model):
compute='_compute_residual', store=True, help="Remaining amount due in the currency of the company.")
payment_ids = fields.Many2many('account.payment', 'account_invoice_payment_rel', 'invoice_id', 'payment_id', string="Payments", copy=False, readonly=True)
payment_move_line_ids = fields.Many2many('account.move.line', string='Payment Move Lines', compute='_compute_payments', store=True)
user_id = fields.Many2one('res.users', string='Salesperson', track_visibility='onchange',
user_id = fields.Many2one('res.users', string='Salesperson', tracking=True,
readonly=True, states={'draft': [('readonly', False)]},
default=lambda self: self.env.user, copy=False)
fiscal_position_id = fields.Many2one('account.fiscal.position', string='Fiscal Position', oldname='fiscal_position',
@@ -369,7 +369,7 @@ class AccountInvoice(models.Model):
help='International Commercial Terms are a series of predefined commercial terms used in international transactions.')
#fields related to vendor bills automated creation by email
source_email = fields.Char(string='Source Email', track_visibility='onchange')
source_email = fields.Char(string='Source Email', tracking=True)
vendor_display_name = fields.Char(compute='_get_vendor_display_info', store=True) # store=True to enable sorting on that column
invoice_icon = fields.Char(compute='_get_vendor_display_info', store=False)
@@ -65,7 +65,7 @@ class AccountVoucher(models.Model):
('cancel', 'Cancelled'),
('proforma', 'Pro-forma'),
('posted', 'Posted')
], 'Status', readonly=True, track_visibility='onchange', copy=False, default='draft',
], 'Status', readonly=True, tracking=True, copy=False, default='draft',
help=" * The 'Draft' status is used when a user is encoding a new and unconfirmed Voucher.\n"
" * The 'Pro-forma' status is used when the voucher does not have a voucher number.\n"
" * The 'Posted' status is used when user create voucher,a voucher number is generated and voucher entries are created in account.\n"
+3 -3
View File
@@ -121,8 +121,8 @@ class AccountAnalyticAccount(models.Model):
account.credit = data_credit.get(account.id, 0.0)
account.balance = account.credit - account.debit
name = fields.Char(string='Analytic Account', index=True, required=True, track_visibility='onchange')
code = fields.Char(string='Reference', index=True, track_visibility='onchange')
name = fields.Char(string='Analytic Account', index=True, required=True, tracking=True)
code = fields.Char(string='Reference', index=True, tracking=True)
active = fields.Boolean('Active', help="If the active field is set to False, it will allow you to hide the account without removing it.", default=True)
group_id = fields.Many2one('account.analytic.group', string='Group')
@@ -132,7 +132,7 @@ class AccountAnalyticAccount(models.Model):
company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id)
# use auto_join to speed up name_search call
partner_id = fields.Many2one('res.partner', string='Customer', auto_join=True, track_visibility='onchange')
partner_id = fields.Many2one('res.partner', string='Customer', auto_join=True, tracking=True)
balance = fields.Monetary(compute='_compute_debit_credit_balance', string='Balance')
debit = fields.Monetary(compute='_compute_debit_credit_balance', string='Debit')
+6 -6
View File
@@ -765,7 +765,7 @@ class Meeting(models.Model):
event.is_highlighted = True
name = fields.Char('Meeting Subject', required=True, states={'done': [('readonly', True)]})
state = fields.Selection([('draft', 'Unconfirmed'), ('open', 'Confirmed')], string='Status', readonly=True, track_visibility='onchange', default='draft')
state = fields.Selection([('draft', 'Unconfirmed'), ('open', 'Confirmed')], string='Status', readonly=True, tracking=True, default='draft')
is_attendee = fields.Boolean('Attendee', compute='_compute_attendee')
attendee_status = fields.Selection(Attendee.STATE_SELECTION, string='Attendee Status', compute='_compute_attendee')
@@ -775,14 +775,14 @@ class Meeting(models.Model):
stop = fields.Datetime('Stop', required=True, help="Stop date of an event, without time for full days events")
allday = fields.Boolean('All Day', states={'done': [('readonly', True)]}, default=False)
start_date = fields.Date('Start Date', compute='_compute_dates', inverse='_inverse_dates', store=True, states={'done': [('readonly', True)]}, track_visibility='onchange')
start_datetime = fields.Datetime('Start DateTime', compute='_compute_dates', inverse='_inverse_dates', store=True, states={'done': [('readonly', True)]}, track_visibility='onchange')
stop_date = fields.Date('End Date', compute='_compute_dates', inverse='_inverse_dates', store=True, states={'done': [('readonly', True)]}, track_visibility='onchange')
stop_datetime = fields.Datetime('End Datetime', compute='_compute_dates', inverse='_inverse_dates', store=True, states={'done': [('readonly', True)]}, track_visibility='onchange') # old date_deadline
start_date = fields.Date('Start Date', compute='_compute_dates', inverse='_inverse_dates', store=True, states={'done': [('readonly', True)]}, tracking=True)
start_datetime = fields.Datetime('Start DateTime', compute='_compute_dates', inverse='_inverse_dates', store=True, states={'done': [('readonly', True)]}, tracking=True)
stop_date = fields.Date('End Date', compute='_compute_dates', inverse='_inverse_dates', store=True, states={'done': [('readonly', True)]}, tracking=True)
stop_datetime = fields.Datetime('End Datetime', compute='_compute_dates', inverse='_inverse_dates', store=True, states={'done': [('readonly', True)]}, tracking=True) # old date_deadline
duration = fields.Float('Duration', states={'done': [('readonly', True)]})
description = fields.Text('Description', states={'done': [('readonly', True)]})
privacy = fields.Selection([('public', 'Everyone'), ('private', 'Only me'), ('confidential', 'Only internal users')], 'Privacy', default='public', states={'done': [('readonly', True)]}, oldname="class")
location = fields.Char('Location', states={'done': [('readonly', True)]}, track_visibility='onchange', help="Location of Event")
location = fields.Char('Location', states={'done': [('readonly', True)]}, tracking=True, help="Location of Event")
show_as = fields.Selection([('free', 'Free'), ('busy', 'Busy')], 'Show Time as', states={'done': [('readonly', True)]}, default='busy')
# linked document
+12 -12
View File
@@ -64,31 +64,31 @@ class Lead(models.Model):
return self._stage_find(team_id=team.id, domain=[('fold', '=', False)]).id
name = fields.Char('Opportunity', required=True, index=True)
partner_id = fields.Many2one('res.partner', string='Customer', track_visibility='onchange', track_sequence=1, index=True,
partner_id = fields.Many2one('res.partner', string='Customer', tracking=1, index=True,
help="Linked partner (optional). Usually created when converting the lead. You can find a partner by its Name, TIN, Email or Internal Reference.")
active = fields.Boolean('Active', default=True, track_visibility=True)
active = fields.Boolean('Active', default=True, tracking=True)
date_action_last = fields.Datetime('Last Action', readonly=True)
email_from = fields.Char('Email', help="Email address of the contact", track_visibility='onchange', track_sequence=4, index=True)
email_from = fields.Char('Email', help="Email address of the contact", tracking=4, index=True)
website = fields.Char('Website', index=True, help="Website of the contact")
team_id = fields.Many2one('crm.team', string='Sales Team', oldname='section_id', default=lambda self: self.env['crm.team'].sudo()._get_default_team_id(user_id=self.env.uid),
index=True, track_visibility='onchange', help='When sending mails, the default email address is taken from the Sales Team.')
index=True, tracking=True, help='When sending mails, the default email address is taken from the Sales Team.')
kanban_state = fields.Selection([('grey', 'No next activity planned'), ('red', 'Next activity late'), ('green', 'Next activity is planned')],
string='Kanban State', compute='_compute_kanban_state')
email_cc = fields.Text('Global CC', help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma")
description = fields.Text('Notes', track_visibility='onchange', track_sequence=6)
description = fields.Text('Notes', tracking=6)
tag_ids = fields.Many2many('crm.lead.tag', 'crm_lead_tag_rel', 'lead_id', 'tag_id', string='Tags', help="Classify and analyze your lead/opportunity categories like: Training, Service")
contact_name = fields.Char('Contact Name', track_visibility='onchange', track_sequence=3)
partner_name = fields.Char("Company Name", track_visibility='onchange', track_sequence=2, index=True, help='The name of the future partner company that will be created while converting the lead into opportunity')
contact_name = fields.Char('Contact Name', tracking=3)
partner_name = fields.Char("Company Name", tracking=2, index=True, help='The name of the future partner company that will be created while converting the lead into opportunity')
type = fields.Selection([('lead', 'Lead'), ('opportunity', 'Opportunity')], index=True, required=True,
default=lambda self: 'lead' if self.env['res.users'].has_group('crm.group_use_lead') else 'opportunity',
help="Type is used to separate Leads and Opportunities")
priority = fields.Selection(crm_stage.AVAILABLE_PRIORITIES, string='Priority', index=True, default=crm_stage.AVAILABLE_PRIORITIES[0][0])
date_closed = fields.Datetime('Closed Date', readonly=True, copy=False)
stage_id = fields.Many2one('crm.stage', string='Stage', ondelete='restrict', track_visibility='onchange', index=True,
stage_id = fields.Many2one('crm.stage', string='Stage', ondelete='restrict', tracking=True, index=True,
domain="['|', ('team_id', '=', False), ('team_id', '=', team_id)]",
group_expand='_read_group_stage_ids', default=lambda self: self._default_stage_id())
user_id = fields.Many2one('res.users', string='Salesperson', track_visibility='onchange', default=lambda self: self.env.user)
user_id = fields.Many2one('res.users', string='Salesperson', index=True, tracking=True, default=lambda self: self.env.user)
referred = fields.Char('Referred By')
date_open = fields.Datetime('Assignation Date', readonly=True, default=fields.Datetime.now)
@@ -102,7 +102,7 @@ class Lead(models.Model):
# Only used for type opportunity
probability = fields.Float('Probability', group_operator="avg", default=lambda self: self._default_probability())
planned_revenue = fields.Monetary('Expected Revenue', currency_field='company_currency', track_visibility='always')
planned_revenue = fields.Monetary('Expected Revenue', currency_field='company_currency', tracking=True)
expected_revenue = fields.Monetary('Prorated Revenue', currency_field='company_currency', store=True, compute="_compute_expected_revenue")
date_deadline = fields.Date('Expected Closing', help="Estimate of the date on which the opportunity will be won.")
color = fields.Integer('Color Index', default=0)
@@ -121,13 +121,13 @@ class Lead(models.Model):
city = fields.Char('City')
state_id = fields.Many2one("res.country.state", string='State')
country_id = fields.Many2one('res.country', string='Country')
phone = fields.Char('Phone', track_visibility='onchange', track_sequence=5)
phone = fields.Char('Phone', tracking=5)
mobile = fields.Char('Mobile')
function = fields.Char('Job Position')
title = fields.Many2one('res.partner.title')
company_id = fields.Many2one('res.company', string='Company', index=True, default=lambda self: self.env.user.company_id.id)
meeting_count = fields.Integer('# Meetings', compute='_compute_meeting_count')
lost_reason = fields.Many2one('crm.lost.reason', string='Lost Reason', index=True, track_visibility='onchange')
lost_reason = fields.Many2one('crm.lost.reason', string='Lost Reason', index=True, tracking=True)
_sql_constraints = [
('check_probability', 'check(probability >= 0 and probability <= 100)', 'The probability of closing the deal should be between 0% and 100%!')
+6 -6
View File
@@ -97,7 +97,7 @@ class EventEvent(models.Model):
user_id = fields.Many2one(
'res.users', string='Responsible',
default=lambda self: self.env.user,
track_visibility="onchange",
tracking=True,
readonly=False, states={'done': [('readonly', True)]})
company_id = fields.Many2one(
'res.company', string='Company', change_default=True,
@@ -105,7 +105,7 @@ class EventEvent(models.Model):
required=False, readonly=False, states={'done': [('readonly', True)]})
organizer_id = fields.Many2one(
'res.partner', string='Organizer',
track_visibility="onchange",
tracking=True,
default=lambda self: self.env.user.company_id.partner_id)
event_type_id = fields.Many2one(
'event.type', string='Category',
@@ -149,10 +149,10 @@ class EventEvent(models.Model):
date_tz = fields.Selection('_tz_get', string='Timezone', required=True, default=lambda self: self.env.user.tz or 'UTC')
date_begin = fields.Datetime(
string='Start Date', required=True,
track_visibility='onchange', states={'done': [('readonly', True)]})
tracking=True, states={'done': [('readonly', True)]})
date_end = fields.Datetime(
string='End Date', required=True,
track_visibility='onchange', states={'done': [('readonly', True)]})
tracking=True, states={'done': [('readonly', True)]})
date_begin_located = fields.Char(string='Start Date Located', compute='_compute_date_begin_tz')
date_end_located = fields.Char(string='End Date Located', compute='_compute_date_end_tz')
@@ -167,7 +167,7 @@ class EventEvent(models.Model):
'res.partner', string='Location',
default=lambda self: self.env.user.company_id.partner_id,
readonly=False, states={'done': [('readonly', True)]},
track_visibility="onchange")
tracking=True)
country_id = fields.Many2one('res.country', 'Country', related='address_id.country_id', store=True, readonly=False)
twitter_hashtag = fields.Char('Twitter Hashtag')
description = fields.Html(
@@ -389,7 +389,7 @@ class EventRegistration(models.Model):
state = fields.Selection([
('draft', 'Unconfirmed'), ('cancel', 'Cancelled'),
('open', 'Confirmed'), ('done', 'Attended')],
string='Status', default='draft', readonly=True, copy=False, track_visibility='onchange')
string='Status', default='draft', readonly=True, copy=False, tracking=True)
email = fields.Char(string='Email')
phone = fields.Char(string='Phone')
name = fields.Char(string='Attendee Name', index=True)
+5 -5
View File
@@ -18,14 +18,14 @@ class FleetVehicle(models.Model):
return state and state.id or False
name = fields.Char(compute="_compute_vehicle_name", store=True)
active = fields.Boolean('Active', default=True, track_visibility="onchange")
active = fields.Boolean('Active', default=True, tracking=True)
company_id = fields.Many2one('res.company', 'Company')
license_plate = fields.Char(track_visibility="onchange",
license_plate = fields.Char(tracking=True,
help='License plate number of the vehicle (i = plate number for a car)')
vin_sn = fields.Char('Chassis Number', help='Unique number written on the vehicle motor (VIN/SN number)', copy=False)
driver_id = fields.Many2one('res.partner', 'Driver', track_visibility="onchange", help='Driver of the vehicle', copy=False)
driver_id = fields.Many2one('res.partner', 'Driver', tracking=True, help='Driver of the vehicle', copy=False)
model_id = fields.Many2one('fleet.vehicle.model', 'Model',
track_visibility="onchange", required=True, help='Model of the vehicle')
tracking=True, required=True, help='Model of the vehicle')
brand_id = fields.Many2one('fleet.vehicle.model.brand', 'Brand', related="model_id.brand_id", store=True, readonly=False)
log_drivers = fields.One2many('fleet.vehicle.assignation.log', 'vehicle_id', string='Assignation Logs')
log_fuel = fields.One2many('fleet.vehicle.log.fuel', 'vehicle_id', 'Fuel Logs')
@@ -42,7 +42,7 @@ class FleetVehicle(models.Model):
color = fields.Char(help='Color of the vehicle')
state_id = fields.Many2one('fleet.vehicle.state', 'State',
default=_get_default_state, group_expand='_read_group_stage_ids',
track_visibility="onchange",
tracking=True,
help='Current state of the vehicle', ondelete="set null")
location = fields.Char(help='Location of the vehicle (garage, ...)')
seats = fields.Integer('Seats Number', help='Number of seats of the vehicle')
+2 -2
View File
@@ -115,10 +115,10 @@ class FleetVehicleLogContract(models.Model):
('closed', 'Closed')
], 'Status', default='open', readonly=True,
help='Choose whether the contract is still valid or not',
track_visibility="onchange",
tracking=True,
copy=False)
notes = fields.Text('Terms and Conditions', help='Write here all supplementary information relative to this contract', copy=False)
cost_generated = fields.Float('Recurring Cost Amount', track_visibility="onchange",
cost_generated = fields.Float('Recurring Cost Amount', tracking=True,
help="Costs paid at regular intervals, depending on the cost frequency. "
"If the cost frequency is set to unique, the cost will be logged at the start date")
cost_frequency = fields.Selection([
+1 -1
View File
@@ -67,7 +67,7 @@ class Challenge(models.Model):
('inprogress', "In Progress"),
('done', "Done"),
], default='draft', copy=False,
string="State", required=True, track_visibility='onchange')
string="State", required=True, tracking=True)
manager_id = fields.Many2one(
'res.users', default=lambda self: self.env.uid,
string="Responsible", help="The user responsible for the challenge.",)
+3 -3
View File
@@ -157,9 +157,9 @@ class Goal(models.Model):
"to generate goals with a value in this field.")
start_date = fields.Date("Start Date", default=fields.Date.today)
end_date = fields.Date("End Date") # no start and end = always active
target_goal = fields.Float('To Reach', required=True, track_visibility='always')
target_goal = fields.Float('To Reach', required=True, tracking=True)
# no goal = global index
current = fields.Float("Current Value", required=True, default=0, track_visibility='always')
current = fields.Float("Current Value", required=True, default=0, tracking=True)
completeness = fields.Float("Completeness", compute='_get_completion')
state = fields.Selection([
('draft', "Draft"),
@@ -167,7 +167,7 @@ class Goal(models.Model):
('reached', "Reached"),
('failed', "Failed"),
('canceled', "Canceled"),
], default='draft', string='State', required=True, track_visibility='always')
], default='draft', string='State', required=True, tracking=True)
to_update = fields.Boolean('To update')
closed = fields.Boolean('Closed goal', help="These goals will not be recomputed.")
+2 -2
View File
@@ -51,7 +51,7 @@ class Job(models.Model):
state = fields.Selection([
('recruit', 'Recruitment in Progress'),
('open', 'Not Recruiting')
], string='Status', readonly=True, required=True, track_visibility='always', copy=False, default='recruit', help="Set whether the recruitment process is open or closed for this job position.")
], string='Status', readonly=True, required=True, tracking=True, copy=False, default='recruit', help="Set whether the recruitment process is open or closed for this job position.")
_sql_constraints = [
('name_company_uniq', 'unique(name, company_id, department_id)', 'The name of the job position must be unique per department in company!'),
@@ -348,7 +348,7 @@ class Department(models.Model):
company_id = fields.Many2one('res.company', string='Company', index=True, default=lambda self: self.env.user.company_id)
parent_id = fields.Many2one('hr.department', string='Parent Department', index=True)
child_ids = fields.One2many('hr.department', 'parent_id', string='Child Departments')
manager_id = fields.Many2one('hr.employee', string='Manager', track_visibility='onchange')
manager_id = fields.Many2one('hr.employee', string='Manager', tracking=True)
member_ids = fields.One2many('hr.employee', 'department_id', string='Members', readonly=True)
jobs_ids = fields.One2many('hr.job', 'department_id', string='Jobs')
note = fields.Text('Note')
+2 -2
View File
@@ -80,7 +80,7 @@ class Contract(models.Model):
resource_calendar_id = fields.Many2one(
'resource.calendar', 'Working Schedule',
default=lambda self: self.env['res.company']._company_default_get().resource_calendar_id.id)
wage = fields.Monetary('Wage', digits=(16, 2), required=True, track_visibility="onchange", help="Employee's monthly gross wage.")
wage = fields.Monetary('Wage', digits=(16, 2), required=True, tracking=True, help="Employee's monthly gross wage.")
advantages = fields.Text('Advantages')
notes = fields.Text('Notes')
state = fields.Selection([
@@ -90,7 +90,7 @@ class Contract(models.Model):
('close', 'Expired'),
('cancel', 'Cancelled')
], string='Status', group_expand='_expand_states',
track_visibility='onchange', help='Status of the contract', default='draft')
tracking=True, help='Status of the contract', default='draft')
company_id = fields.Many2one('res.company', default=lambda self: self.env.user.company_id)
currency_id = fields.Many2one(string="Currency", related='company_id.currency_id', readonly=True)
permit_no = fields.Char('Work Permit No', related="employee_id.permit_no", readonly=False)
+2 -2
View File
@@ -516,11 +516,11 @@ class HrExpenseSheet(models.Model):
('post', 'Posted'),
('done', 'Paid'),
('cancel', 'Refused')
], string='Status', index=True, readonly=True, track_visibility='onchange', copy=False, default='draft', required=True, help='Expense Report State')
], string='Status', index=True, readonly=True, tracking=True, copy=False, default='draft', required=True, help='Expense Report State')
employee_id = fields.Many2one('hr.employee', string="Employee", required=True, readonly=True, states={'draft': [('readonly', False)]}, default=lambda self: self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1))
address_id = fields.Many2one('res.partner', string="Employee Home Address")
payment_mode = fields.Selection([("own_account", "Employee (to reimburse)"), ("company_account", "Company")], related='expense_line_ids.payment_mode', default='own_account', readonly=True, string="Paid By")
user_id = fields.Many2one('res.users', 'Manager', readonly=True, copy=False, states={'draft': [('readonly', False)]}, track_visibility='onchange', oldname='responsible_id')
user_id = fields.Many2one('res.users', 'Manager', readonly=True, copy=False, states={'draft': [('readonly', False)]}, tracking=True, oldname='responsible_id')
total_amount = fields.Monetary('Total Amount', currency_field='currency_id', compute='_compute_amount', store=True, digits=dp.get_precision('Account'))
company_id = fields.Many2one('res.company', string='Company', readonly=True, states={'draft': [('readonly', False)]}, default=lambda self: self.env.user.company_id)
currency_id = fields.Many2one('res.currency', string='Currency', readonly=True, states={'draft': [('readonly', False)]}, default=lambda self: self.env.user.company_id.currency_id)
+5 -5
View File
@@ -104,7 +104,7 @@ class HolidaysRequest(models.Model):
('refuse', 'Refused'),
('validate1', 'Second Approval'),
('validate', 'Approved')
], string='Status', readonly=True, track_visibility='onchange', copy=False, default='confirm',
], string='Status', readonly=True, tracking=True, copy=False, default='confirm',
help="The status is set to 'To Submit', when a leave request is created." +
"\nThe status is 'To Approve', when leave request is confirmed by user." +
"\nThe status is 'Refused', when leave request is refused by manager." +
@@ -122,7 +122,7 @@ class HolidaysRequest(models.Model):
# HR data
employee_id = fields.Many2one(
'hr.employee', string='Employee', index=True, readonly=True,
states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}, default=_default_employee, track_visibility='onchange')
states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}, default=_default_employee, tracking=True)
manager_id = fields.Many2one('hr.employee', string='Manager', readonly=True)
department_id = fields.Many2one(
'hr.department', string='Department', readonly=True,
@@ -132,13 +132,13 @@ class HolidaysRequest(models.Model):
date_from = fields.Datetime(
'Start Date', readonly=True, index=True, copy=False, required=True,
default=fields.Datetime.now,
states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}, track_visibility='onchange')
states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}, tracking=True)
date_to = fields.Datetime(
'End Date', readonly=True, copy=False, required=True,
default=fields.Datetime.now,
states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}, track_visibility='onchange')
states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}, tracking=True)
number_of_days = fields.Float(
'Duration (Days)', copy=False, readonly=True, track_visibility='onchange',
'Duration (Days)', copy=False, readonly=True, tracking=True,
states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]},
help='Number of days of the leave request according to your working schedule.')
number_of_days_display = fields.Float(
@@ -41,29 +41,29 @@ class HolidaysAllocation(models.Model):
('refuse', 'Refused'),
('validate1', 'Second Approval'),
('validate', 'Approved')
], string='Status', readonly=True, track_visibility='onchange', copy=False, default='confirm',
], string='Status', readonly=True, tracking=True, copy=False, default='confirm',
help="The status is set to 'To Submit', when a leave request is created." +
"\nThe status is 'To Approve', when leave request is confirmed by user." +
"\nThe status is 'Refused', when leave request is refused by manager." +
"\nThe status is 'Approved', when leave request is approved by manager.")
date_from = fields.Datetime(
'Start Date', readonly=True, index=True, copy=False,
states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}, track_visibility='onchange')
states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}, tracking=True)
date_to = fields.Datetime(
'End Date', readonly=True, copy=False,
states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}, track_visibility='onchange')
states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}, tracking=True)
holiday_status_id = fields.Many2one(
"hr.leave.type", string="Leave Type", required=True, readonly=True,
states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]},
domain=[('valid', '=', True)], default=_default_holiday_status_id)
employee_id = fields.Many2one(
'hr.employee', string='Employee', index=True, readonly=True,
states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}, default=_default_employee, track_visibility='onchange')
states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}, default=_default_employee, tracking=True)
manager_id = fields.Many2one('hr.employee', string='Manager', readonly=True)
notes = fields.Text('Reasons', readonly=True, states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]})
# duration
number_of_days = fields.Float(
'Number of Days', track_visibility='onchange',
'Number of Days', tracking=True,
help='Duration in days. Reference field to use when necessary.')
number_of_days_display = fields.Float(
'Duration (days)', compute='_compute_number_of_days_display',
+2 -2
View File
@@ -6,8 +6,8 @@ from odoo import api, fields, models, tools
class MaintenanceEquipment(models.Model):
_inherit = 'maintenance.equipment'
employee_id = fields.Many2one('hr.employee', string='Assigned to Employee', track_visibility='onchange')
department_id = fields.Many2one('hr.department', string='Assigned to Department', track_visibility='onchange')
employee_id = fields.Many2one('hr.employee', string='Assigned to Employee', tracking=True)
department_id = fields.Many2one('hr.department', string='Assigned to Department', tracking=True)
equipment_assign_to = fields.Selection(
[('department', 'Department'), ('employee', 'Employee'), ('other', 'Other')],
string='Used By',
+2 -2
View File
@@ -19,8 +19,8 @@ class Job(models.Model):
manager_id = fields.Many2one(
'hr.employee', related='department_id.manager_id', string="Department Manager",
readonly=True, store=True)
user_id = fields.Many2one('res.users', "Recruitment Responsible", track_visibility='onchange')
hr_responsible_id = fields.Many2one('res.users', "HR Responsible", track_visibility='onchange',
user_id = fields.Many2one('res.users', "Recruitment Responsible", tracking=True)
hr_responsible_id = fields.Many2one('res.users', "HR Responsible", tracking=True,
help="Person responsible of validating the employee's contracts.")
document_ids = fields.One2many('ir.attachment', compute='_compute_document_ids', string="Documents")
documents_count = fields.Integer(compute='_compute_document_ids', string="Document Count")
@@ -124,7 +124,7 @@ class Applicant(models.Model):
probability = fields.Float("Probability")
partner_id = fields.Many2one('res.partner', "Contact")
create_date = fields.Datetime("Creation Date", readonly=True, index=True)
stage_id = fields.Many2one('hr.recruitment.stage', 'Stage', ondelete='restrict', track_visibility='onchange',
stage_id = fields.Many2one('hr.recruitment.stage', 'Stage', ondelete='restrict', tracking=True,
domain="['|', ('job_id', '=', False), ('job_id', '=', job_id)]",
copy=False, index=True,
group_expand='_read_group_stage_ids',
@@ -133,7 +133,7 @@ class Applicant(models.Model):
help="Stage of the applicant before being in the current stage. Used for lost cases analysis.")
categ_ids = fields.Many2many('hr.applicant.category', string="Tags")
company_id = fields.Many2one('res.company', "Company", default=_default_company_id)
user_id = fields.Many2one('res.users', "Responsible", track_visibility="onchange", default=lambda self: self.env.uid)
user_id = fields.Many2one('res.users', "Responsible", tracking=True, default=lambda self: self.env.uid)
date_closed = fields.Datetime("Closed", readonly=True, index=True)
date_open = fields.Datetime("Assigned", readonly=True, index=True)
date_last_stage_update = fields.Datetime("Last Stage Update", index=True, default=fields.Datetime.now)
@@ -154,7 +154,7 @@ class Applicant(models.Model):
day_close = fields.Float(compute='_compute_day', string="Days to Close")
delay_close = fields.Float(compute="_compute_day", string='Delay to Close', readonly=True, group_operator="avg", help="Number of days to close", store=True)
color = fields.Integer("Color Index", default=0)
emp_id = fields.Many2one('hr.employee', string="Employee", track_visibility="onchange", help="Employee linked to the applicant.")
emp_id = fields.Many2one('hr.employee', string="Employee", tracking=True, help="Employee linked to the applicant.")
user_email = fields.Char(related='user_id.email', type="char", string="User Email", readonly=True)
attachment_number = fields.Integer(compute='_get_attachment_number', string="Number of Attachments")
employee_name = fields.Char(related='emp_id.name', string="Employee Name", readonly=False)
@@ -24,7 +24,7 @@ class HrContract(models.Model):
final_yearly_costs = fields.Monetary(compute='_compute_final_yearly_costs',
readonly=False, store=True,
string="Employee Budget",
track_visibility="onchange",
tracking=True,
help="Total yearly cost of the employee for the employer.")
monthly_yearly_costs = fields.Monetary(compute='_compute_monthly_yearly_costs', string='Monthly Equivalent Cost', readonly=True,
help="Total monthly cost of the employee for the employer.")
@@ -41,41 +41,41 @@ class HrContract(models.Model):
# Advantages
commission_on_target = fields.Monetary(string="Commission on Target",
track_visibility="onchange",
tracking=True,
help="Monthly gross amount that the employee receives if the target is reached.")
fuel_card = fields.Monetary(string="Fuel Card",
track_visibility="onchange",
tracking=True,
help="Monthly amount the employee receives on his fuel card.")
internet = fields.Monetary(string="Internet",
track_visibility="onchange",
tracking=True,
help="The employee's internet subcription will be paid up to this amount.")
representation_fees = fields.Monetary(string="Representation Fees",
track_visibility="onchange",
tracking=True,
help="Monthly net amount the employee receives to cover his representation fees.")
mobile = fields.Monetary(string="Mobile",
track_visibility="onchange",
tracking=True,
help="The employee's mobile subscription will be paid up to this amount.")
mobile_plus = fields.Monetary(string="International Communication",
track_visibility="onchange",
tracking=True,
help="The employee's mobile subscription for international communication will be paid up to this amount.")
meal_voucher_amount = fields.Monetary(string="Meal Vouchers",
track_visibility="onchange",
tracking=True,
help="Amount the employee receives in the form of meal vouchers per worked day.")
holidays = fields.Float(string='Legal Leaves',
help="Number of days of paid leaves the employee gets per year.")
holidays_editable = fields.Boolean(string="Editable Leaves", default=True)
holidays_compensation = fields.Monetary(compute='_compute_holidays_compensation', string="Holidays Compensation")
wage_with_holidays = fields.Monetary(compute='_compute_wage_with_holidays', inverse='_inverse_wage_with_holidays',
track_visibility='onchange', string="Wage update with holidays retenues")
tracking=True, string="Wage update with holidays retenues")
additional_net_amount = fields.Monetary(string="Net Supplements",
track_visibility="onchange",
tracking=True,
help="Monthly net amount the employee receives.")
retained_net_amount = fields.Monetary(sting="Net Retained",
track_visibility="onchange",
tracking=True,
help="Monthly net amount that is retained on the employee's salary.")
eco_checks = fields.Monetary("Eco Vouchers",
help="Yearly amount the employee receives in the form of eco vouchers.")
ip = fields.Boolean(default=False, track_visibility="onchange")
ip = fields.Boolean(default=False, tracking=True)
ip_wage_rate = fields.Float(string="IP percentage", help="Should be between 0 and 100 %")
@api.constrains('ip_wage_rate')
@@ -13,7 +13,7 @@ class FleetVehicle(models.Model):
co2_fee = fields.Float(compute='_compute_co2_fee', string="CO2 Fee", store=True)
total_depreciated_cost = fields.Float(compute='_compute_total_depreciated_cost', store=True,
string="Total Cost (Depreciated)", track_visibility="onchange",
string="Total Cost (Depreciated)", tracking=True,
help="This includes all the depreciated costs and the CO2 fee")
total_cost = fields.Float(compute='_compute_total_cost', string="Total Cost", help="This include all the costs and the CO2 fee")
fuel_type = fields.Selection(required=True, default='diesel')
@@ -131,7 +131,7 @@ class FleetVehicle(models.Model):
class FleetVehicleLogContract(models.Model):
_inherit = 'fleet.vehicle.log.contract'
recurring_cost_amount_depreciated = fields.Float("Recurring Cost Amount (depreciated)", track_visibility="onchange")
recurring_cost_amount_depreciated = fields.Float("Recurring Cost Amount (depreciated)", tracking=True)
class FleetVehicleModel(models.Model):
@@ -9,7 +9,7 @@ class HrContract(models.Model):
car_id = fields.Many2one('fleet.vehicle', string='Company Car',
default=lambda self: self.env['fleet.vehicle'].search([('driver_id', '=', self.employee_id.address_home_id.id)], limit=1),
track_visibility="onchange",
tracking=True,
help="Employee's company car.")
car_atn = fields.Float(compute='_compute_car_atn_and_costs', string='ATN Company Car', store=True)
company_car_total_depreciated_cost = fields.Float(compute='_compute_car_atn_and_costs', store=True)
+2 -2
View File
@@ -17,8 +17,8 @@ class MailBlackList(models.Model):
_rec_name = 'email'
email = fields.Char(string='Email Address', required=True, index=True, help='This field is case insensitive.',
track_visibility=True)
active = fields.Boolean(default=True, track_visibility=True)
tracking=True)
active = fields.Boolean(default=True, tracking=True)
_sql_constraints = [
('unique_email', 'unique (email)', 'Email address already exists!')
+9 -9
View File
@@ -33,7 +33,7 @@ class MaintenanceEquipmentCategory(models.Model):
name = fields.Char('Category Name', required=True, translate=True)
company_id = fields.Many2one('res.company', string='Company',
default=lambda self: self.env.user.company_id)
technician_user_id = fields.Many2one('res.users', 'Responsible', track_visibility='onchange', default=lambda self: self.env.uid, oldname='user_id')
technician_user_id = fields.Many2one('res.users', 'Responsible', tracking=True, default=lambda self: self.env.uid, oldname='user_id')
color = fields.Integer('Color Index')
note = fields.Text('Comments', translate=True)
equipment_ids = fields.One2many('maintenance.equipment', 'category_id', string='Equipments', copy=False)
@@ -125,16 +125,16 @@ class MaintenanceEquipment(models.Model):
company_id = fields.Many2one('res.company', string='Company',
default=lambda self: self.env.user.company_id)
active = fields.Boolean(default=True)
technician_user_id = fields.Many2one('res.users', string='Technician', track_visibility='onchange', oldname='user_id')
owner_user_id = fields.Many2one('res.users', string='Owner', track_visibility='onchange')
technician_user_id = fields.Many2one('res.users', string='Technician', tracking=True, oldname='user_id')
owner_user_id = fields.Many2one('res.users', string='Owner', tracking=True)
category_id = fields.Many2one('maintenance.equipment.category', string='Equipment Category',
track_visibility='onchange', group_expand='_read_group_category_ids')
tracking=True, group_expand='_read_group_category_ids')
partner_id = fields.Many2one('res.partner', string='Vendor', domain="[('supplier', '=', 1)]")
partner_ref = fields.Char('Vendor Reference')
location = fields.Char('Location')
model = fields.Char('Model')
serial_no = fields.Char('Serial Number', copy=False)
assign_date = fields.Date('Assigned Date', track_visibility='onchange')
assign_date = fields.Date('Assigned Date', tracking=True)
effective_date = fields.Date('Effective Date', default=fields.Date.context_today, required=True, help="Date at which the equipment became effective. This date will be used to compute the Mean Time Between Failure.")
cost = fields.Float('Cost')
note = fields.Text('Note')
@@ -283,20 +283,20 @@ class MaintenanceRequest(models.Model):
company_id = fields.Many2one('res.company', string='Company',
default=lambda self: self.env.user.company_id)
description = fields.Text('Description')
request_date = fields.Date('Request Date', track_visibility='onchange', default=fields.Date.context_today,
request_date = fields.Date('Request Date', tracking=True, default=fields.Date.context_today,
help="Date requested for the maintenance to happen")
owner_user_id = fields.Many2one('res.users', string='Created by User', default=lambda s: s.env.uid)
category_id = fields.Many2one('maintenance.equipment.category', related='equipment_id.category_id', string='Category', store=True, readonly=True)
equipment_id = fields.Many2one('maintenance.equipment', string='Equipment',
ondelete='restrict', index=True)
user_id = fields.Many2one('res.users', string='Technician', track_visibility='onchange', oldname='technician_user_id')
stage_id = fields.Many2one('maintenance.stage', string='Stage', ondelete='restrict', track_visibility='onchange',
user_id = fields.Many2one('res.users', string='Technician', tracking=True, oldname='technician_user_id')
stage_id = fields.Many2one('maintenance.stage', string='Stage', ondelete='restrict', tracking=True,
group_expand='_read_group_stage_ids', default=_default_stage)
priority = fields.Selection([('0', 'Very Low'), ('1', 'Low'), ('2', 'Normal'), ('3', 'High')], string='Priority')
color = fields.Integer('Color Index')
close_date = fields.Date('Close Date', help="Date the maintenance was finished. ")
kanban_state = fields.Selection([('normal', 'In Progress'), ('blocked', 'Blocked'), ('done', 'Ready for next stage')],
string='Kanban State', required=True, default='normal', track_visibility='onchange')
string='Kanban State', required=True, default='normal', tracking=True)
# active = fields.Boolean(default=True, help="Set active to false to hide the maintenance request without deleting it.")
archive = fields.Boolean(default=False, help="Set archive to true to hide the maintenance request without deleting it.")
maintenance_type = fields.Selection([('corrective', 'Corrective'), ('preventive', 'Preventive')], string='Maintenance Type', default="corrective")
+3 -3
View File
@@ -56,7 +56,7 @@ class MrpProduction(models.Model):
product_qty = fields.Float(
'Quantity To Produce',
default=1.0, digits=dp.get_precision('Product Unit of Measure'),
readonly=True, required=True, track_visibility='onchange',
readonly=True, required=True, tracking=True,
states={'draft': [('readonly', False)]})
product_uom_id = fields.Many2one(
'uom.uom', 'Product Unit of Measure',
@@ -108,7 +108,7 @@ class MrpProduction(models.Model):
('done', 'Done'),
('cancel', 'Cancelled')], string='State',
compute='_compute_state', copy=False, index=True, readonly=True,
store=True, track_visibility='onchange',
store=True, tracking=True,
help=" * Draft: The MO is not confirmed yet.\n"
" * Confirmed: The MO is confirmed, the stock rules and the reordering of the components are trigerred.\n"
" * Planned: The WO are planned.\n"
@@ -122,7 +122,7 @@ class MrpProduction(models.Model):
('waiting', 'Waiting Another Operation')],
string='Material Availability',
compute='_compute_state', copy=False, index=True, readonly=True,
store=True, track_visibility='onchange', oldname='availability',
store=True, tracking=True, oldname='availability',
help=" * Ready: The material is available to start the production.\n\
* Waiting: The material is not available to start the production.\n\
The material availability is impacted by the manufacturing readiness\
+1 -1
View File
@@ -28,7 +28,7 @@ class MrpWorkorder(models.Model):
production_id = fields.Many2one(
'mrp.production', 'Manufacturing Order',
index=True, ondelete='cascade', required=True, track_visibility='onchange',
index=True, ondelete='cascade', required=True, tracking=True,
states={'done': [('readonly', True)], 'cancel': [('readonly', True)]})
product_id = fields.Many2one(
'product.product', 'Product',
+1 -1
View File
@@ -579,7 +579,7 @@ class PaymentTransaction(models.Model):
help='Internal reference of the TX')
acquirer_reference = fields.Char(string='Acquirer Reference', readonly=True, help='Reference of the TX as stored in the acquirer database')
# duplicate partner / transaction data to store the values at transaction time
partner_id = fields.Many2one('res.partner', 'Customer', track_visibility='onchange')
partner_id = fields.Many2one('res.partner', 'Customer', tracking=True)
partner_name = fields.Char('Partner Name')
partner_lang = fields.Selection(_lang_get, 'Language', default=lambda self: self.env.lang)
partner_email = fields.Char('Email')
+11 -11
View File
@@ -173,11 +173,11 @@ class Project(models.Model):
def _get_default_favorite_user_ids(self):
return [(6, 0, [self.env.uid])]
name = fields.Char("Name", index=True, required=True, track_visibility='onchange')
name = fields.Char("Name", index=True, required=True, tracking=True)
active = fields.Boolean(default=True,
help="If the active field is set to False, it will allow you to hide the project without removing it.")
sequence = fields.Integer(default=10, help="Gives the sequence order when displaying a list of Projects.")
partner_id = fields.Many2one('res.partner', string='Customer', auto_join=True, track_visibility='onchange')
partner_id = fields.Many2one('res.partner', string='Customer', auto_join=True, tracking=True)
company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env.user.company_id)
currency_id = fields.Many2one('res.currency', related="company_id.currency_id", string="Currency", readonly=True)
@@ -198,7 +198,7 @@ class Project(models.Model):
task_ids = fields.One2many('project.task', 'project_id', string='Tasks',
domain=['|', ('stage_id.fold', '=', False), ('stage_id', '=', False)])
color = fields.Integer(string='Color Index')
user_id = fields.Many2one('res.users', string='Project Manager', default=lambda self: self.env.user, track_visibility="onchange")
user_id = fields.Many2one('res.users', string='Project Manager', default=lambda self: self.env.user, tracking=True)
alias_id = fields.Many2one('mail.alias', string='Alias', ondelete="restrict", required=True,
help="Internal email associated with this project. Incoming emails are automatically synchronized "
"with Tasks (or optionally Issues if the Issue Tracker module is installed).")
@@ -217,7 +217,7 @@ class Project(models.Model):
" them or by someone of their company.")
doc_count = fields.Integer(compute='_compute_attached_docs_count', string="Number of documents attached")
date_start = fields.Date(string='Start Date')
date = fields.Date(string='Expiration Date', index=True, track_visibility='onchange')
date = fields.Date(string='Expiration Date', index=True, tracking=True)
subtask_project_id = fields.Many2one('project.project', string='Sub-task Project', ondelete="restrict",
help="Project in which sub-tasks of the current project will be created. It can be the current project itself.")
@@ -425,7 +425,7 @@ class Task(models.Model):
return stages.browse(stage_ids)
active = fields.Boolean(default=True)
name = fields.Char(string='Title', track_visibility='always', required=True, index=True)
name = fields.Char(string='Title', tracking=True, required=True, index=True)
description = fields.Html(string='Description')
priority = fields.Selection([
('0', 'Low'),
@@ -433,7 +433,7 @@ class Task(models.Model):
], default='0', index=True, string="Priority")
sequence = fields.Integer(string='Sequence', index=True, default=10,
help="Gives the sequence order when displaying a list of tasks.")
stage_id = fields.Many2one('project.task.type', string='Stage', ondelete='restrict', track_visibility='onchange', index=True,
stage_id = fields.Many2one('project.task.type', string='Stage', ondelete='restrict', tracking=True, index=True,
default=_get_default_stage_id, group_expand='_read_group_stage_ids',
domain="[('project_ids', '=', project_id)]", copy=False)
tag_ids = fields.Many2many('project.tags', string='Tags', oldname='categ_ids')
@@ -442,7 +442,7 @@ class Task(models.Model):
('done', 'Green'),
('blocked', 'Red')], string='Kanban State',
copy=False, default='normal', required=True)
kanban_state_label = fields.Char(compute='_compute_kanban_state_label', string='Kanban State Label', track_visibility='onchange')
kanban_state_label = fields.Char(compute='_compute_kanban_state_label', string='Kanban State Label', tracking=True)
create_date = fields.Datetime("Created On", readonly=True, index=True)
write_date = fields.Datetime("Last Updated On", readonly=True, index=True)
date_start = fields.Datetime(string='Starting Date',
@@ -450,7 +450,7 @@ class Task(models.Model):
index=True, copy=False)
date_end = fields.Datetime(string='Ending Date', index=True, copy=False)
date_assign = fields.Datetime(string='Assigning Date', index=True, copy=False, readonly=True)
date_deadline = fields.Date(string='Deadline', index=True, copy=False, track_visibility='onchange')
date_deadline = fields.Date(string='Deadline', index=True, copy=False, tracking=True)
date_last_stage_update = fields.Datetime(string='Last Stage Update',
default=fields.Datetime.now,
index=True,
@@ -460,15 +460,15 @@ class Task(models.Model):
string='Project',
default=lambda self: self.env.context.get('default_project_id'),
index=True,
track_visibility='onchange',
tracking=True,
change_default=True)
notes = fields.Text(string='Notes')
planned_hours = fields.Float("Planned Hours", help='It is the time planned to achieve the task. If this document has sub-tasks, it means the time needed to achieve this tasks and its childs.',track_visibility='onchange')
planned_hours = fields.Float("Planned Hours", help='It is the time planned to achieve the task. If this document has sub-tasks, it means the time needed to achieve this tasks and its childs.',tracking=True)
subtask_planned_hours = fields.Float("Subtasks", compute='_compute_subtask_planned_hours', help="Computed using sum of hours planned of all subtasks created from main task. Usually these hours are less or equal to the Planned Hours (of main task).")
user_id = fields.Many2one('res.users',
string='Assigned to',
default=lambda self: self.env.uid,
index=True, track_visibility='always')
index=True, tracking=True)
partner_id = fields.Many2one('res.partner',
string='Customer',
default=lambda self: self._get_default_partner())
+4 -4
View File
@@ -85,7 +85,7 @@ class PurchaseOrder(models.Model):
date_order = fields.Datetime('Order Date', required=True, states=READONLY_STATES, index=True, copy=False, default=fields.Datetime.now,\
help="Depicts the date where the Quotation should be validated and converted into a purchase order.")
date_approve = fields.Date('Confirmation Date', readonly=1, index=True, copy=False)
partner_id = fields.Many2one('res.partner', string='Vendor', required=True, states=READONLY_STATES, change_default=True, track_visibility='always', help="You can find a vendor by its Name, TIN, Email or Internal Reference.")
partner_id = fields.Many2one('res.partner', string='Vendor', required=True, states=READONLY_STATES, change_default=True, tracking=True, help="You can find a vendor by its Name, TIN, Email or Internal Reference.")
dest_address_id = fields.Many2one('res.partner', string='Drop Ship Address', states=READONLY_STATES,
help="Put an address if you want to deliver directly from the vendor to the customer. "
"Otherwise, keep empty to deliver to your own company.")
@@ -98,7 +98,7 @@ class PurchaseOrder(models.Model):
('purchase', 'Purchase Order'),
('done', 'Locked'),
('cancel', 'Cancelled')
], string='Status', readonly=True, index=True, copy=False, default='draft', track_visibility='onchange')
], string='Status', readonly=True, index=True, copy=False, default='draft', tracking=True)
order_line = fields.One2many('purchase.order.line', 'order_id', string='Order Lines', states={'cancel': [('readonly', True)], 'done': [('readonly', True)]}, copy=True)
notes = fields.Text('Terms and Conditions')
@@ -113,7 +113,7 @@ class PurchaseOrder(models.Model):
# There is no inverse function on purpose since the date may be different on each line
date_planned = fields.Datetime(string='Scheduled Date', compute='_compute_date_planned', store=True, index=True)
amount_untaxed = fields.Monetary(string='Untaxed Amount', store=True, readonly=True, compute='_amount_all', track_visibility='always')
amount_untaxed = fields.Monetary(string='Untaxed Amount', store=True, readonly=True, compute='_amount_all', tracking=True)
amount_tax = fields.Monetary(string='Taxes', store=True, readonly=True, compute='_amount_all')
amount_total = fields.Monetary(string='Total', store=True, readonly=True, compute='_amount_all')
@@ -122,7 +122,7 @@ class PurchaseOrder(models.Model):
incoterm_id = fields.Many2one('account.incoterms', 'Incoterm', states={'done': [('readonly', True)]}, help="International Commercial Terms are a series of predefined commercial terms used in international transactions.")
product_id = fields.Many2one('product.product', related='order_line.product_id', string='Product', readonly=False)
user_id = fields.Many2one('res.users', string='Purchase Representative', index=True, track_visibility='onchange', default=lambda self: self.env.user)
user_id = fields.Many2one('res.users', string='Purchase Representative', index=True, tracking=True, default=lambda self: self.env.user)
company_id = fields.Many2one('res.company', 'Company', required=True, index=True, states=READONLY_STATES, default=lambda self: self.env.user.company_id.id)
def _compute_access_url(self):
@@ -61,9 +61,9 @@ class PurchaseRequisition(models.Model):
order_count = fields.Integer(compute='_compute_orders_number', string='Number of Orders')
vendor_id = fields.Many2one('res.partner', string="Vendor")
type_id = fields.Many2one('purchase.requisition.type', string="Agreement Type", required=True, default=_get_type_id)
ordering_date = fields.Date(string="Ordering Date", track_visibility='onchange')
date_end = fields.Datetime(string='Agreement Deadline', track_visibility='onchange')
schedule_date = fields.Date(string='Delivery Date', index=True, help="The expected and scheduled delivery date where all the products are received", track_visibility='onchange')
ordering_date = fields.Date(string="Ordering Date", tracking=True)
date_end = fields.Datetime(string='Agreement Deadline', tracking=True)
schedule_date = fields.Date(string='Delivery Date', index=True, help="The expected and scheduled delivery date where all the products are received", tracking=True)
user_id = fields.Many2one('res.users', string='Purchase Representative', default= lambda self: self.env.user)
description = fields.Text()
company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env['res.company']._company_default_get('purchase.requisition'))
@@ -71,7 +71,7 @@ class PurchaseRequisition(models.Model):
line_ids = fields.One2many('purchase.requisition.line', 'requisition_id', string='Products to Purchase', states={'done': [('readonly', True)]}, copy=True)
warehouse_id = fields.Many2one('stock.warehouse', string='Warehouse')
state = fields.Selection(PURCHASE_REQUISITION_STATES,
'Status', track_visibility='onchange', required=True,
'Status', tracking=True, required=True,
copy=False, default='draft')
state_blanket_order = fields.Selection(PURCHASE_REQUISITION_STATES, compute='_set_state')
picking_type_id = fields.Many2one('stock.picking.type', 'Operation Type', required=True, default=_get_picking_in)
+3 -3
View File
@@ -61,7 +61,7 @@ class Repair(models.Model):
('2binvoiced', 'To be Invoiced'),
('invoice_except', 'Invoice Exception'),
('done', 'Repaired')], string='Status',
copy=False, default='draft', readonly=True, track_visibility='onchange',
copy=False, default='draft', readonly=True, tracking=True,
help="* The \'Draft\' status is used when a user is encoding a new and unconfirmed repair order.\n"
"* The \'Confirmed\' status is used when a user confirms the repair order.\n"
"* The \'Ready to Repair\' status is used to start to repairing, user can start repairing only after repair order is confirmed.\n"
@@ -96,10 +96,10 @@ class Repair(models.Model):
help='Selecting \'Before Repair\' or \'After Repair\' will allow you to generate invoice before or after the repair is done respectively. \'No invoice\' means you don\'t want to generate invoice for this repair order.')
invoice_id = fields.Many2one(
'account.invoice', 'Invoice',
copy=False, readonly=True, track_visibility="onchange")
copy=False, readonly=True, tracking=True)
move_id = fields.Many2one(
'stock.move', 'Move',
copy=False, readonly=True, track_visibility="onchange",
copy=False, readonly=True, tracking=True,
help="Move created by the repair order")
fees_lines = fields.One2many(
'repair.fee', 'repair_id', 'Operations',
+1 -1
View File
@@ -439,7 +439,7 @@ class ResourceResource(models.Model):
name = fields.Char(required=True)
active = fields.Boolean(
'Active', default=True, track_visibility='onchange',
'Active', default=True, tracking=True,
help="If the active field is set to False, it will allow you to hide the resource record without removing it.")
company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env['res.company']._company_default_get())
resource_type = fields.Selection([
+5 -5
View File
@@ -129,7 +129,7 @@ class SaleOrder(models.Model):
('sale', 'Sales Order'),
('done', 'Locked'),
('cancel', 'Cancelled'),
], string='Status', readonly=True, copy=False, index=True, track_visibility='onchange', track_sequence=3, default='draft')
], string='Status', readonly=True, copy=False, index=True, tracking=3, default='draft')
date_order = fields.Datetime(string='Order Date', required=True, readonly=True, index=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, copy=False, default=fields.Datetime.now)
validity_date = fields.Date(string='Expiration', readonly=True, copy=False, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]},
help="Expiration date of the quotation, after this date, the customer won't be able to validate the quotation online.", default=_default_validity_date)
@@ -143,8 +143,8 @@ class SaleOrder(models.Model):
remaining_validity_days = fields.Integer(compute='_compute_remaining_validity_days', string="Remaining Days Before Expiration")
create_date = fields.Datetime(string='Creation Date', readonly=True, index=True, help="Date on which sales order is created.")
confirmation_date = fields.Datetime(string='Confirmation Date', readonly=True, index=True, help="Date on which the sales order is confirmed.", oldname="date_confirm", copy=False)
user_id = fields.Many2one('res.users', string='Salesperson', index=True, track_visibility='onchange', track_sequence=2, default=lambda self: self.env.user)
partner_id = fields.Many2one('res.partner', string='Customer', readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, required=True, change_default=True, index=True, track_visibility='always', track_sequence=1, help="You can find a customer by its Name, TIN, Email or Internal Reference.")
user_id = fields.Many2one('res.users', string='Salesperson', index=True, tracking=2, default=lambda self: self.env.user)
partner_id = fields.Many2one('res.partner', string='Customer', readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, required=True, change_default=True, index=True, tracking=1, help="You can find a customer by its Name, TIN, Email or Internal Reference.")
partner_invoice_id = fields.Many2one('res.partner', string='Invoice Address', readonly=True, required=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)], 'sale': [('readonly', False)]}, help="Invoice address for current sales order.")
partner_shipping_id = fields.Many2one('res.partner', string='Delivery Address', readonly=True, required=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)], 'sale': [('readonly', False)]}, help="Delivery address for current sales order.")
@@ -165,10 +165,10 @@ class SaleOrder(models.Model):
note = fields.Text('Terms and conditions', default=_default_note)
amount_untaxed = fields.Monetary(string='Untaxed Amount', store=True, readonly=True, compute='_amount_all', track_visibility='onchange', track_sequence=5)
amount_untaxed = fields.Monetary(string='Untaxed Amount', store=True, readonly=True, compute='_amount_all', tracking=5)
amount_by_group = fields.Binary(string="Tax amount by group", compute='_amount_by_group', help="type: [(name, amount, base, formated amount, formated base)]")
amount_tax = fields.Monetary(string='Taxes', store=True, readonly=True, compute='_amount_all')
amount_total = fields.Monetary(string='Total', store=True, readonly=True, compute='_amount_all', track_visibility='always', track_sequence=6)
amount_total = fields.Monetary(string='Total', store=True, readonly=True, compute='_amount_all', tracking=4)
currency_rate = fields.Float("Currency Rate", compute='_compute_currency_rate', compute_sudo=True, store=True, digits=(12, 6), readonly=True, help='The rate of the currency to the currency of rate 1 applicable at the date of the order')
payment_term_id = fields.Many2one('account.payment.term', string='Payment Terms', oldname='payment_term')
+4 -4
View File
@@ -199,7 +199,7 @@ class Picking(models.Model):
('done', 'Done'),
('cancel', 'Cancelled'),
], string='Status', compute='_compute_state',
copy=False, index=True, readonly=True, store=True, track_visibility='onchange',
copy=False, index=True, readonly=True, store=True, tracking=True,
help=" * Draft: The transfer is not confirmed yet. Reservation doesn't apply.\n"
" * Waiting another operation: This transfer is waiting for another operation before being ready.\n"
" * Waiting: The transfer is waiting for the availability of some products.\n(a) The shipping policy is \"As soon as possible\": no product could be reserved.\n(b) The shipping policy is \"When all products are ready\": not all the products could be reserved.\n"
@@ -215,16 +215,16 @@ class Picking(models.Model):
PROCUREMENT_PRIORITIES, string='Priority',
compute='_compute_priority', inverse='_set_priority', store=True,
# default='1', required=True, # TDE: required, depending on moves ? strange
index=True, track_visibility='onchange',
index=True, tracking=True,
states={'done': [('readonly', True)], 'cancel': [('readonly', True)]},
help="Priority for this picking. Setting manually a value here would set it as priority for all the moves")
scheduled_date = fields.Datetime(
'Scheduled Date', compute='_compute_scheduled_date', inverse='_set_scheduled_date', store=True,
index=True, track_visibility='onchange',
index=True, tracking=True,
help="Scheduled time for the first part of the shipment to be processed. Setting manually a value here would set it as expected date for all the stock moves.")
date = fields.Datetime(
'Creation Date',
default=fields.Datetime.now, index=True, track_visibility='onchange',
default=fields.Datetime.now, index=True, tracking=True,
states={'done': [('readonly', True)], 'cancel': [('readonly', True)]},
help="Creation Date, usually the time of the order")
date_done = fields.Datetime('Date of Transfer', copy=False, readonly=True, help="Date at which the transfer has been processed or cancelled.")
@@ -22,10 +22,10 @@ class LandedCost(models.Model):
name = fields.Char(
'Name', default=lambda self: _('New'),
copy=False, readonly=True, track_visibility='always')
copy=False, readonly=True, tracking=True)
date = fields.Date(
'Date', default=fields.Date.context_today,
copy=False, required=True, states={'done': [('readonly', True)]}, track_visibility='onchange')
copy=False, required=True, states={'done': [('readonly', True)]}, tracking=True)
picking_ids = fields.Many2many(
'stock.picking', string='Transfers',
copy=False, states={'done': [('readonly', True)]})
@@ -39,12 +39,12 @@ class LandedCost(models.Model):
'Item Description', states={'done': [('readonly', True)]})
amount_total = fields.Float(
'Total', compute='_compute_total_amount',
digits=0, store=True, track_visibility='always')
digits=0, store=True, tracking=True)
state = fields.Selection([
('draft', 'Draft'),
('done', 'Posted'),
('cancel', 'Cancelled')], 'State', default='draft',
copy=False, readonly=True, track_visibility='onchange')
copy=False, readonly=True, tracking=True)
account_move_id = fields.Many2one(
'account.move', 'Journal Entry',
copy=False, readonly=True)
@@ -16,7 +16,7 @@ class StockPickingBatch(models.Model):
copy=False, required=True,
help='Name of the batch picking')
user_id = fields.Many2one(
'res.users', string='Responsible', track_visibility='onchange',
'res.users', string='Responsible', tracking=True,
help='Person responsible for this batch picking')
picking_ids = fields.One2many(
'stock.picking', 'batch_id', string='Pickings',
@@ -26,7 +26,7 @@ class StockPickingBatch(models.Model):
('in_progress', 'Running'),
('done', 'Done'),
('cancel', 'Cancelled')], default='draft',
copy=False, track_visibility='onchange', required=True)
copy=False, tracking=True, required=True)
@api.model
def create(self, vals):
+7 -7
View File
@@ -24,8 +24,8 @@ class MailTestStandard(models.Model):
name = fields.Char()
email_from = fields.Char()
user_id = fields.Many2one('res.users', 'Responsible', track_visibility='onchange')
umbrella_id = fields.Many2one('mail.test', track_visibility='onchange')
user_id = fields.Many2one('res.users', 'Responsible', tracking=True)
umbrella_id = fields.Many2one('mail.test', tracking=True)
class MailTestActivity(models.Model):
@@ -57,13 +57,13 @@ class MailTestFull(models.Model):
_inherit = ['mail.thread']
name = fields.Char()
email_from = fields.Char(track_visibility='always')
email_from = fields.Char(tracking=True)
count = fields.Integer(default=1)
datetime = fields.Datetime(default=fields.Datetime.now)
mail_template = fields.Many2one('mail.template', 'Template')
customer_id = fields.Many2one('res.partner', 'Customer', track_visibility='onchange', track_sequence=2)
user_id = fields.Many2one('res.users', 'Responsible', track_visibility='onchange', track_sequence=1)
umbrella_id = fields.Many2one('mail.test', track_visibility='onchange')
customer_id = fields.Many2one('res.partner', 'Customer', tracking=2)
user_id = fields.Many2one('res.users', 'Responsible', tracking=1)
umbrella_id = fields.Many2one('mail.test', tracking=True)
def _track_template(self, tracking):
res = super(MailTestFull, self)._track_template(tracking)
@@ -116,7 +116,7 @@ class MailModel(models.Model):
name = fields.Char()
value = fields.Integer()
value_pc = fields.Float(compute="_value_pc", store=True)
track = fields.Char(default='test', track_visibility="onchange")
track = fields.Char(default='test', tracking=True)
partner_id = fields.Many2one('res.partner', string='Customer')
@api.depends('value')
+5 -5
View File
@@ -117,8 +117,8 @@ class TestTracking(common.BaseFunctionalTest, common.MockEmails):
[('customer_id', 'many2one', False, self.user_admin.partner_id) # onchange tracked field
])
def test_message_track_sequence(self):
""" Update some tracked fields and check that the mail.tracking.value are ordered according to their track_sequence"""
def test_message_tracking_sequence(self):
""" Update some tracked fields and check that the mail.tracking.value are ordered according to their tracking_sequence"""
self.record.write({
'name': 'Zboub',
'customer_id': self.user_admin.partner_id.id,
@@ -128,6 +128,6 @@ class TestTracking(common.BaseFunctionalTest, common.MockEmails):
self.assertEqual(len(self.record.message_ids), 1, 'should have 1 tracking message')
tracking_values = self.env['mail.tracking.value'].search([('mail_message_id', '=', self.record.message_ids.id)])
self.assertEqual(tracking_values[0].track_sequence, 1)
self.assertEqual(tracking_values[1].track_sequence, 2)
self.assertEqual(tracking_values[2].track_sequence, 100)
self.assertEqual(tracking_values[0].tracking_sequence, 1)
self.assertEqual(tracking_values[1].tracking_sequence, 2)
self.assertEqual(tracking_values[2].tracking_sequence, 100)
@@ -28,7 +28,7 @@ class MassMailTestBlacklist(models.Model):
email_from = fields.Char()
user_id = fields.Many2one(
'res.users', 'Responsible',
track_visibility='onchange')
tracking=True)
umbrella_id = fields.Many2one(
'mail.test', 'Meta Umbrella Record',
track_visibility='onchange')
tracking=True)
@@ -11,7 +11,7 @@ class CrmLead(models.Model):
_inherit = "crm.lead"
partner_latitude = fields.Float('Geo Latitude', digits=(16, 5))
partner_longitude = fields.Float('Geo Longitude', digits=(16, 5))
partner_assigned_id = fields.Many2one('res.partner', 'Assigned Partner', track_visibility='onchange', help="Partner this case has been forwarded/assigned to.", index=True)
partner_assigned_id = fields.Many2one('res.partner', 'Assigned Partner', tracking=True, help="Partner this case has been forwarded/assigned to.", index=True)
partner_declined_ids = fields.Many2many(
'res.partner',
'crm_lead_declined_partner',
@@ -36,11 +36,11 @@ class ResPartnerActivation(models.Model):
class ResPartner(models.Model):
_inherit = "res.partner"
partner_weight = fields.Integer('Level Weight', default=0, track_visibility='onchange',
partner_weight = fields.Integer('Level Weight', default=0, tracking=True,
help="This should be a numerical value greater than 0 which will decide the contention for this partner to take this lead/opportunity.")
grade_id = fields.Many2one('res.partner.grade', 'Level', track_visibility='onchange')
grade_id = fields.Many2one('res.partner.grade', 'Level', tracking=True)
grade_sequence = fields.Integer(related='grade_id.sequence', readonly=True, store=True)
activation = fields.Many2one('res.partner.activation', 'Activation', index=True, track_visibility='onchange')
activation = fields.Many2one('res.partner.activation', 'Activation', index=True, tracking=True)
date_partnership = fields.Date('Partnership Date')
date_review = fields.Date('Latest Partner Review')
date_review_next = fields.Date('Next Partner Review')
+1 -1
View File
@@ -22,7 +22,7 @@ class Event(models.Model):
_name = 'event.event'
_inherit = ['event.event', 'website.seo.metadata', 'website.published.multi.mixin']
is_published = fields.Boolean(track_visibility='onchange')
is_published = fields.Boolean(tracking=True)
is_participating = fields.Boolean("Is Participating", compute="_compute_is_participating")
@@ -57,7 +57,7 @@ class Track(models.Model):
name = fields.Char('Title', required=True, translate=True)
active = fields.Boolean(default=True)
user_id = fields.Many2one('res.users', 'Responsible', track_visibility='onchange', default=lambda self: self.env.user)
user_id = fields.Many2one('res.users', 'Responsible', tracking=True, default=lambda self: self.env.user)
partner_id = fields.Many2one('res.partner', 'Speaker')
partner_name = fields.Char('Speaker Name')
partner_email = fields.Char('Speaker Email')
@@ -68,12 +68,12 @@ class Track(models.Model):
'event.track.stage', string='Stage', ondelete='restrict',
index=True, copy=False, default=_get_default_stage_id,
group_expand='_read_group_stage_ids',
required=True, track_visibility='onchange')
required=True, tracking=True)
kanban_state = fields.Selection([
('normal', 'Grey'),
('done', 'Green'),
('blocked', 'Red')], string='Kanban State',
copy=False, default='normal', required=True, track_visibility='onchange',
copy=False, default='normal', required=True, tracking=True,
help="A track's kanban state indicates special situations affecting it:\n"
" * Grey is the default situation\n"
" * Red indicates something is preventing the progress of this track\n"
@@ -13,7 +13,7 @@ class SaleOrder(models.Model):
amount_delivery = fields.Monetary(
compute='_compute_amount_delivery', digits=0,
string='Delivery Amount',
help="The amount without tax.", store=True, track_visibility='always')
help="The amount without tax.", store=True, tracking=True)
has_delivery = fields.Boolean(
compute='_compute_has_delivery', string='Has delivery',
help="Has an order line set for delivery", store=True)