diff --git a/addons/account/models/account.py b/addons/account/models/account.py index 6f1e1f101b7525e3416924eb9182aa254a46ff2a..3818a98d1a18c7047b804002dbf5e9e11d817d7b 100644 --- a/addons/account/models/account.py +++ b/addons/account/models/account.py @@ -465,14 +465,14 @@ class AccountJournal(models.Model): company_partner_id = fields.Many2one('res.partner', related='company_id.partner_id', string='Account Holder', readonly=True, store=False) bank_account_id = fields.Many2one('res.partner.bank', string="Bank Account", ondelete='restrict', copy=False, domain="[('partner_id','=', company_partner_id)]") bank_statements_source = fields.Selection(selection=_get_bank_statements_available_sources, string='Bank Feeds', default='undefined', help="Defines how the bank statements will be registered") - bank_acc_number = fields.Char(related='bank_account_id.acc_number') - bank_id = fields.Many2one('res.bank', related='bank_account_id.bank_id') + bank_acc_number = fields.Char(related='bank_account_id.acc_number', readonly=False) + bank_id = fields.Many2one('res.bank', related='bank_account_id.bank_id', readonly=False) post_at_bank_rec = fields.Boolean(string="Post At Bank Reconciliation", help="Whether or not the payments made in this journal should be generated in draft state, so that the related journal entries are only posted when performing bank reconciliation.") # alias configuration for 'purchase' type journals alias_id = fields.Many2one('mail.alias', string='Alias') alias_domain = fields.Char('Alias domain', compute='_compute_alias_domain', default=lambda self: self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain")) - alias_name = fields.Char('Alias Name for Vendor Bills', related='alias_id.alias_name', help="It creates draft vendor bill by sending an email.") + alias_name = fields.Char('Alias Name for Vendor Bills', related='alias_id.alias_name', help="It creates draft vendor bill by sending an email.", readonly=False) _sql_constraints = [ ('code_company_uniq', 'unique (code, name, company_id)', 'The code and name of the journal must be unique per company !'), diff --git a/addons/account/models/account_bank_statement.py b/addons/account/models/account_bank_statement.py index e899374d0c8f0da2a254540ef6e13f08318e0f02..f1758d9a92bf22ac7d7e3d686edae5020f3a2d43 100644 --- a/addons/account/models/account_bank_statement.py +++ b/addons/account/models/account_bank_statement.py @@ -143,7 +143,7 @@ class AccountBankStatement(models.Model): state = fields.Selection([('open', 'New'), ('confirm', 'Validated')], string='Status', required=True, readonly=True, copy=False, default='open') currency_id = fields.Many2one('res.currency', compute='_compute_currency', oldname='currency', string="Currency") journal_id = fields.Many2one('account.journal', string='Journal', required=True, states={'confirm': [('readonly', True)]}, default=_default_journal) - journal_type = fields.Selection(related='journal_id.type', help="Technical field used for usability purposes") + journal_type = fields.Selection(related='journal_id.type', help="Technical field used for usability purposes", readonly=False) company_id = fields.Many2one('res.company', related='journal_id.company_id', string='Company', store=True, readonly=True, default=lambda self: self.env['res.company']._company_default_get('account.bank.statement')) diff --git a/addons/account/models/account_invoice.py b/addons/account/models/account_invoice.py index 0d92a946f79f384f993ae6d13739439ae90cc9e4..fa1dc45f4598379318634afb4bf818e619369775 100644 --- a/addons/account/models/account_invoice.py +++ b/addons/account/models/account_invoice.py @@ -1575,7 +1575,7 @@ class AccountInvoiceLine(models.Model): ondelete='set null', index=True, oldname='uos_id') product_id = fields.Many2one('product.product', string='Product', ondelete='restrict', index=True) - product_image = fields.Binary('Product Image', related="product_id.image", store=False) + product_image = fields.Binary('Product Image', related="product_id.image", store=False, readonly=False) account_id = fields.Many2one('account.account', string='Account', domain=[('deprecated', '=', False)], default=_default_account, help="The income or expense account related to the selected product.") @@ -1602,7 +1602,7 @@ class AccountInvoiceLine(models.Model): related='invoice_id.company_id', store=True, readonly=True, related_sudo=False) partner_id = fields.Many2one('res.partner', string='Partner', related='invoice_id.partner_id', store=True, readonly=True, related_sudo=False) - currency_id = fields.Many2one('res.currency', related='invoice_id.currency_id', store=True, related_sudo=False) + currency_id = fields.Many2one('res.currency', related='invoice_id.currency_id', store=True, related_sudo=False, readonly=False) company_currency_id = fields.Many2one('res.currency', related='invoice_id.company_currency_id', readonly=True, related_sudo=False) is_rounding_line = fields.Boolean(string='Rounding Line', help='Is a rounding line in case of cash rounding.') diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index e0066eb155b2d47a81ffee1ea66b690ded2d3b0c..6e8b5e43769cb2c716457ef61711c9b43a1eacea 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -611,8 +611,8 @@ class AccountMoveLine(models.Model): ondelete="cascade", domain=[('deprecated', '=', False)], default=lambda self: self._context.get('account_id', False)) move_id = fields.Many2one('account.move', string='Journal Entry', ondelete="cascade", help="The move of this entry line.", index=True, required=True, auto_join=True) - narration = fields.Text(related='move_id.narration', string='Narration') - ref = fields.Char(related='move_id.ref', string='Reference', store=True, copy=False, index=True) + narration = fields.Text(related='move_id.narration', string='Narration', readonly=False) + ref = fields.Char(related='move_id.ref', string='Reference', store=True, copy=False, index=True, readonly=False) payment_id = fields.Many2one('account.payment', string="Originator Payment", help="Payment that created this entry", copy=False) statement_line_id = fields.Many2one('account.bank.statement.line', index=True, string='Bank statement line reconciled with this entry', copy=False, readonly=True) statement_id = fields.Many2one('account.bank.statement', related='statement_line_id.statement_id', string='Statement', store=True, @@ -623,13 +623,13 @@ class AccountMoveLine(models.Model): help='Debit journal items that are matched with this journal item.') matched_credit_ids = fields.One2many('account.partial.reconcile', 'debit_move_id', String='Matched Credits', help='Credit journal items that are matched with this journal item.') - journal_id = fields.Many2one('account.journal', related='move_id.journal_id', string='Journal', + journal_id = fields.Many2one('account.journal', related='move_id.journal_id', string='Journal', readonly=False, index=True, store=True, copy=False) # related is required blocked = fields.Boolean(string='No Follow-up', default=False, help="You can check this box to mark this journal item as a litigation with the associated partner") date_maturity = fields.Date(string='Due date', index=True, required=True, help="This field is used for payable and receivable journal entries. You can put the limit date for the payment of this line.") - date = fields.Date(related='move_id.date', string='Date', index=True, store=True, copy=False) # related is required + date = fields.Date(related='move_id.date', string='Date', index=True, store=True, copy=False, readonly=False) # related is required analytic_line_ids = fields.One2many('account.analytic.line', 'move_id', string='Analytic lines', oldname="analytic_lines") tax_ids = fields.Many2many('account.tax', string='Taxes', domain=['|', ('active', '=', False), ('active', '=', True)]) tax_line_id = fields.Many2one('account.tax', string='Originator tax', ondelete='restrict') @@ -641,7 +641,7 @@ class AccountMoveLine(models.Model): # TODO: put the invoice link and partner_id on the account_move invoice_id = fields.Many2one('account.invoice', oldname="invoice") partner_id = fields.Many2one('res.partner', string='Partner', ondelete='restrict') - user_type_id = fields.Many2one('account.account.type', related='account_id.user_type_id', index=True, store=True, oldname="user_type") + user_type_id = fields.Many2one('account.account.type', related='account_id.user_type_id', index=True, store=True, oldname="user_type", readonly=False) tax_exigible = fields.Boolean(string='Appears in VAT report', default=True, help="Technical field used to mark a tax line as exigible in the vat report or not (only exigible journal items are displayed). By default all new journal items are directly exigible, but with the feature cash_basis on taxes, some will become exigible only when the payment is recorded.") parent_state = fields.Char(compute="_compute_parent_state", help="State of the parent account.move") @@ -1376,7 +1376,7 @@ class AccountPartialReconcile(models.Model): currency_id = fields.Many2one('res.currency', string='Currency') company_currency_id = fields.Many2one('res.currency', string="Company Currency", related='company_id.currency_id', readonly=True, help='Utility field to express amount currency') - company_id = fields.Many2one('res.company', related='debit_move_id.company_id', store=True, string='Company') + company_id = fields.Many2one('res.company', related='debit_move_id.company_id', store=True, string='Company', readonly=False) full_reconcile_id = fields.Many2one('account.full.reconcile', string="Full Reconcile", copy=False) max_date = fields.Date(string='Max Date of Matched Lines', compute='_compute_max_date', readonly=True, copy=False, store=True, diff --git a/addons/account/models/company.py b/addons/account/models/company.py index 2f49a85962e8648091527e5fc9126f98bcdec2c6..223c37eea7f108d1d189ef3d249d39fac2f55913 100644 --- a/addons/account/models/company.py +++ b/addons/account/models/company.py @@ -38,9 +38,9 @@ class ResCompany(models.Model): ('round_globally', 'Round Globally'), ], default='round_per_line', string='Tax Calculation Rounding Method') currency_exchange_journal_id = fields.Many2one('account.journal', string="Exchange Gain or Loss Journal", domain=[('type', '=', 'general')]) - income_currency_exchange_account_id = fields.Many2one('account.account', related='currency_exchange_journal_id.default_credit_account_id', + income_currency_exchange_account_id = fields.Many2one('account.account', related='currency_exchange_journal_id.default_credit_account_id', readonly=False, string="Gain Exchange Rate Account", domain="[('internal_type', '=', 'other'), ('deprecated', '=', False), ('company_id', '=', id)]") - expense_currency_exchange_account_id = fields.Many2one('account.account', related='currency_exchange_journal_id.default_debit_account_id', + expense_currency_exchange_account_id = fields.Many2one('account.account', related='currency_exchange_journal_id.default_debit_account_id', readonly=False, string="Loss Exchange Rate Account", domain="[('internal_type', '=', 'other'), ('deprecated', '=', False), ('company_id', '=', id)]") anglo_saxon_accounting = fields.Boolean(string="Use anglo-saxon accounting") property_stock_account_input_categ_id = fields.Many2one('account.account', string="Input Account for Stock Valuation", oldname="property_stock_account_input_categ") @@ -73,8 +73,8 @@ Best Regards,''')) #Fields of the setup step for opening move account_opening_move_id = fields.Many2one(string='Opening Journal Entry', comodel_name='account.move', help="The journal entry containing the initial balance of all this company's accounts.") - account_opening_journal_id = fields.Many2one(string='Opening Journal', comodel_name='account.journal', related='account_opening_move_id.journal_id', help="Journal where the opening entry of this company's accounting has been posted.") - account_opening_date = fields.Date(string='Opening Date', related='account_opening_move_id.date', help="Date at which the opening entry of this company's accounting has been posted.") + account_opening_journal_id = fields.Many2one(string='Opening Journal', comodel_name='account.journal', related='account_opening_move_id.journal_id', help="Journal where the opening entry of this company's accounting has been posted.", readonly=False) + account_opening_date = fields.Date(string='Opening Date', related='account_opening_move_id.date', help="Date at which the opening entry of this company's accounting has been posted.", readonly=False) # Fields marking the completion of a setup step # YTI FIXME : The selection should be factorize as a static list in base, like ONBOARDING_STEP_STATES diff --git a/addons/account/models/res_config_settings.py b/addons/account/models/res_config_settings.py index b7ebec88286347b9769dc57a23b46875d9803010..978b85017bede930f9b2fb0d5a17b75c42a3c227 100644 --- a/addons/account/models/res_config_settings.py +++ b/addons/account/models/res_config_settings.py @@ -8,23 +8,23 @@ class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' has_accounting_entries = fields.Boolean(compute='_compute_has_chart_of_accounts') - currency_id = fields.Many2one('res.currency', related="company_id.currency_id", required=True, + currency_id = fields.Many2one('res.currency', related="company_id.currency_id", required=True, readonly=False, string='Currency', help="Main currency of the company.") currency_exchange_journal_id = fields.Many2one( 'account.journal', - related='company_id.currency_exchange_journal_id', + related='company_id.currency_exchange_journal_id', readonly=False, string="Exchange Gain or Loss Journal", domain="[('company_id', '=', company_id), ('type', '=', 'general')]", help='The accounting journal where automatic exchange differences will be registered') has_chart_of_accounts = fields.Boolean(compute='_compute_has_chart_of_accounts', string='Company has a chart of accounts') chart_template_id = fields.Many2one('account.chart.template', string='Template', domain="[('visible','=', True)]") - sale_tax_id = fields.Many2one('account.tax', string="Default Sale Tax", related='company_id.account_sale_tax_id') - purchase_tax_id = fields.Many2one('account.tax', string="Default Purchase Tax", related='company_id.account_purchase_tax_id') + sale_tax_id = fields.Many2one('account.tax', string="Default Sale Tax", related='company_id.account_sale_tax_id', readonly=False) + purchase_tax_id = fields.Many2one('account.tax', string="Default Purchase Tax", related='company_id.account_purchase_tax_id', readonly=False) tax_calculation_rounding_method = fields.Selection([ ('round_per_line', 'Round calculation of taxes per line'), ('round_globally', 'Round globally calculation of taxes '), - ], related='company_id.tax_calculation_rounding_method', string='Tax calculation rounding method') + ], related='company_id.tax_calculation_rounding_method', string='Tax calculation rounding method', readonly=False) module_account_accountant = fields.Boolean(string='Accounting') group_analytic_accounting = fields.Boolean(string='Analytic Accounting', implied_group='analytic.group_analytic_accounting') @@ -76,19 +76,19 @@ class ResConfigSettings(models.TransientModel): module_l10n_eu_service = fields.Boolean(string="EU Digital Goods VAT") module_account_taxcloud = fields.Boolean(string="Account TaxCloud") module_account_invoice_extract = fields.Boolean(string="Automate Bill Processing") - tax_exigibility = fields.Boolean(string='Cash Basis', related='company_id.tax_exigibility') - tax_cash_basis_journal_id = fields.Many2one('account.journal', related='company_id.tax_cash_basis_journal_id', string="Tax Cash Basis Journal") + tax_exigibility = fields.Boolean(string='Cash Basis', related='company_id.tax_exigibility', readonly=False) + tax_cash_basis_journal_id = fields.Many2one('account.journal', related='company_id.tax_cash_basis_journal_id', string="Tax Cash Basis Journal", readonly=False) invoice_reference_type = fields.Selection(string='Communication', - related='company_id.invoice_reference_type', help='Default Reference Type on Invoices.') + related='company_id.invoice_reference_type', help='Default Reference Type on Invoices.', readonly=False) account_bank_reconciliation_start = fields.Date(string="Bank Reconciliation Threshold", - related='company_id.account_bank_reconciliation_start', + related='company_id.account_bank_reconciliation_start', readonly=False, help="""The bank reconciliation widget won't ask to reconcile payments older than this date. This is useful if you install accounting after having used invoicing for some time and don't want to reconcile all the past payments with bank statements.""") - qr_code = fields.Boolean(string='Display SEPA QR code', related='company_id.qr_code') - invoice_is_print = fields.Boolean(string='Print', related='company_id.invoice_is_print') - invoice_is_email = fields.Boolean(string='Send Email', related='company_id.invoice_is_email') + qr_code = fields.Boolean(string='Display SEPA QR code', related='company_id.qr_code', readonly=False) + invoice_is_print = fields.Boolean(string='Print', related='company_id.invoice_is_print', readonly=False) + invoice_is_email = fields.Boolean(string='Send Email', related='company_id.invoice_is_email', readonly=False) @api.multi def set_values(self): diff --git a/addons/account/wizard/setup_wizards.py b/addons/account/wizard/setup_wizards.py index 64f6aef13754bd2ca148d6b0487a21e292d3165b..75ee6d7c4fc6b1ee4bec575c7804b7a3efcb069a 100644 --- a/addons/account/wizard/setup_wizards.py +++ b/addons/account/wizard/setup_wizards.py @@ -10,11 +10,11 @@ class FinancialYearOpeningWizard(models.TransientModel): company_id = fields.Many2one(comodel_name='res.company', required=True) opening_move_posted = fields.Boolean(string='Opening Move Posted', compute='_compute_opening_move_posted') - opening_date = fields.Date(string='Opening Date', required=True, related='company_id.account_opening_date', help="Date from which the accounting is managed in Odoo. It is the date of the opening entry.") + opening_date = fields.Date(string='Opening Date', required=True, related='company_id.account_opening_date', help="Date from which the accounting is managed in Odoo. It is the date of the opening entry.", readonly=False) fiscalyear_last_day = fields.Integer(related="company_id.fiscalyear_last_day", required=True, help="The last day of the month will be taken if the chosen day doesn't exist.") fiscalyear_last_month = fields.Selection(selection=[(1, 'January'), (2, 'February'), (3, 'March'), (4, 'April'), (5, 'May'), (6, 'June'), (7, 'July'), (8, 'August'), (9, 'September'), (10, 'October'), (11, 'November'), (12, 'December')], - related="company_id.fiscalyear_last_month", + related="company_id.fiscalyear_last_month", readonly=False, required=True, help="The last day of the month will be taken if the chosen day doesn't exist.") diff --git a/addons/account_asset/models/account_asset.py b/addons/account_asset/models/account_asset.py index 276f72268df83ad01cde2d4b7bfad8d0a57c0e1c..e6ce2091968488643a6500ffaaccca2f213c4210 100644 --- a/addons/account_asset/models/account_asset.py +++ b/addons/account_asset/models/account_asset.py @@ -109,7 +109,7 @@ class AccountAssetAsset(models.Model): salvage_value = fields.Float(string='Salvage Value', digits=0, readonly=True, states={'draft': [('readonly', False)]}, help="It is the amount you plan to have that you cannot depreciate.") invoice_id = fields.Many2one('account.invoice', string='Invoice', states={'draft': [('readonly', False)]}, copy=False) - type = fields.Selection(related="category_id.type", string='Type', required=True) + type = fields.Selection(related="category_id.type", string='Type', required=True, readonly=False) account_analytic_id = fields.Many2one('account.analytic.account', string='Analytic Account') analytic_tag_ids = fields.Many2many('account.analytic.tag', string='Analytic Tag') date_first_depreciation = fields.Selection([ @@ -477,7 +477,7 @@ class AccountAssetDepreciationLine(models.Model): name = fields.Char(string='Depreciation Name', required=True, index=True) sequence = fields.Integer(required=True) asset_id = fields.Many2one('account.asset.asset', string='Asset', required=True, ondelete='cascade') - parent_state = fields.Selection(related='asset_id.state', string='State of Asset') + parent_state = fields.Selection(related='asset_id.state', string='State of Asset', readonly=False) amount = fields.Float(string='Current Depreciation', digits=0, required=True) remaining_value = fields.Float(string='Next Period Depreciation', digits=0, required=True) depreciated_value = fields.Float(string='Cumulative Depreciation', required=True) diff --git a/addons/account_check_printing/models/res_config_settings.py b/addons/account_check_printing/models/res_config_settings.py index 2ba9bc94323b8aa73daa882a5ecd02d72d406186..b31823234909553576d58cce505c18941d4cae21 100644 --- a/addons/account_check_printing/models/res_config_settings.py +++ b/addons/account_check_printing/models/res_config_settings.py @@ -11,13 +11,13 @@ class ResConfigSettings(models.TransientModel): account_check_printing_layout = fields.Selection(related='company_id.account_check_printing_layout', string="Check Layout", 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", + 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', + 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', + 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', + 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', + 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.") diff --git a/addons/account_voucher/models/account_voucher.py b/addons/account_voucher/models/account_voucher.py index b348e13a62e40d10559f3b5c190ab62795cd3b3a..c979480bf35f68bcc9a5761f7bdd4faab28e8b6c 100644 --- a/addons/account_voucher/models/account_voucher.py +++ b/addons/account_voucher/models/account_voucher.py @@ -416,7 +416,7 @@ class AccountVoucherLine(models.Model): analytic_tag_ids = fields.Many2many('account.analytic.tag', string='Analytic Tags') company_id = fields.Many2one('res.company', related='voucher_id.company_id', string='Company', store=True, readonly=True) tax_ids = fields.Many2many('account.tax', string='Tax', help="Only for tax excluded from price") - currency_id = fields.Many2one('res.currency', related='voucher_id.currency_id') + currency_id = fields.Many2one('res.currency', related='voucher_id.currency_id', readonly=False) @api.one @api.depends('price_unit', 'tax_ids', 'quantity', 'product_id', 'voucher_id.currency_id') diff --git a/addons/analytic/models/analytic_account.py b/addons/analytic/models/analytic_account.py index 199f6097ae12cff0140d1b6d1b9d2cecff55499d..46fdbb17259421c184c98cf73ec6a7f5de3223b9 100644 --- a/addons/analytic/models/analytic_account.py +++ b/addons/analytic/models/analytic_account.py @@ -14,7 +14,7 @@ class AccountAnalyticDistribution(models.Model): account_id = fields.Many2one('account.analytic.account', string='Analytic Account', required=True) percentage = fields.Float(string='Percentage', required=True, default=100.0) - name = fields.Char(string='Name', related='account_id.name') + name = fields.Char(string='Name', related='account_id.name', readonly=False) tag_id = fields.Many2one('account.analytic.tag', string="Parent tag", required=True) _sql_constraints = [ diff --git a/addons/auth_ldap/models/res_config_settings.py b/addons/auth_ldap/models/res_config_settings.py index 92158e3fa3b7367021588ffc0d8b4e8df4f60380..4cc12be31e1effc61405404da7ea778dc6651437 100644 --- a/addons/auth_ldap/models/res_config_settings.py +++ b/addons/auth_ldap/models/res_config_settings.py @@ -7,4 +7,4 @@ from odoo import fields, models class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' - ldaps = fields.One2many(related='company_id.ldaps', string="LDAP Parameters") + ldaps = fields.One2many(related='company_id.ldaps', string="LDAP Parameters", readonly=False) diff --git a/addons/base_gengo/models/res_config_settings.py b/addons/base_gengo/models/res_config_settings.py index 17bbc2b24af3fd473168543a239a7677f0249cf3..78161d2142905ff487dd82530ad11d75bfaee56f 100644 --- a/addons/base_gengo/models/res_config_settings.py +++ b/addons/base_gengo/models/res_config_settings.py @@ -7,11 +7,11 @@ from odoo import api, models, fields class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' - gengo_private_key = fields.Text(string="Gengo Private Key", related="company_id.gengo_private_key") - gengo_public_key = fields.Text(string="Gengo Public Key", related="company_id.gengo_public_key") + gengo_private_key = fields.Text(string="Gengo Private Key", related="company_id.gengo_private_key", readonly=False) + gengo_public_key = fields.Text(string="Gengo Public Key", related="company_id.gengo_public_key", readonly=False) gengo_comment = fields.Text(string="Comments", related="company_id.gengo_comment", help="This comment will be automatically be enclosed in each an every request sent to Gengo") - gengo_auto_approve = fields.Boolean(string="Auto Approve Translation ?", related="company_id.gengo_auto_approve", + gengo_auto_approve = fields.Boolean(string="Auto Approve Translation ?", related="company_id.gengo_auto_approve", readonly=False, help="Jobs are Automatically Approved by Gengo.") - gengo_sandbox = fields.Boolean(string="Sandbox Mode", related="company_id.gengo_sandbox", + gengo_sandbox = fields.Boolean(string="Sandbox Mode", related="company_id.gengo_sandbox", readonly=False, help="Check this box if you're using the sandbox mode of Gengo, mainly used for testing purpose.") diff --git a/addons/base_setup/models/res_config_settings.py b/addons/base_setup/models/res_config_settings.py index d23737db9013acf4785a075f88cff2a100637756..bb6c718b29d960f7b0d56605d684c827f39df7cf 100644 --- a/addons/base_setup/models/res_config_settings.py +++ b/addons/base_setup/models/res_config_settings.py @@ -36,12 +36,12 @@ class ResConfigSettings(models.TransientModel): help="Share your partners to all companies defined in your instance.\n" " * Checked : Partners are visible for every companies, even if a company is defined on the partner.\n" " * Unchecked : Each company can see only its partner (partners where company is defined). Partners not related to a company are visible for all companies.") - report_footer = fields.Text(related="company_id.report_footer", string='Custom Report Footer', help="Footer text displayed at the bottom of all reports.") + report_footer = fields.Text(related="company_id.report_footer", string='Custom Report Footer', help="Footer text displayed at the bottom of all reports.", readonly=False) group_multi_currency = fields.Boolean(string='Multi-Currencies', implied_group='base.group_multi_currency', help="Allows to work in a multi currency environment") - paperformat_id = fields.Many2one(related="company_id.paperformat_id", string='Paper format') - external_report_layout_id = fields.Many2one(related="company_id.external_report_layout_id") + paperformat_id = fields.Many2one(related="company_id.paperformat_id", string='Paper format', readonly=False) + external_report_layout_id = fields.Many2one(related="company_id.external_report_layout_id", readonly=False) show_effect = fields.Boolean(string="Show Effect", config_parameter='base_setup.show_effect') @api.model diff --git a/addons/base_vat/models/res_config_settings.py b/addons/base_vat/models/res_config_settings.py index 0bcb8445cee8ee3ede1ce507fc86dcfeefde2d46..c5a06f872d428f7fe453c1912b0bdbb1580b5af5 100644 --- a/addons/base_vat/models/res_config_settings.py +++ b/addons/base_vat/models/res_config_settings.py @@ -6,5 +6,5 @@ from odoo import fields, models class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' - vat_check_vies = fields.Boolean(related='company_id.vat_check_vies', + vat_check_vies = fields.Boolean(related='company_id.vat_check_vies', readonly=False, string='Verify VAT Numbers') diff --git a/addons/crm_phone_validation/models/res_config_settings.py b/addons/crm_phone_validation/models/res_config_settings.py index 1ec56636935ddd0c3867ebb30a2d75136cb0abd6..b22f4552b5f6bae5cce12effd82323159e6c84c5 100644 --- a/addons/crm_phone_validation/models/res_config_settings.py +++ b/addons/crm_phone_validation/models/res_config_settings.py @@ -7,4 +7,4 @@ from odoo import fields, models class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' - crm_phone_valid_method = fields.Selection(related="company_id.phone_international_format", required=True) + crm_phone_valid_method = fields.Selection(related="company_id.phone_international_format", required=True, readonly=False) diff --git a/addons/delivery/models/delivery_carrier.py b/addons/delivery/models/delivery_carrier.py index d7797cb01fa97f777c9895cee692cddd9b039fba..77f34f856d0301cb4ae5c7f2ed24d47551bda001 100644 --- a/addons/delivery/models/delivery_carrier.py +++ b/addons/delivery/models/delivery_carrier.py @@ -42,7 +42,7 @@ class DeliveryCarrier(models.Model): integration_level = fields.Selection([('rate', 'Get Rate'), ('rate_and_ship', 'Get Rate and Create Shipment')], string="Integration Level", default='rate_and_ship', help="Action while validating Delivery Orders") prod_environment = fields.Boolean("Environment", help="Set to True if your credentials are certified for production.") debug_logging = fields.Boolean('Debug logging', help="Log requests in order to ease debugging") - company_id = fields.Many2one('res.company', string='Company', related='product_id.company_id', store=True) + company_id = fields.Many2one('res.company', string='Company', related='product_id.company_id', store=True, readonly=False) product_id = fields.Many2one('product.product', string='Delivery Product', required=True, ondelete='restrict') country_ids = fields.Many2many('res.country', 'delivery_carrier_country_rel', 'carrier_id', 'country_id', 'Countries') diff --git a/addons/digest/models/digest.py b/addons/digest/models/digest.py index d89016bd78b71b4bc4bf654e6bd52214c5a56a4b..7dc03b405a6d8f27d9c4f43753417195fa3aa88f 100644 --- a/addons/digest/models/digest.py +++ b/addons/digest/models/digest.py @@ -32,7 +32,7 @@ class Digest(models.Model): domain="[('model','=','digest.digest')]", default=lambda self: self.env.ref('digest.digest_mail_template'), required=True) - currency_id = fields.Many2one(related="company_id.currency_id", string='Currency') + currency_id = fields.Many2one(related="company_id.currency_id", string='Currency', readonly=False) company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id.id) available_fields = fields.Char(compute='_compute_available_fields') is_subscribed = fields.Boolean('Is user subscribed', compute='_compute_is_subscribed') diff --git a/addons/event/models/event.py b/addons/event/models/event.py index 06156e3a99ee17bbf6493ee10093105f01032122..dc15eead79f4a0b3b33967487440877028638541 100644 --- a/addons/event/models/event.py +++ b/addons/event/models/event.py @@ -159,7 +159,7 @@ class EventEvent(models.Model): default=lambda self: self.env.user.company_id.partner_id, readonly=False, states={'done': [('readonly', True)]}, track_visibility="onchange") - country_id = fields.Many2one('res.country', 'Country', related='address_id.country_id', store=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( string='Description', oldname='note', translate=html_translate, sanitize_attributes=False, diff --git a/addons/fleet/models/fleet_vehicle.py b/addons/fleet/models/fleet_vehicle.py index 3eadaca7a2c0d44bce0d48f1ed36211b230fc69a..7a00aea283fb22c6ab123f29731cdaa3b32439c0 100644 --- a/addons/fleet/models/fleet_vehicle.py +++ b/addons/fleet/models/fleet_vehicle.py @@ -26,7 +26,7 @@ class FleetVehicle(models.Model): driver_id = fields.Many2one('res.partner', 'Driver', track_visibility="onchange", 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') - brand_id = fields.Many2one('fleet.vehicle.model.brand', 'Brand', related="model_id.brand_id", store=True) + 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') log_services = fields.One2many('fleet.vehicle.log.services', 'vehicle_id', 'Services Logs') @@ -66,9 +66,9 @@ class FleetVehicle(models.Model): horsepower_tax = fields.Float('Horsepower Taxation') power = fields.Integer('Power', help='Power in kW of the vehicle') co2 = fields.Float('CO2 Emissions', help='CO2 emissions of the vehicle') - image = fields.Binary(related='model_id.image', string="Logo") - image_medium = fields.Binary(related='model_id.image_medium', string="Logo (medium)") - image_small = fields.Binary(related='model_id.image_small', string="Logo (small)") + image = fields.Binary(related='model_id.image', string="Logo", readonly=False) + image_medium = fields.Binary(related='model_id.image_medium', string="Logo (medium)", readonly=False) + image_small = fields.Binary(related='model_id.image_small', string="Logo (small)", readonly=False) contract_renewal_due_soon = fields.Boolean(compute='_compute_contract_reminder', search='_search_contract_renewal_due_soon', string='Has Contracts to renew', multi='contract_info') contract_renewal_overdue = fields.Boolean(compute='_compute_contract_reminder', search='_search_get_overdue_contract_reminder', @@ -292,7 +292,7 @@ class FleetVehicleOdometer(models.Model): 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") + driver_id = fields.Many2one(related="vehicle_id.driver_id", string="Driver", readonly=False) @api.depends('vehicle_id', 'date') def _compute_vehicle_log_name(self): diff --git a/addons/fleet/models/fleet_vehicle_cost.py b/addons/fleet/models/fleet_vehicle_cost.py index f51cf01597ac250daa8dc5c968510f83555854f5..422645912de0ac879dd8cc5cf21842e6471eeba1 100644 --- a/addons/fleet/models/fleet_vehicle_cost.py +++ b/addons/fleet/models/fleet_vehicle_cost.py @@ -12,7 +12,7 @@ class FleetVehicleCost(models.Model): _description = 'Cost related to a vehicle' _order = 'date desc, vehicle_id asc' - name = fields.Char(related='vehicle_id.name', string='Name', store=True) + name = fields.Char(related='vehicle_id.name', string='Name', store=True, readonly=False) vehicle_id = fields.Many2one('fleet.vehicle', 'Vehicle', required=True, help='Vehicle concerned by this log') cost_subtype_id = fields.Many2one('fleet.service.type', 'Type', help='Cost type purchased with this cost') amount = fields.Float('Total Price') @@ -134,7 +134,7 @@ class FleetVehicleLogContract(models.Model): # we need to keep this field as a related with store=True because the graph view doesn't support # (1) to address fields from inherited table # (2) fields that aren't stored in database - cost_amount = fields.Float(related='cost_id.amount', string='Amount', store=True) + cost_amount = fields.Float(related='cost_id.amount', string='Amount', store=True, readonly=False) odometer = fields.Float(string='Odometer at creation', help='Odometer measure of the vehicle at the moment of the contract creation') @@ -317,7 +317,7 @@ class FleetVehicleLogFuel(models.Model): # we need to keep this field as a related with store=True because the graph view doesn't support # (1) to address fields from inherited table # (2) fields that aren't stored in database - cost_amount = fields.Float(related='cost_id.amount', string='Amount', store=True) + cost_amount = fields.Float(related='cost_id.amount', string='Amount', store=True, readonly=False) @api.onchange('vehicle_id') def _onchange_vehicle(self): @@ -366,7 +366,7 @@ class FleetVehicleLogServices(models.Model): vendor_id = fields.Many2one('res.partner', 'Vendor', domain="[('supplier','=',True)]") # we need to keep this field as a related with store=True because the graph view doesn't support # (1) to address fields from inherited table and (2) fields that aren't stored in database - cost_amount = fields.Float(related='cost_id.amount', string='Amount', store=True) + cost_amount = fields.Float(related='cost_id.amount', string='Amount', store=True, readonly=False) notes = fields.Text() cost_id = fields.Many2one('fleet.vehicle.cost', 'Cost', required=True, ondelete='cascade') diff --git a/addons/fleet/models/fleet_vehicle_model.py b/addons/fleet/models/fleet_vehicle_model.py index 55a76f2e7695e20e9450be113b05dc087ed8bfa6..ded926fc2a0f0de049b4f1776a371befb5a87cf4 100644 --- a/addons/fleet/models/fleet_vehicle_model.py +++ b/addons/fleet/models/fleet_vehicle_model.py @@ -12,9 +12,9 @@ class FleetVehicleModel(models.Model): name = fields.Char('Model name', required=True) brand_id = fields.Many2one('fleet.vehicle.model.brand', 'Make', required=True, help='Make of the vehicle') vendors = fields.Many2many('res.partner', 'fleet_vehicle_model_vendors', 'model_id', 'partner_id', string='Vendors') - image = fields.Binary(related='brand_id.image', string="Logo") - image_medium = fields.Binary(related='brand_id.image_medium', string="Logo (medium)") - image_small = fields.Binary(related='brand_id.image_small', string="Logo (small)") + image = fields.Binary(related='brand_id.image', string="Logo", readonly=False) + image_medium = fields.Binary(related='brand_id.image_medium', string="Logo (medium)", readonly=False) + image_small = fields.Binary(related='brand_id.image_small', string="Logo (small)", readonly=False) @api.multi @api.depends('name', 'brand_id') diff --git a/addons/gamification/models/badge.py b/addons/gamification/models/badge.py index 4e0d9d1c27ccd08a03f328d279a239d55e9f92a0..6686b29fee5a907129969d6ded9bc3c24f28afac 100644 --- a/addons/gamification/models/badge.py +++ b/addons/gamification/models/badge.py @@ -21,7 +21,7 @@ class BadgeUser(models.Model): badge_id = fields.Many2one('gamification.badge', string='Badge', required=True, ondelete="cascade", index=True) challenge_id = fields.Many2one('gamification.challenge', string='Challenge originating', help="If this badge was rewarded through a challenge") comment = fields.Text('Comment') - badge_name = fields.Char(related='badge_id.name', string="Badge Name") + badge_name = fields.Char(related='badge_id.name', string="Badge Name", readonly=False) def _send_badge(self): """Send a notification to a user for receiving a badge diff --git a/addons/gamification/models/challenge.py b/addons/gamification/models/challenge.py index 1c088cd2bac584c70f92890212c4ee487ed84ec7..bf8e17fa4a2b0acb437aa844b1a28df4aa51315a 100644 --- a/addons/gamification/models/challenge.py +++ b/addons/gamification/models/challenge.py @@ -781,7 +781,7 @@ class ChallengeLine(models.Model): sequence = fields.Integer('Sequence', help='Sequence number for ordering', default=1) target_goal = fields.Float('Target Value to Reach', required=True) - name = fields.Char("Name", related='definition_id.name') + name = fields.Char("Name", related='definition_id.name', readonly=False) condition = fields.Selection("Condition", related='definition_id.condition', readonly=True) definition_suffix = fields.Char("Unit", related='definition_id.suffix', readonly=True) definition_monetary = fields.Boolean("Monetary", related='definition_id.monetary', readonly=True) diff --git a/addons/gamification/models/goal.py b/addons/gamification/models/goal.py index 3f98b352bc9e78e7b71f4ed8aec18342bd2bd67a..a812764e5c6a17ceb15e78d51b19b48084251f73 100644 --- a/addons/gamification/models/goal.py +++ b/addons/gamification/models/goal.py @@ -172,7 +172,7 @@ class Goal(models.Model): to_update = fields.Boolean('To update') closed = fields.Boolean('Closed goal', help="These goals will not be recomputed.") - computation_mode = fields.Selection(related='definition_id.computation_mode') + computation_mode = fields.Selection(related='definition_id.computation_mode', readonly=False) remind_update_delay = fields.Integer( "Remind delay", help="The number of days after which the user " "assigned to a manual goal will be reminded. " diff --git a/addons/google_spreadsheet/models/res_config_settings.py b/addons/google_spreadsheet/models/res_config_settings.py index ee47df724decb03cba8ce247f5b74969db03dcf0..71c91daae991e268272d66a2eac8c6bb4aa9f18b 100644 --- a/addons/google_spreadsheet/models/res_config_settings.py +++ b/addons/google_spreadsheet/models/res_config_settings.py @@ -7,4 +7,4 @@ from odoo import fields, models class ResConfigSettings(models.TransientModel): _inherit = "res.config.settings" - google_drive_uri_copy = fields.Char(related='google_drive_uri', string='URI Copy', help="The URL to generate the authorization code from Google") + google_drive_uri_copy = fields.Char(related='google_drive_uri', string='URI Copy', help="The URL to generate the authorization code from Google", readonly=False) diff --git a/addons/hr/models/hr.py b/addons/hr/models/hr.py index cb53273cf6d72080a17a2931f591758acc8d1704..e6e7d2e47d53664ee2eff5e48c41da6890a776f5 100644 --- a/addons/hr/models/hr.py +++ b/addons/hr/models/hr.py @@ -107,9 +107,9 @@ class Employee(models.Model): # resource and user # required on the resource, make sure required="True" set in the view - name = fields.Char(related='resource_id.name', store=True, oldname='name_related') - user_id = fields.Many2one('res.users', 'User', related='resource_id.user_id', store=True) - active = fields.Boolean('Active', related='resource_id.active', default=True, store=True) + name = fields.Char(related='resource_id.name', store=True, oldname='name_related', readonly=False) + user_id = fields.Many2one('res.users', 'User', related='resource_id.user_id', store=True, readonly=False) + active = fields.Boolean('Active', related='resource_id.active', default=True, store=True, readonly=False) # private partner address_home_id = fields.Many2one( 'res.partner', 'Private Address', help='Enter here the private address of the employee, not the one linked to your company.', diff --git a/addons/hr/models/res_config_settings.py b/addons/hr/models/res_config_settings.py index d66006cc101fd4691d2633147b1810329a7e097d..4512d6e04f373e3ce30719267cbfed3fd9279320 100644 --- a/addons/hr/models/res_config_settings.py +++ b/addons/hr/models/res_config_settings.py @@ -8,5 +8,5 @@ class ResConfigSettings(models.TransientModel): resource_calendar_id = fields.Many2one( 'resource.calendar', 'Company Working Hours', - related='company_id.resource_calendar_id') + related='company_id.resource_calendar_id', readonly=False) module_hr_org_chart = fields.Boolean(string="Show Organizational Chart") diff --git a/addons/hr_contract/models/hr_contract.py b/addons/hr_contract/models/hr_contract.py index b0670634ee119acea17b7070b260675472ded3d0..bb30f94856e68684ca28ebc6af4b0bbc334c9d95 100644 --- a/addons/hr_contract/models/hr_contract.py +++ b/addons/hr_contract/models/hr_contract.py @@ -77,9 +77,9 @@ class Contract(models.Model): track_visibility='onchange', 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") - visa_no = fields.Char('Visa No', related="employee_id.visa_no") - visa_expire = fields.Date('Visa Expire Date', related="employee_id.visa_expire") + permit_no = fields.Char('Work Permit No', related="employee_id.permit_no", readonly=False) + visa_no = fields.Char('Visa No', related="employee_id.visa_no", readonly=False) + visa_expire = fields.Date('Visa Expire Date', related="employee_id.visa_expire", readonly=False) reported_to_secretariat = fields.Boolean('Social Secretariat', help='Green this button when the contract information has been transfered to the social secretariat.') diff --git a/addons/hr_expense/models/hr_expense.py b/addons/hr_expense/models/hr_expense.py index b4e261748078d08ee1a818479019e9b9ce238b2e..287bb0ac8b503d00d3c60248d4e0fda43d671797 100644 --- a/addons/hr_expense/models/hr_expense.py +++ b/addons/hr_expense/models/hr_expense.py @@ -57,7 +57,7 @@ class HrExpense(models.Model): total_amount_company = fields.Monetary("Total (Company Currency)", compute='_compute_total_amount_company', store=True, currency_field='company_currency_id', digits=dp.get_precision('Account')) company_id = fields.Many2one('res.company', string='Company', readonly=True, states={'draft': [('readonly', False)], 'refused': [('readonly', False)]}, default=lambda self: self.env.user.company_id) currency_id = fields.Many2one('res.currency', string='Currency', readonly=True, states={'draft': [('readonly', False)], 'refused': [('readonly', False)]}, default=lambda self: self.env.user.company_id.currency_id) - company_currency_id = fields.Many2one('res.currency', string="Report Company Currency", related='sheet_id.currency_id', store=True) + company_currency_id = fields.Many2one('res.currency', string="Report Company Currency", related='sheet_id.currency_id', store=True, readonly=False) analytic_account_id = fields.Many2one('account.analytic.account', string='Analytic Account', states={'post': [('readonly', True)], 'done': [('readonly', True)]}, oldname='analytic_account') analytic_tag_ids = fields.Many2many('account.analytic.tag', string='Analytic Tags', states={'post': [('readonly', True)], 'done': [('readonly', True)]}) account_id = fields.Many2one('account.account', string='Account', states={'post': [('readonly', True)], 'done': [('readonly', True)]}, default=_default_account_id, help="An expense account is expected") diff --git a/addons/hr_expense_check/models/payment.py b/addons/hr_expense_check/models/payment.py index 857ac4a030d6ed4d1c0906cdd5a48aaaf91fb871..e4bd4418791bde119ffbd7cb3c4ed4f2635cacb1 100644 --- a/addons/hr_expense_check/models/payment.py +++ b/addons/hr_expense_check/models/payment.py @@ -7,7 +7,7 @@ class HrExpenseRegisterPaymentWizard(models.TransientModel): _inherit = "hr.expense.sheet.register.payment.wizard" check_amount_in_words = fields.Char(string="Amount in Words") - check_manual_sequencing = fields.Boolean(related='journal_id.check_manual_sequencing') + check_manual_sequencing = fields.Boolean(related='journal_id.check_manual_sequencing', readonly=False) # Note: a check_number == 0 means that it will be attributed when the check is printed check_number = fields.Integer(string="Check Number", readonly=True, copy=False, default=0, help="Number of the check corresponding to this payment. If your pre-printed check are not already numbered, " diff --git a/addons/hr_holidays/models/hr_leave.py b/addons/hr_holidays/models/hr_leave.py index 902ba6afd28bfac9f8a1370a365d9ecc75b8c19d..742986ab227c6111ca3fe58c821b6cd4cd947730 100644 --- a/addons/hr_holidays/models/hr_leave.py +++ b/addons/hr_holidays/models/hr_leave.py @@ -115,7 +115,7 @@ class HolidaysRequest(models.Model): states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}, domain=[('valid', '=', True)]) leave_type_request_unit = fields.Selection(related='holiday_status_id.request_unit', readonly=True) - validation_type = fields.Selection('Validation Type', related='holiday_status_id.validation_type') + validation_type = fields.Selection('Validation Type', related='holiday_status_id.validation_type', readonly=False) # HR data employee_id = fields.Many2one( 'hr.employee', string='Employee', index=True, readonly=True, diff --git a/addons/hr_recruitment/models/hr_recruitment.py b/addons/hr_recruitment/models/hr_recruitment.py index 8c7093b5c5cc7f723c6613408a5099473ab5c51d..7f146ca5d5659f0dfb497e79a6198f2d970370d3 100644 --- a/addons/hr_recruitment/models/hr_recruitment.py +++ b/addons/hr_recruitment/models/hr_recruitment.py @@ -157,16 +157,16 @@ class Applicant(models.Model): emp_id = fields.Many2one('hr.employee', string="Employee", track_visibility="onchange", 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") + employee_name = fields.Char(related='emp_id.name', string="Employee Name", readonly=False) attachment_ids = fields.One2many('ir.attachment', 'res_id', domain=[('res_model', '=', 'hr.applicant')], string='Attachments') kanban_state = fields.Selection([ ('normal', 'Grey'), ('done', 'Green'), ('blocked', 'Red')], string='Kanban State', copy=False, default='normal', required=True) - legend_blocked = fields.Char(related='stage_id.legend_blocked', string='Kanban Blocked') - legend_done = fields.Char(related='stage_id.legend_done', string='Kanban Valid') - legend_normal = fields.Char(related='stage_id.legend_normal', string='Kanban Ongoing') + legend_blocked = fields.Char(related='stage_id.legend_blocked', string='Kanban Blocked', readonly=False) + legend_done = fields.Char(related='stage_id.legend_done', string='Kanban Valid', readonly=False) + legend_normal = fields.Char(related='stage_id.legend_normal', string='Kanban Ongoing', readonly=False) @api.depends('date_open', 'date_closed') diff --git a/addons/hr_recruitment_survey/models/hr_applicant.py b/addons/hr_recruitment_survey/models/hr_applicant.py index c83649269bba80700d85d88721048db564107053..46fb9445da0cc4e007175eb42c82d208222d29b9 100644 --- a/addons/hr_recruitment_survey/models/hr_applicant.py +++ b/addons/hr_recruitment_survey/models/hr_applicant.py @@ -6,7 +6,7 @@ from odoo import api, fields, models class Applicant(models.Model): _inherit = "hr.applicant" - survey_id = fields.Many2one('survey.survey', related='job_id.survey_id', string="Survey") + survey_id = fields.Many2one('survey.survey', related='job_id.survey_id', string="Survey", readonly=False) response_id = fields.Many2one('survey.user_input', "Response", ondelete="set null", oldname="response") @api.multi diff --git a/addons/hr_timesheet/models/analytic_account.py b/addons/hr_timesheet/models/analytic_account.py index eba72e424560df251ea2b780c7d2ffb9dac19ebf..8e794bf42558db2709c065b68ff961bddf81a96f 100644 --- a/addons/hr_timesheet/models/analytic_account.py +++ b/addons/hr_timesheet/models/analytic_account.py @@ -9,7 +9,7 @@ class AccountAnalyticAccount(models.Model): _inherit = 'account.analytic.account' _description = 'Analytic Account' - company_uom_id = fields.Many2one('uom.uom', related='company_id.project_time_mode_id', string="Company UOM") + company_uom_id = fields.Many2one('uom.uom', related='company_id.project_time_mode_id', string="Company UOM", readonly=False) project_ids = fields.One2many('project.project', 'analytic_account_id', string='Projects') project_count = fields.Integer("Project Count", compute='_compute_project_count') diff --git a/addons/hr_timesheet/models/project.py b/addons/hr_timesheet/models/project.py index e34f395b87b1aa09e1ed68c8943f7cc21f9149a0..e93a3c5deac474d9acde441f692c328906345300 100644 --- a/addons/hr_timesheet/models/project.py +++ b/addons/hr_timesheet/models/project.py @@ -96,7 +96,7 @@ class Task(models.Model): _inherit = "project.task" analytic_account_active = fields.Boolean("Analytic Account", related='project_id.analytic_account_id.active', readonly=True) - allow_timesheets = fields.Boolean("Allow timesheets", related='project_id.allow_timesheets', help="Timesheets can be logged on this task.") + allow_timesheets = fields.Boolean("Allow timesheets", related='project_id.allow_timesheets', help="Timesheets can be logged on this task.", readonly=False) remaining_hours = fields.Float("Remaining Hours", compute='_compute_remaining_hours', store=True, readonly=True, help="Total remaining time, can be re-estimated periodically by the assignee of the task.") effective_hours = fields.Float("Hours Spent", compute='_compute_effective_hours', compute_sudo=True, store=True, help="Computed using the sum of the task work done.") total_hours_spent = fields.Float("Total Hours", compute='_compute_total_hours_spent', store=True, help="Computed as: Time Spent + Sub-tasks Hours.") diff --git a/addons/hr_timesheet/models/res_config_settings.py b/addons/hr_timesheet/models/res_config_settings.py index 73d57d048fa458229584a19b60cf4028c8247c08..3253224b00c078e310bc939935c248435ffaecdc 100644 --- a/addons/hr_timesheet/models/res_config_settings.py +++ b/addons/hr_timesheet/models/res_config_settings.py @@ -10,11 +10,11 @@ class ResConfigSettings(models.TransientModel): module_project_timesheet_synchro = fields.Boolean("Awesome Timesheet") module_project_timesheet_holidays = fields.Boolean("Leaves") project_time_mode_id = fields.Many2one( - 'uom.uom', related='company_id.project_time_mode_id', string='Project Time Unit', + 'uom.uom', related='company_id.project_time_mode_id', string='Project Time Unit', readonly=False, help="This will set the unit of measure used in projects and tasks.\n" "If you use the timesheet linked to projects, don't " "forget to setup the right unit of measure in your employees.") timesheet_encode_uom_id = fields.Many2one('uom.uom', string="Encoding Unit", - related='company_id.timesheet_encode_uom_id', + related='company_id.timesheet_encode_uom_id', readonly=False, help="""This will set the unit of measure used to encode timesheet. This will simply provide tools and widgets to help the encoding. All reporting will still be expressed in hours (default value).""") diff --git a/addons/l10n_be_hr_payroll_fleet/models/hr_contract.py b/addons/l10n_be_hr_payroll_fleet/models/hr_contract.py index 2864a2a7f0d6305403cfb344aca41a8291666e8d..05dd20a00fecc08eab14d8f575cf70161100426d 100644 --- a/addons/l10n_be_hr_payroll_fleet/models/hr_contract.py +++ b/addons/l10n_be_hr_payroll_fleet/models/hr_contract.py @@ -18,11 +18,11 @@ class HrContract(models.Model): # YTI: Check if could be removed new_car_model_id = fields.Many2one('fleet.vehicle.model', string="Model", domain=lambda self: self._get_possible_model_domain()) max_unused_cars = fields.Integer(compute='_compute_max_unused_cars') - acquisition_date = fields.Date(related='car_id.acquisition_date') - car_value = fields.Float(related="car_id.car_value") - fuel_type = fields.Selection(related="car_id.fuel_type") - co2 = fields.Float(related="car_id.co2") - driver_id = fields.Many2one('res.partner', related="car_id.driver_id") + acquisition_date = fields.Date(related='car_id.acquisition_date', readonly=False) + car_value = fields.Float(related="car_id.car_value", readonly=False) + fuel_type = fields.Selection(related="car_id.fuel_type", readonly=False) + co2 = fields.Float(related="car_id.co2", readonly=False) + driver_id = fields.Many2one('res.partner', related="car_id.driver_id", readonly=False) car_open_contracts_count = fields.Integer(compute='_compute_car_open_contracts_count') recurring_cost_amount_depreciated = fields.Float( compute='_compute_recurring_cost_amount_depreciated', diff --git a/addons/l10n_be_invoice_bba/models/res_config_settings.py b/addons/l10n_be_invoice_bba/models/res_config_settings.py index b95cac58f89ef62b7e11dc1ad1b494730f744922..26f62dc966dd059dc49eafdbb36fe9c0c042fac2 100644 --- a/addons/l10n_be_invoice_bba/models/res_config_settings.py +++ b/addons/l10n_be_invoice_bba/models/res_config_settings.py @@ -6,6 +6,6 @@ from odoo import api, fields, models class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' - l10n_be_structured_comm = fields.Selection(related='company_id.l10n_be_structured_comm', + l10n_be_structured_comm = fields.Selection(related='company_id.l10n_be_structured_comm', readonly=False, string='Communication Algorithm', default='random', help='Choose an algorithm to generate the structured communication.') diff --git a/addons/l10n_ch/models/account_invoice.py b/addons/l10n_ch/models/account_invoice.py index 6afa172d617174d3275958500532f4112827bc31..6373d00f8a73f3d53cf8c1ef18371bd15cd90804 100644 --- a/addons/l10n_ch/models/account_invoice.py +++ b/addons/l10n_ch/models/account_invoice.py @@ -26,7 +26,7 @@ class AccountInvoice(models.Model): l10n_ch_isr_valid = fields.Boolean(compute='_compute_l10n_ch_isr_valid', help='Boolean value. True iff all the data required to generate the ISR are present') l10n_ch_isr_sent = fields.Boolean(defaut=False, help="Boolean value telling whether or not the ISR corresponding to this invoice has already been printed or sent by mail.") - l10n_ch_currency_name = fields.Char(related='currency_id.name', string="Currency Name", help="The name of this invoice's currency") #This field is used in the "invisible" condition field of the 'Print ISR' button. + l10n_ch_currency_name = fields.Char(related='currency_id.name', readonly=False, string="Currency Name", help="The name of this invoice's currency") #This field is used in the "invisible" condition field of the 'Print ISR' button. @api.depends('partner_bank_id.bank_id.l10n_ch_postal_eur', 'partner_bank_id.bank_id.l10n_ch_postal_chf') def _compute_l10n_ch_isr_postal(self): diff --git a/addons/l10n_ch/models/account_journal.py b/addons/l10n_ch/models/account_journal.py index 4ad11b5d84c01c47b5f059185f23e8fc31de3821..a42e163a299ba0d77e0f33b4fe908b5dcc609880 100644 --- a/addons/l10n_ch/models/account_journal.py +++ b/addons/l10n_ch/models/account_journal.py @@ -13,7 +13,7 @@ class AccountJournal(models.Model): _inherit = 'account.journal' # creation of bank journals by giving the account number, allow craetion of the - l10n_ch_postal = fields.Char(related='bank_account_id.l10n_ch_postal') + l10n_ch_postal = fields.Char(related='bank_account_id.l10n_ch_postal', readonly=False) @api.model def create(self, vals): diff --git a/addons/l10n_ch/models/res_config_settings.py b/addons/l10n_ch/models/res_config_settings.py index 31bc5fc7bedec04deac9ef92cb7562b658bff142..0b972855e66928e210ef29f021e9ecbb61a2dcb8 100644 --- a/addons/l10n_ch/models/res_config_settings.py +++ b/addons/l10n_ch/models/res_config_settings.py @@ -8,13 +8,13 @@ class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' l10n_ch_isr_preprinted_account = fields.Boolean(string='Preprinted account', - related="company_id.l10n_ch_isr_preprinted_account") + related="company_id.l10n_ch_isr_preprinted_account", readonly=False) l10n_ch_isr_preprinted_bank = fields.Boolean(string='Preprinted bank', - related="company_id.l10n_ch_isr_preprinted_bank") + related="company_id.l10n_ch_isr_preprinted_bank", readonly=False) l10n_ch_isr_print_bank_location = fields.Boolean(string="Print bank on ISR", - related="company_id.l10n_ch_isr_print_bank_location", + related="company_id.l10n_ch_isr_print_bank_location", readonly=False, required=True) l10n_ch_isr_scan_line_left = fields.Float(string='Horizontal offset', - related="company_id.l10n_ch_isr_scan_line_left") + related="company_id.l10n_ch_isr_scan_line_left", readonly=False) l10n_ch_isr_scan_line_top = fields.Float(string='Vertical offset', - related="company_id.l10n_ch_isr_scan_line_top") + related="company_id.l10n_ch_isr_scan_line_top", readonly=False) diff --git a/addons/l10n_fr/models/l10n_fr.py b/addons/l10n_fr/models/l10n_fr.py index dfa228db3f53766c748979c7cc0ce673840823be..16d7709ab118c55bfad9b035a4ef64bf68075a6a 100644 --- a/addons/l10n_fr/models/l10n_fr.py +++ b/addons/l10n_fr/models/l10n_fr.py @@ -7,7 +7,7 @@ from odoo import fields, models class ResCompany(models.Model): _inherit = 'res.company' - siret = fields.Char(related='partner_id.siret', string='SIRET', size=14) + siret = fields.Char(related='partner_id.siret', string='SIRET', size=14, readonly=False) ape = fields.Char(string='APE') class ResPartner(models.Model): diff --git a/addons/l10n_fr_hr_payroll/models/res_config_settings.py b/addons/l10n_fr_hr_payroll/models/res_config_settings.py index 1ae73b14698e623acbc551413aaea55eba30e250..8f70e8636d9e27dc6bf12a865cf4d884954129c7 100644 --- a/addons/l10n_fr_hr_payroll/models/res_config_settings.py +++ b/addons/l10n_fr_hr_payroll/models/res_config_settings.py @@ -7,8 +7,8 @@ from odoo import fields, models class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' - plafond_secu = fields.Float(related='company_id.plafond_secu', string="Plafond de la Securite Sociale") - nombre_employes = fields.Integer(related='company_id.nombre_employes', string="Nombre d'employes") - cotisation_prevoyance = fields.Float(related='company_id.cotisation_prevoyance', string='Cotisation Patronale Prevoyance') - org_ss = fields.Char(related='company_id.org_ss', string="Organisme de securite sociale") - conv_coll = fields.Char(related='company_id.conv_coll', string="Convention collective") + plafond_secu = fields.Float(related='company_id.plafond_secu', string="Plafond de la Securite Sociale", readonly=False) + nombre_employes = fields.Integer(related='company_id.nombre_employes', string="Nombre d'employes", readonly=False) + cotisation_prevoyance = fields.Float(related='company_id.cotisation_prevoyance', string='Cotisation Patronale Prevoyance', readonly=False) + org_ss = fields.Char(related='company_id.org_ss', string="Organisme de securite sociale", readonly=False) + conv_coll = fields.Char(related='company_id.conv_coll', string="Convention collective", readonly=False) diff --git a/addons/l10n_in_hr_payroll/models/l10n_in_hr_payroll.py b/addons/l10n_in_hr_payroll/models/l10n_in_hr_payroll.py index 8421058a60d1fcec344ed45d732ac3069009215e..25fbe7da64ac77a0f371f3cce810a1cbd5ce37f0 100644 --- a/addons/l10n_in_hr_payroll/models/l10n_in_hr_payroll.py +++ b/addons/l10n_in_hr_payroll/models/l10n_in_hr_payroll.py @@ -168,8 +168,8 @@ class HrPayrollAdviceLine(models.Model): employee_id = fields.Many2one('hr.employee', string='Employee', required=True) bysal = fields.Float(string='By Salary', digits=dp.get_precision('Payroll')) debit_credit = fields.Char(string='C/D', default='C') - company_id = fields.Many2one('res.company', related='advice_id.company_id', string='Company', store=True) - ifsc = fields.Boolean(related='advice_id.neft', string='IFSC') + company_id = fields.Many2one('res.company', related='advice_id.company_id', string='Company', store=True, readonly=False) + ifsc = fields.Boolean(related='advice_id.neft', string='IFSC', readonly=False) @api.onchange('employee_id') def onchange_employee_id(self): diff --git a/addons/l10n_sg/models/res_company.py b/addons/l10n_sg/models/res_company.py index 8c560b59a121d6411a77cb602c37ce370560667b..e63b6621069227a5f77fe54c4e9d89f1c536fdd3 100644 --- a/addons/l10n_sg/models/res_company.py +++ b/addons/l10n_sg/models/res_company.py @@ -7,4 +7,4 @@ class ResCompany(models.Model): _description = 'Companies' _inherit = 'res.company' - l10n_sg_unique_entity_number = fields.Char(string='UEN', related="partner_id.l10n_sg_unique_entity_number") + l10n_sg_unique_entity_number = fields.Char(string='UEN', related="partner_id.l10n_sg_unique_entity_number", readonly=False) diff --git a/addons/lunch/models/lunch.py b/addons/lunch/models/lunch.py index 36cd7d1408c4705ed1c9335572a238673893fca1..facc3d44809dfaaa1188cfff66e269e1276bf6e1 100644 --- a/addons/lunch/models/lunch.py +++ b/addons/lunch/models/lunch.py @@ -46,7 +46,7 @@ class LunchOrder(models.Model): 'Status', readonly=True, index=True, copy=False, compute='_compute_order_state', store=True) alerts = fields.Text(compute='_compute_alerts_get', string="Alerts") - company_id = fields.Many2one('res.company', related='user_id.company_id', store=True) + company_id = fields.Many2one('res.company', related='user_id.company_id', store=True, readonly=False) currency_id = fields.Many2one('res.currency', related='company_id.currency_id', readonly=True, store=True) cash_move_balance = fields.Monetary(compute='_compute_cash_move_balance', multi='cash_move_balance') balance_visible = fields.Boolean(compute='_compute_cash_move_balance', multi='cash_move_balance') @@ -183,7 +183,7 @@ class LunchOrderLine(models.Model): ('cancelled', 'Cancelled')], 'Status', readonly=True, index=True, default='new') cashmove = fields.One2many('lunch.cashmove', 'order_id', 'Cash Move') - currency_id = fields.Many2one('res.currency', related='order_id.currency_id') + currency_id = fields.Many2one('res.currency', related='order_id.currency_id', readonly=False) def _check_supplier_availibility(self): products = self.mapped('product_id') diff --git a/addons/mail/models/mail_activity.py b/addons/mail/models/mail_activity.py index 2f72a277396e215d98ce41e295c6e428a53e97d3..4e41d9b6967076345670e6b8084e144a50e130d5 100644 --- a/addons/mail/models/mail_activity.py +++ b/addons/mail/models/mail_activity.py @@ -122,9 +122,9 @@ class MailActivity(models.Model): activity_type_id = fields.Many2one( 'mail.activity.type', 'Activity', domain="['|', ('res_model_id', '=', False), ('res_model_id', '=', res_model_id)]", ondelete='restrict') - activity_category = fields.Selection(related='activity_type_id.category') - activity_decoration = fields.Selection(related='activity_type_id.decoration_type') - icon = fields.Char('Icon', related='activity_type_id.icon') + activity_category = fields.Selection(related='activity_type_id.category', readonly=False) + activity_decoration = fields.Selection(related='activity_type_id.decoration_type', readonly=False) + icon = fields.Char('Icon', related='activity_type_id.icon', readonly=False) summary = fields.Char('Summary') note = fields.Html('Note') feedback = fields.Html('Feedback') @@ -152,8 +152,8 @@ class MailActivity(models.Model): 'Next activities available', compute='_compute_has_recommended_activities', help='Technical field for UX purpose') - mail_template_ids = fields.Many2many(related='activity_type_id.mail_template_ids') - force_next = fields.Boolean(related='activity_type_id.force_next') + mail_template_ids = fields.Many2many(related='activity_type_id.mail_template_ids', readonly=False) + force_next = fields.Boolean(related='activity_type_id.force_next', readonly=False) @api.multi @api.onchange('previous_activity_type_id') @@ -502,12 +502,12 @@ class MailActivityMixin(models.AbstractModel): 'Today: Activity date is today\nPlanned: Future activities.') activity_user_id = fields.Many2one( 'res.users', 'Responsible User', - related='activity_ids.user_id', + related='activity_ids.user_id', readonly=False, search='_search_activity_user_id', groups="base.group_user") activity_type_id = fields.Many2one( 'mail.activity.type', 'Next Activity Type', - related='activity_ids.activity_type_id', + related='activity_ids.activity_type_id', readonly=False, search='_search_activity_type_id', groups="base.group_user") activity_date_deadline = fields.Date( @@ -517,7 +517,7 @@ class MailActivityMixin(models.AbstractModel): groups="base.group_user") activity_summary = fields.Char( 'Next Activity Summary', - related='activity_ids.summary', + related='activity_ids.summary', readonly=False, search='_search_activity_summary', groups="base.group_user",) diff --git a/addons/mail/models/mail_channel.py b/addons/mail/models/mail_channel.py index d1c3c3f6fa6d026fb83e659351d1a00892d86cef..d2a375f4fc9c56eeaa1ad32cc89214a693064e88 100644 --- a/addons/mail/models/mail_channel.py +++ b/addons/mail/models/mail_channel.py @@ -27,7 +27,7 @@ class ChannelPartner(models.Model): _primary_email = ['partner_email'] partner_id = fields.Many2one('res.partner', string='Recipient', ondelete='cascade') - partner_email = fields.Char('Email', related='partner_id.email') + partner_email = fields.Char('Email', related='partner_id.email', readonly=False) channel_id = fields.Many2one('mail.channel', string='Channel', ondelete='cascade') seen_message_id = fields.Many2one('mail.message', string='Last Seen') fold_state = fields.Selection([('open', 'Open'), ('folded', 'Folded'), ('closed', 'Closed')], string='Conversation Fold State', default='open') diff --git a/addons/mail/models/mail_message.py b/addons/mail/models/mail_message.py index fa298bf3c5a47dd70fb6b0413e1e7ba344678b3d..39ed664168768b411e5e44949d15a386445be92b 100644 --- a/addons/mail/models/mail_message.py +++ b/addons/mail/models/mail_message.py @@ -76,7 +76,7 @@ class Message(models.Model): 'res.partner', 'Author', index=True, ondelete='set null', default=_get_default_author, help="Author of the message. If not set, email_from may hold an email address that did not match any partner.") - author_avatar = fields.Binary("Author's avatar", related='author_id.image_small') + author_avatar = fields.Binary("Author's avatar", related='author_id.image_small', readonly=False) # recipients: include inactive partners (they may have been archived after # the message was sent, but they should remain visible in the relation) partner_ids = fields.Many2many('res.partner', string='Recipients', diff --git a/addons/mail/models/res_users.py b/addons/mail/models/res_users.py index 18da52a96fcc9950256216a25f60ea01398420f0..495b9ae8722158ede95bd0f868bc739f8e1cb443 100644 --- a/addons/mail/models/res_users.py +++ b/addons/mail/models/res_users.py @@ -24,7 +24,7 @@ class Users(models.Model): alias_contact = fields.Selection([ ('everyone', 'Everyone'), ('partners', 'Authenticated Partners'), - ('followers', 'Followers only')], string='Alias Contact Security', related='alias_id.alias_contact') + ('followers', 'Followers only')], string='Alias Contact Security', related='alias_id.alias_contact', readonly=False) notification_type = fields.Selection([ ('email', 'Handle by Emails'), ('inbox', 'Handle in Odoo')], diff --git a/addons/mail/wizard/mail_resend_message.py b/addons/mail/wizard/mail_resend_message.py index 4a76e40be97a7269b0876455ba80f3ae6ba4fba7..c8ea6bb73c3d903d8931ac5f7dad0267bbe7a1e4 100644 --- a/addons/mail/wizard/mail_resend_message.py +++ b/addons/mail/wizard/mail_resend_message.py @@ -101,8 +101,8 @@ class PartnerResend(models.TransientModel): _description = 'Partner with additionnal information for mail resend' partner_id = fields.Many2one('res.partner', string='Partner', required=True, ondelete='cascade') - name = fields.Char(related="partner_id.name", related_sudo=False) - email = fields.Char(related="partner_id.email", related_sudo=False) + name = fields.Char(related="partner_id.name", related_sudo=False, readonly=False) + email = fields.Char(related="partner_id.email", related_sudo=False, readonly=False) resend = fields.Boolean(string="Send Again", default=True) resend_wizard_id = fields.Many2one('mail.resend.message', string="Resend wizard") message = fields.Char(string="Help message") diff --git a/addons/mass_mailing/models/mass_mailing.py b/addons/mass_mailing/models/mass_mailing.py index 2005575b2167f42e0331ae2e05cd7b4ff69c9a45..c26a9bab5a70c51ed56178da7defbfc4965e203c 100644 --- a/addons/mass_mailing/models/mass_mailing.py +++ b/addons/mass_mailing/models/mass_mailing.py @@ -54,9 +54,9 @@ class MassMailingContactListRel(models.Model): opt_out = fields.Boolean(string='Opt Out', help='The contact has chosen not to receive mails anymore from this list', default=False) unsubscription_date = fields.Datetime(string='Unsubscription Date') - contact_count = fields.Integer(related='list_id.contact_nbr', store=False) - message_bounce = fields.Integer(related='contact_id.message_bounce', store=False) - is_blacklisted = fields.Boolean(related='contact_id.is_blacklisted', store=False) + contact_count = fields.Integer(related='list_id.contact_nbr', store=False, readonly=False) + message_bounce = fields.Integer(related='contact_id.message_bounce', store=False, readonly=False) + is_blacklisted = fields.Boolean(related='contact_id.is_blacklisted', store=False, readonly=False) _sql_constraints = [ ('unique_contact_list', 'unique (contact_id, list_id)', diff --git a/addons/mrp/models/mrp_bom.py b/addons/mrp/models/mrp_bom.py index a3cb538229d418b317fb13ebdda1b9b6248b44fc..fcab8f82015f9b5cce426d3c7b6a1f9b87a6933c 100644 --- a/addons/mrp/models/mrp_bom.py +++ b/addons/mrp/models/mrp_bom.py @@ -213,7 +213,7 @@ class MrpBomLine(models.Model): product_id = fields.Many2one( 'product.product', 'Component', required=True) - product_tmpl_id = fields.Many2one('product.template', 'Product Template', related='product_id.product_tmpl_id') + product_tmpl_id = fields.Many2one('product.template', 'Product Template', related='product_id.product_tmpl_id', readonly=False) product_qty = fields.Float( 'Quantity', default=1.0, digits=dp.get_precision('Product Unit of Measure'), required=True) @@ -227,7 +227,7 @@ class MrpBomLine(models.Model): help="Gives the sequence order when displaying.") routing_id = fields.Many2one( 'mrp.routing', 'Routing', - related='bom_id.routing_id', store=True, + related='bom_id.routing_id', store=True, readonly=False, help="The list of operations to produce the finished product. The routing is mainly used to " "compute work center costs during operations and to plan future loads on work centers " "based on production planning.") diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index c3c8465e01f7cb1fd665e0744c0a0f7b9c02746b..2896c4cef49104d265ef3d021f369e01c5b134ba 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -52,7 +52,7 @@ class MrpProduction(models.Model): domain=[('type', 'in', ['product', 'consu'])], readonly=True, required=True, states={'confirmed': [('readonly', False)]}) - product_tmpl_id = fields.Many2one('product.template', 'Product Template', related='product_id.product_tmpl_id') + product_tmpl_id = fields.Many2one('product.template', 'Product Template', related='product_id.product_tmpl_id', readonly=False) product_qty = fields.Float( 'Quantity To Produce', default=1.0, digits=dp.get_precision('Product Unit of Measure'), @@ -163,7 +163,7 @@ class MrpProduction(models.Model): readonly=True, states={'confirmed': [('readonly', False)]}, default='1') is_locked = fields.Boolean('Is Locked', default=True, copy=False) show_final_lots = fields.Boolean('Show Final Lots', compute='_compute_show_lots') - production_location_id = fields.Many2one('stock.location', "Production Location", related='product_id.property_stock_production') + production_location_id = fields.Many2one('stock.location', "Production Location", related='product_id.property_stock_production', readonly=False) picking_ids = fields.Many2many('stock.picking', compute='_compute_picking_ids', string='Picking associated to this manufacturing order') delivery_count = fields.Integer(string='Delivery Orders', compute='_compute_picking_ids') diff --git a/addons/mrp/models/mrp_workcenter.py b/addons/mrp/models/mrp_workcenter.py index 2d9aa26b7fd44318f450e8fc09cdf33e8930c5eb..be92616c509050a068bfde7f0232b2d87f465245 100644 --- a/addons/mrp/models/mrp_workcenter.py +++ b/addons/mrp/models/mrp_workcenter.py @@ -14,9 +14,9 @@ class MrpWorkcenter(models.Model): _inherit = ['resource.mixin'] # resource - name = fields.Char('Work Center', related='resource_id.name', store=True) - time_efficiency = fields.Float('Time Efficiency', related='resource_id.time_efficiency', default=100, store=True) - active = fields.Boolean('Active', related='resource_id.active', default=True, store=True) + name = fields.Char('Work Center', related='resource_id.name', store=True, readonly=False) + time_efficiency = fields.Float('Time Efficiency', related='resource_id.time_efficiency', default=100, store=True, readonly=False) + active = fields.Boolean('Active', related='resource_id.active', default=True, store=True, readonly=False) code = fields.Char('Code', copy=False) note = fields.Text( @@ -205,7 +205,7 @@ class MrpWorkcenterProductivityLoss(models.Model): sequence = fields.Integer('Sequence', default=1) manual = fields.Boolean('Is a Blocking Reason', default=True) loss_id = fields.Many2one('mrp.workcenter.productivity.loss.type', domain=([('loss_type', 'in', ['quality', 'availability'])]), string='Category') - loss_type = fields.Selection(string='Effectiveness Category', related='loss_id.loss_type', store=True) + loss_type = fields.Selection(string='Effectiveness Category', related='loss_id.loss_type', store=True, readonly=False) class MrpWorkcenterProductivity(models.Model): @@ -224,7 +224,7 @@ class MrpWorkcenterProductivity(models.Model): 'mrp.workcenter.productivity.loss', "Loss Reason", ondelete='restrict', required=True) loss_type = fields.Selection( - "Effectiveness", related='loss_id.loss_type', store=True) + "Effectiveness", related='loss_id.loss_type', store=True, readonly=False) description = fields.Text('Description') date_start = fields.Datetime('Start Date', default=fields.Datetime.now, required=True) date_end = fields.Datetime('End Date') diff --git a/addons/mrp/models/mrp_workorder.py b/addons/mrp/models/mrp_workorder.py index ed55bf176c961ee22ec20b03ba71ed0f5cbd7267..b12d0eb6e0aac2648da9cf9c895dc1d8ceac59e3 100644 --- a/addons/mrp/models/mrp_workorder.py +++ b/addons/mrp/models/mrp_workorder.py @@ -23,7 +23,7 @@ class MrpWorkorder(models.Model): 'mrp.workcenter', 'Work Center', required=True, states={'done': [('readonly', True)], 'cancel': [('readonly', True)]}) working_state = fields.Selection( - 'Workcenter Status', related='workcenter_id.working_state', + 'Workcenter Status', related='workcenter_id.working_state', readonly=False, help='Technical: used in views only') production_id = fields.Many2one( @@ -47,7 +47,7 @@ class MrpWorkorder(models.Model): related='production_id.state', help='Technical: used in views only.') product_tracking = fields.Selection( - 'Product Tracking', related='production_id.product_id.tracking', + 'Product Tracking', related='production_id.product_id.tracking', readonly=False, help='Technical: used in views only.') qty_production = fields.Float('Original Production Quantity', readonly=True, related='production_id.product_qty') qty_remaining = fields.Float('Quantity To Be Produced', compute='_compute_qty_remaining', digits=dp.get_precision('Product Unit of Measure')) @@ -124,7 +124,7 @@ class MrpWorkorder(models.Model): next_work_order_id = fields.Many2one('mrp.workorder', "Next Work Order") scrap_ids = fields.One2many('stock.scrap', 'workorder_id') scrap_count = fields.Integer(compute='_compute_scrap_move_count', string='Scrap Move') - production_date = fields.Datetime('Production Date', related='production_id.date_planned_start', store=True) + production_date = fields.Datetime('Production Date', related='production_id.date_planned_start', store=True, readonly=False) color = fields.Integer('Color', compute='_compute_color') capacity = fields.Float( 'Capacity', default=1.0, diff --git a/addons/mrp/models/res_config_settings.py b/addons/mrp/models/res_config_settings.py index 5445a0b3fa3f9b843f8ae4dc434d3e7e5be504f5..5e47515b1f3a82aa81995b9a7c1cd0acc27d2697 100644 --- a/addons/mrp/models/res_config_settings.py +++ b/addons/mrp/models/res_config_settings.py @@ -7,7 +7,7 @@ from odoo import api, fields, models class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' - manufacturing_lead = fields.Float(related='company_id.manufacturing_lead', string="Manufacturing Lead Time") + manufacturing_lead = fields.Float(related='company_id.manufacturing_lead', string="Manufacturing Lead Time", readonly=False) use_manufacturing_lead = fields.Boolean(string="Default Manufacturing Lead Time", config_parameter='mrp.use_manufacturing_lead', oldname='default_use_manufacturing_lead') module_mrp_byproduct = fields.Boolean("By-Products") module_mrp_mps = fields.Boolean("Master Production Schedule") diff --git a/addons/mrp/models/stock_move.py b/addons/mrp/models/stock_move.py index b76a77ccc440fd3fac103145c88cc7d028ecbadc..83444b708a7ed8c286f3ca5892f2d293ece55eb9 100644 --- a/addons/mrp/models/stock_move.py +++ b/addons/mrp/models/stock_move.py @@ -17,7 +17,7 @@ class StockMoveLine(models.Model): 'Quantity Finished Product', digits=dp.get_precision('Product Unit of Measure'), help="Informative, not used in matching") done_wo = fields.Boolean('Done for Work Order', default=True, help="Technical Field which is False when temporarily filled in in work order") # TDE FIXME: naming - done_move = fields.Boolean('Move Done', related='move_id.is_done', store=True) # TDE FIXME: naming + done_move = fields.Boolean('Move Done', related='move_id.is_done', readonly=False, store=True) # TDE FIXME: naming def _get_similar_move_lines(self): lines = super(StockMoveLine, self)._get_similar_move_lines() diff --git a/addons/mrp/wizard/mrp_product_produce.py b/addons/mrp/wizard/mrp_product_produce.py index 6cd21a094f504f86d663b7344ea8c464dce55846..aaea368454ed414f5257f46eddc5bc9f6aaeaeed 100644 --- a/addons/mrp/wizard/mrp_product_produce.py +++ b/addons/mrp/wizard/mrp_product_produce.py @@ -46,7 +46,7 @@ class MrpProductProduce(models.TransientModel): product_uom_id = fields.Many2one('uom.uom', 'Unit of Measure') lot_id = fields.Many2one('stock.production.lot', string='Lot/Serial Number') produce_line_ids = fields.One2many('mrp.product.produce.line', 'product_produce_id', string='Product to Track') - product_tracking = fields.Selection(related="product_id.tracking") + product_tracking = fields.Selection(related="product_id.tracking", readonly=False) @api.multi def do_produce(self): @@ -172,7 +172,7 @@ class MrpProductProduceLine(models.TransientModel): product_produce_id = fields.Many2one('mrp.product.produce') product_id = fields.Many2one('product.product', 'Product') - product_tracking = fields.Selection(related="product_id.tracking") + product_tracking = fields.Selection(related="product_id.tracking", readonly=False) lot_id = fields.Many2one('stock.production.lot', 'Lot/Serial Number') qty_to_consume = fields.Float('To Consume', digits=dp.get_precision('Product Unit of Measure')) product_uom_id = fields.Many2one('uom.uom', 'Unit of Measure') diff --git a/addons/pad/models/res_config_settings.py b/addons/pad/models/res_config_settings.py index 939bb10e934508bd3a9a066a694a8c245df743bd..a89abe3601da58e34940453484526d3bcac1ca7e 100644 --- a/addons/pad/models/res_config_settings.py +++ b/addons/pad/models/res_config_settings.py @@ -7,5 +7,5 @@ from odoo import fields, models class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' - pad_server = fields.Char(related='company_id.pad_server', string="Pad Server *") - pad_key = fields.Char(related='company_id.pad_key', string="Pad Api Key *") + pad_server = fields.Char(related='company_id.pad_server', string="Pad Server *", readonly=False) + pad_key = fields.Char(related='company_id.pad_key', string="Pad Api Key *", readonly=False) diff --git a/addons/payment/models/payment_acquirer.py b/addons/payment/models/payment_acquirer.py index 0016e41ed62611e5e103373ec2ae4ec9f1996e4f..93efd9212aaa3d1a544d2693f483c70551c527d0 100644 --- a/addons/payment/models/payment_acquirer.py +++ b/addons/payment/models/payment_acquirer.py @@ -147,7 +147,7 @@ class PaymentAcquirer(models.Model): # TDE FIXME: remove that brol module_id = fields.Many2one('ir.module.module', string='Corresponding Module') - module_state = fields.Selection(selection=ir_module.STATES, string='Installation State', related='module_id.state') + module_state = fields.Selection(selection=ir_module.STATES, string='Installation State', related='module_id.state', readonly=False) image = fields.Binary( "Image", attachment=True, @@ -168,7 +168,7 @@ class PaymentAcquirer(models.Model): ('s2s','Payment from Odoo')], default='form', required=True, string='Payment Flow', help="""Note: Subscriptions does not take this field in account, it uses server to server by default.""") - inbound_payment_method_ids = fields.Many2many('account.payment.method', related='journal_id.inbound_payment_method_ids') + inbound_payment_method_ids = fields.Many2many('account.payment.method', related='journal_id.inbound_payment_method_ids', readonly=False) @api.onchange('payment_flow') def _onchange_payment_flow(self): diff --git a/addons/payment_authorize/models/payment.py b/addons/payment_authorize/models/payment.py index 2cb98f74b24d30a436ef4a7cf2489c378ff67fdb..c1380db1fd6dfaa0fe65eb1cf50c2fce6d3c0211 100644 --- a/addons/payment_authorize/models/payment.py +++ b/addons/payment_authorize/models/payment.py @@ -343,8 +343,8 @@ class PaymentToken(models.Model): authorize_profile = fields.Char(string='Authorize.net Profile ID', help='This contains the unique reference ' 'for this partner/payment token combination in the Authorize.net backend') - provider = fields.Selection(string='Provider', related='acquirer_id.provider') - save_token = fields.Selection(string='Save Cards', related='acquirer_id.save_token') + provider = fields.Selection(string='Provider', related='acquirer_id.provider', readonly=False) + save_token = fields.Selection(string='Save Cards', related='acquirer_id.save_token', readonly=False) @api.model def authorize_create(self, values): diff --git a/addons/point_of_sale/models/pos_config.py b/addons/point_of_sale/models/pos_config.py index 8e3156c1bf63546a4b42c72da62df1e30888bce2..8411e864faa0a3dcfb5efa537c9c2482303bc802 100644 --- a/addons/point_of_sale/models/pos_config.py +++ b/addons/point_of_sale/models/pos_config.py @@ -71,7 +71,7 @@ class PosConfig(models.Model): 'pos_config_id', 'journal_id', string='Available Payment Methods', domain="[('journal_user', '=', True ), ('type', 'in', ['bank', 'cash'])]",) picking_type_id = fields.Many2one('stock.picking.type', string='Operation Type') - use_existing_lots = fields.Boolean(related='picking_type_id.use_existing_lots') + use_existing_lots = fields.Boolean(related='picking_type_id.use_existing_lots', readonly=False) stock_location_id = fields.Many2one( 'stock.location', string='Stock Location', domain=[('usage', '=', 'internal')], required=True, default=_get_default_location) diff --git a/addons/point_of_sale/models/pos_order.py b/addons/point_of_sale/models/pos_order.py index e7c7cb70b1ad4933bfc9855b73d287a27e2f8669..fc52d816c4941bcf4958ac4a30b1717748ffc933 100644 --- a/addons/point_of_sale/models/pos_order.py +++ b/addons/point_of_sale/models/pos_order.py @@ -504,8 +504,8 @@ class PosOrder(models.Model): 'pos.session', string='Session', required=True, index=True, domain="[('state', '=', 'opened')]", states={'draft': [('readonly', False)]}, readonly=True, default=_default_session) - config_id = fields.Many2one('pos.config', related='session_id.config_id', string="Point of Sale") - invoice_group = fields.Boolean(related="config_id.module_account") + config_id = fields.Many2one('pos.config', related='session_id.config_id', string="Point of Sale", readonly=False) + invoice_group = fields.Boolean(related="config_id.module_account", readonly=False) state = fields.Selection( [('draft', 'New'), ('cancel', 'Cancelled'), ('paid', 'Paid'), ('done', 'Posted'), ('invoiced', 'Invoiced')], 'Status', readonly=True, copy=False, default='draft') @@ -513,7 +513,7 @@ class PosOrder(models.Model): invoice_id = fields.Many2one('account.invoice', string='Invoice', copy=False) account_move = fields.Many2one('account.move', string='Journal Entry', readonly=True, copy=False) picking_id = fields.Many2one('stock.picking', string='Picking', readonly=True, copy=False) - picking_type_id = fields.Many2one('stock.picking.type', related='session_id.config_id.picking_type_id', string="Operation Type") + picking_type_id = fields.Many2one('stock.picking.type', related='session_id.config_id.picking_type_id', string="Operation Type", readonly=False) location_id = fields.Many2one( comodel_name='stock.location', related='session_id.config_id.stock_location_id', @@ -1056,9 +1056,9 @@ class PosOrderLineLot(models.Model): _description = "Specify product lot/serial number in pos order line" pos_order_line_id = fields.Many2one('pos.order.line') - order_id = fields.Many2one('pos.order', related="pos_order_line_id.order_id") + order_id = fields.Many2one('pos.order', related="pos_order_line_id.order_id", readonly=False) lot_name = fields.Char('Lot Name') - product_id = fields.Many2one('product.product', related='pos_order_line_id.product_id') + product_id = fields.Many2one('product.product', related='pos_order_line_id.product_id', readonly=False) class ReportSaleDetails(models.AbstractModel): diff --git a/addons/point_of_sale/models/pos_session.py b/addons/point_of_sale/models/pos_session.py index 8b6ee9aef2e9c9375a4545bff6e72f51a3f4a371..aabcb4307d483c81d84cac3130831eae1b66b6cd 100644 --- a/addons/point_of_sale/models/pos_session.py +++ b/addons/point_of_sale/models/pos_session.py @@ -55,7 +55,7 @@ class PosSession(models.Model): readonly=True, states={'opening_control': [('readonly', False)]}, default=lambda self: self.env.uid) - currency_id = fields.Many2one('res.currency', related='config_id.currency_id', string="Currency") + currency_id = fields.Many2one('res.currency', related='config_id.currency_id', string="Currency", readonly=False) start_at = fields.Datetime(string='Opening Date', readonly=True) stop_at = fields.Datetime(string='Closing Date', readonly=True, copy=False) diff --git a/addons/point_of_sale/models/product.py b/addons/point_of_sale/models/product.py index 57e5bf6649020c5768186581908c52e690ffa4a3..b5cd2b2bbf51c9bdcfb2d76c37c4759fb63a22b0 100644 --- a/addons/point_of_sale/models/product.py +++ b/addons/point_of_sale/models/product.py @@ -49,4 +49,4 @@ class UomCateg(models.Model): class Uom(models.Model): _inherit = 'uom.uom' - is_pos_groupable = fields.Boolean(related='category_id.is_pos_groupable') + is_pos_groupable = fields.Boolean(related='category_id.is_pos_groupable', readonly=False) diff --git a/addons/point_of_sale/models/res_config_settings.py b/addons/point_of_sale/models/res_config_settings.py index 14acf115ba88230342a49fe7b4ea6fdab8c9ff04..cda8fe38f764d263c40e7406844f1dc149f3bfd7 100644 --- a/addons/point_of_sale/models/res_config_settings.py +++ b/addons/point_of_sale/models/res_config_settings.py @@ -6,7 +6,7 @@ from odoo import api, fields, models class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' - sale_tax_id = fields.Many2one('account.tax', string="Default Sale Tax", related='company_id.account_sale_tax_id') + sale_tax_id = fields.Many2one('account.tax', string="Default Sale Tax", related='company_id.account_sale_tax_id', readonly=False) module_pos_mercury = fields.Boolean(string="Integrated Card Payments", help="The transactions are processed by Vantiv. Set your Vantiv credentials on the related payment journal.") pos_sales_price = fields.Boolean("Multiple Product Prices", config_parameter='point_of_sale.pos_sales_price') pos_pricelist_setting = fields.Selection([ diff --git a/addons/product/models/product.py b/addons/product/models/product.py index 0bad75eec379b6b920e3c616bda4dd66343adb2e..0649bc10ced8cf91386b716fa3dc87a05e2ec339 100644 --- a/addons/product/models/product.py +++ b/addons/product/models/product.py @@ -626,7 +626,7 @@ class SupplierInfo(models.Model): 'Sequence', default=1, help="Assigns the priority to the list of product vendor.") product_uom = fields.Many2one( 'uom.uom', 'Unit of Measure', - readonly="1", related='product_tmpl_id.uom_po_id', + related='product_tmpl_id.uom_po_id', help="This comes from the product form.") min_qty = fields.Float( 'Minimal Quantity', default=0.0, required=True, @@ -649,7 +649,7 @@ class SupplierInfo(models.Model): product_tmpl_id = fields.Many2one( 'product.template', 'Product Template', index=True, ondelete='cascade', oldname='product_id') - product_variant_count = fields.Integer('Variant Count', related='product_tmpl_id.product_variant_count') + product_variant_count = fields.Integer('Variant Count', related='product_tmpl_id.product_variant_count', readonly=False) delay = fields.Integer( 'Delivery Lead Time', default=1, required=True, help="Lead time in days between the confirmation of the purchase order and the receipt of the products in your warehouse. Used by the scheduler for automatic computation of the purchase order planning.") diff --git a/addons/product/models/product_template.py b/addons/product/models/product_template.py index 636331219a6d50410990d079e2852d2d765113d9..5dfcec1b0636fb49808653d3b467775edc2867c0 100644 --- a/addons/product/models/product_template.py +++ b/addons/product/models/product_template.py @@ -69,7 +69,7 @@ class ProductTemplate(models.Model): digits=dp.get_precision('Product Price'), help="Price at which the product is sold to customers.") lst_price = fields.Float( - 'Public Price', related='list_price', + 'Public Price', related='list_price', readonly=False, digits=dp.get_precision('Product Price')) standard_price = fields.Float( 'Cost', compute='_compute_standard_price', @@ -123,7 +123,7 @@ class ProductTemplate(models.Model): '# Product Variants', compute='_compute_product_variant_count') # related to display product product information if is_product_variant - barcode = fields.Char('Barcode', oldname='ean13', related='product_variant_ids.barcode') + barcode = fields.Char('Barcode', oldname='ean13', related='product_variant_ids.barcode', readonly=False) default_code = fields.Char( 'Internal Reference', compute='_compute_default_code', inverse='_set_default_code', store=True) diff --git a/addons/product_expiry/models/stock_quant.py b/addons/product_expiry/models/stock_quant.py index 4dd0945aeefdd52e5acb9c76240eb5ca5e515984..af036fcdc3cc7700449b91c1ab7252102276bf4c 100644 --- a/addons/product_expiry/models/stock_quant.py +++ b/addons/product_expiry/models/stock_quant.py @@ -7,7 +7,7 @@ from odoo import api, fields, models class StockQuant(models.Model): _inherit = 'stock.quant' - removal_date = fields.Datetime(related='lot_id.removal_date', store=True) + removal_date = fields.Datetime(related='lot_id.removal_date', store=True, readonly=False) @api.model def _get_removal_strategy_order(self, removal_strategy): diff --git a/addons/project_timesheet_holidays/models/res_config_settings.py b/addons/project_timesheet_holidays/models/res_config_settings.py index 6e264971e769abe24357662ec729f76d88d3747f..60b56b39bae98ba39551a8702c4467e67e7f7f17 100644 --- a/addons/project_timesheet_holidays/models/res_config_settings.py +++ b/addons/project_timesheet_holidays/models/res_config_settings.py @@ -7,5 +7,5 @@ from odoo import fields, models class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' - leave_timesheet_project_id = fields.Many2one(related='company_id.leave_timesheet_project_id', string="Internal Project") - leave_timesheet_task_id = fields.Many2one(related='company_id.leave_timesheet_task_id', string="Leave Task") + leave_timesheet_project_id = fields.Many2one(related='company_id.leave_timesheet_project_id', string="Internal Project", readonly=False) + leave_timesheet_task_id = fields.Many2one(related='company_id.leave_timesheet_task_id', string="Leave Task", readonly=False) diff --git a/addons/purchase/models/purchase.py b/addons/purchase/models/purchase.py index 90ac6e930f121944eb0a77690daef6449be987a9..9b13a39b6e3747dc1ecd095cd880e5d28a5e8646 100644 --- a/addons/purchase/models/purchase.py +++ b/addons/purchase/models/purchase.py @@ -121,7 +121,7 @@ class PurchaseOrder(models.Model): payment_term_id = fields.Many2one('account.payment.term', 'Payment Terms') 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') + 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) company_id = fields.Many2one('res.company', 'Company', required=True, index=True, states=READONLY_STATES, default=lambda self: self.env.user.company_id.id) @@ -408,7 +408,7 @@ class PurchaseOrderLine(models.Model): product_uom = fields.Many2one('uom.uom', string='Product Unit of Measure', required=True) product_id = fields.Many2one('product.product', string='Product', domain=[('purchase_ok', '=', True)], change_default=True, required=True) product_image = fields.Binary( - 'Product Image', related="product_id.image", + 'Product Image', related="product_id.image", readonly=False, help="Non-stored related field to allow portal user to see the image of the product he has ordered") product_type = fields.Selection(related='product_id.type', readonly=True) price_unit = fields.Float(string='Unit Price', required=True, digits=dp.get_precision('Product Price')) @@ -421,7 +421,7 @@ class PurchaseOrderLine(models.Model): account_analytic_id = fields.Many2one('account.analytic.account', string='Analytic Account') analytic_tag_ids = fields.Many2many('account.analytic.tag', string='Analytic Tags') company_id = fields.Many2one('res.company', related='order_id.company_id', string='Company', store=True, readonly=True) - state = fields.Selection(related='order_id.state', store=True) + state = fields.Selection(related='order_id.state', store=True, readonly=False) invoice_lines = fields.One2many('account.invoice.line', 'purchase_line_id', string="Bill Lines", readonly=True, copy=False) diff --git a/addons/purchase/models/res_config_settings.py b/addons/purchase/models/res_config_settings.py index 47b183d144ff6042b9f10578bbd827c236c40adc..c7ef268c9594f7d318ab2eac19730c90f0695ec0 100644 --- a/addons/purchase/models/res_config_settings.py +++ b/addons/purchase/models/res_config_settings.py @@ -8,10 +8,10 @@ class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' lock_confirmed_po = fields.Boolean("Lock Confirmed Orders", default=lambda self: self.env.user.company_id.po_lock == 'lock') - po_lock = fields.Selection(related='company_id.po_lock', string="Purchase Order Modification *") + 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.user.company_id.po_double_validation == 'two_step') - po_double_validation = fields.Selection(related='company_id.po_double_validation', string="Levels of Approvals *") - po_double_validation_amount = fields.Monetary(related='company_id.po_double_validation_amount', string="Minimum Amount", currency_field='company_currency_id') + 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([ @@ -25,7 +25,7 @@ class ResConfigSettings(models.TransientModel): implied_group="purchase.group_manage_vendor_price") module_account_3way_match = fields.Boolean("3-way matching: purchases, receptions and bills") module_purchase_requisition = fields.Boolean("Purchase Agreements") - po_lead = fields.Float(related='company_id.po_lead') + po_lead = fields.Float(related='company_id.po_lead', readonly=False) use_po_lead = fields.Boolean( string="Security Lead Time for Purchase", oldname='default_new_po_lead', diff --git a/addons/purchase_requisition/models/purchase_requisition.py b/addons/purchase_requisition/models/purchase_requisition.py index 0c4ac448e4878898d3e8c72840f59194842e6774..80d122b6682644ebf28f187917c8c8a63a493363 100644 --- a/addons/purchase_requisition/models/purchase_requisition.py +++ b/addons/purchase_requisition/models/purchase_requisition.py @@ -184,7 +184,7 @@ class SupplierInfo(models.Model): _inherit = "product.supplierinfo" _order = 'sequence, purchase_requisition_id desc, min_qty desc, price' - purchase_requisition_id = fields.Many2one('purchase.requisition', related='purchase_requisition_line_id.requisition_id', string='Blanket order') + purchase_requisition_id = fields.Many2one('purchase.requisition', related='purchase_requisition_line_id.requisition_id', string='Blanket order', readonly=False) purchase_requisition_line_id = fields.Many2one('purchase.requisition.line') @@ -296,7 +296,7 @@ class PurchaseOrder(models.Model): _inherit = "purchase.order" requisition_id = fields.Many2one('purchase.requisition', string='Purchase Agreement', copy=False) - is_quantity_copy = fields.Selection(related='requisition_id.is_quantity_copy') + is_quantity_copy = fields.Selection(related='requisition_id.is_quantity_copy', readonly=False) @api.onchange('requisition_id') def _onchange_requisition_id(self): diff --git a/addons/rating/models/rating.py b/addons/rating/models/rating.py index 3aea681b0fbbdb8f1a84ea4072f808f37d8355f4..d0cda7f1bda34d1e7959441e4a0b82ee32451fcd 100644 --- a/addons/rating/models/rating.py +++ b/addons/rating/models/rating.py @@ -38,7 +38,7 @@ class Rating(models.Model): res_id = fields.Integer(string='Document', required=True, help="Identifier of the rated object", index=True) parent_res_name = fields.Char('Parent Document Name', compute='_compute_parent_res_name', store=True) parent_res_model_id = fields.Many2one('ir.model', 'Parent Related Document Model', index=True, ondelete='cascade') - parent_res_model = fields.Char('Parent Document Model', store=True, related='parent_res_model_id.model', index=True) + parent_res_model = fields.Char('Parent Document Model', store=True, related='parent_res_model_id.model', index=True, readonly=False) parent_res_id = fields.Integer('Parent Document', index=True) rated_partner_id = fields.Many2one('res.partner', string="Rated person", help="Owner of the rated resource") partner_id = fields.Many2one('res.partner', string='Customer', help="Author of the rating") @@ -139,8 +139,8 @@ class RatingMixin(models.AbstractModel): rating_ids = fields.One2many('rating.rating', 'res_id', string='Rating', domain=lambda self: [('res_model', '=', self._name)], auto_join=True) rating_last_value = fields.Float('Rating Last Value', compute='_compute_rating_last_value', compute_sudo=True, store=True) - rating_last_feedback = fields.Text('Rating Last Feedback', related='rating_ids.feedback') - rating_last_image = fields.Binary('Rating Last Image', related='rating_ids.rating_image') + rating_last_feedback = fields.Text('Rating Last Feedback', related='rating_ids.feedback', readonly=False) + rating_last_image = fields.Binary('Rating Last Image', related='rating_ids.rating_image', readonly=False) rating_count = fields.Integer('Rating count', compute="_compute_rating_count") @api.multi diff --git a/addons/repair/models/repair.py b/addons/repair/models/repair.py index 1302cb93a01cbde48c65c0841ac4db396c5b452e..de88001fb577aa590e2fec0282d029403e330780 100644 --- a/addons/repair/models/repair.py +++ b/addons/repair/models/repair.py @@ -114,7 +114,7 @@ class Repair(models.Model): amount_untaxed = fields.Float('Untaxed Amount', compute='_amount_untaxed', store=True) amount_tax = fields.Float('Taxes', compute='_amount_tax', store=True) amount_total = fields.Float('Total', compute='_amount_total', store=True) - tracking = fields.Selection('Product Tracking', related="product_id.tracking") + tracking = fields.Selection('Product Tracking', related="product_id.tracking", readonly=False) @api.one @api.depends('partner_id') diff --git a/addons/resource/models/res_users.py b/addons/resource/models/res_users.py index 9793a560da0890906678ac0bd471196d78850710..12290b916ec45d37e28f78ba0c0b4f5da4c90962 100644 --- a/addons/resource/models/res_users.py +++ b/addons/resource/models/res_users.py @@ -11,4 +11,4 @@ class ResUsers(models.Model): 'resource.resource', 'user_id', 'Resources') resource_calendar_id = fields.Many2one( 'resource.calendar', 'Default Working Hours', - related='resource_ids.calendar_id') + related='resource_ids.calendar_id', readonly=False) diff --git a/addons/resource/models/resource_mixin.py b/addons/resource/models/resource_mixin.py index c74db075395499f947cae121fe55393c9d51bbdc..7770efb46335006a8bad64038de34384be81ddf2 100644 --- a/addons/resource/models/resource_mixin.py +++ b/addons/resource/models/resource_mixin.py @@ -22,13 +22,13 @@ class ResourceMixin(models.AbstractModel): company_id = fields.Many2one( 'res.company', 'Company', default=lambda self: self.env['res.company']._company_default_get(), - index=True, related='resource_id.company_id', store=True) + index=True, related='resource_id.company_id', store=True, readonly=False) resource_calendar_id = fields.Many2one( 'resource.calendar', 'Working Hours', default=lambda self: self.env['res.company']._company_default_get().resource_calendar_id, - index=True, related='resource_id.calendar_id', store=True) + index=True, related='resource_id.calendar_id', store=True, readonly=False) tz = fields.Selection( - string='Timezone', related='resource_id.tz', + string='Timezone', related='resource_id.tz', readonly=False, help="This field is used in order to define in which timezone the resources will work.") @api.model diff --git a/addons/sale/models/res_config_settings.py b/addons/sale/models/res_config_settings.py index 71f2e83d656764f7e66fe213ef0054ac1a826cfc..0a5060483a47b610b8b1bd9904fe6762355aea67 100644 --- a/addons/sale/models/res_config_settings.py +++ b/addons/sale/models/res_config_settings.py @@ -7,18 +7,18 @@ from odoo import api, fields, models class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' - sale_note = fields.Text(related='company_id.sale_note', string="Terms & Conditions") + sale_note = fields.Text(related='company_id.sale_note', string="Terms & Conditions", readonly=False) use_sale_note = fields.Boolean( string='Default Terms & Conditions', oldname='default_use_sale_note', config_parameter='sale.use_sale_note') group_discount_per_so_line = fields.Boolean("Discounts", implied_group='sale.group_discount_per_so_line') module_sale_margin = fields.Boolean("Margins") - quotation_validity_days = fields.Integer(related='company_id.quotation_validity_days', string="Default Quotation Validity (Days)") + quotation_validity_days = fields.Integer(related='company_id.quotation_validity_days', string="Default Quotation Validity (Days)", readonly=False) use_quotation_validity_days = fields.Boolean("Default Quotation Validity", config_parameter='sale.use_quotation_validity_days') group_warning_sale = fields.Boolean("Sale Order Warnings", implied_group='sale.group_warning_sale') - portal_confirmation_sign = fields.Boolean(related='company_id.portal_confirmation_sign', string='Online Signature') - portal_confirmation_pay = fields.Boolean(related='company_id.portal_confirmation_pay', string='Online Payment') + portal_confirmation_sign = fields.Boolean(related='company_id.portal_confirmation_sign', string='Online Signature', readonly=False) + portal_confirmation_pay = fields.Boolean(related='company_id.portal_confirmation_pay', string='Online Payment', readonly=False) group_sale_delivery_address = fields.Boolean("Customer Addresses", implied_group='sale.group_delivery_invoice_address') multi_sales_price = fields.Boolean("Multiple Sales Prices per Product") multi_sales_price_method = fields.Selection([ diff --git a/addons/sale/models/sale.py b/addons/sale/models/sale.py index 13c8943094c16c3813d685d755b4f310d6981f50..4d184741d4fe3f9aa3c75e880afb0d87301be4f8 100644 --- a/addons/sale/models/sale.py +++ b/addons/sale/models/sale.py @@ -1136,7 +1136,7 @@ class SaleOrderLine(models.Model): # It allows keeping track of the extra_price associated to those attribute values and add them to the SO line description product_no_variant_attribute_values = fields.Many2many('product.template.attribute.value', string='Product attribute values that do not create variants') # Non-stored related field to allow portal user to see the image of the product he has ordered - product_image = fields.Binary('Product Image', related="product_id.image", store=False) + product_image = fields.Binary('Product Image', related="product_id.image", store=False, readonly=False) qty_delivered_method = fields.Selection([ ('manual', 'Manual'), @@ -1162,7 +1162,7 @@ class SaleOrderLine(models.Model): salesman_id = fields.Many2one(related='order_id.user_id', store=True, string='Salesperson', readonly=True) currency_id = fields.Many2one(related='order_id.currency_id', depends=['order_id'], store=True, string='Currency', readonly=True) company_id = fields.Many2one(related='order_id.company_id', string='Company', store=True, readonly=True) - order_partner_id = fields.Many2one(related='order_id.partner_id', store=True, string='Customer') + order_partner_id = fields.Many2one(related='order_id.partner_id', store=True, string='Customer', readonly=False) analytic_tag_ids = fields.Many2many('account.analytic.tag', string='Analytic Tags') analytic_line_ids = fields.One2many('account.analytic.line', 'so_line', string="Analytic lines") is_expense = fields.Boolean('Is expense', help="Is true if the sales order line comes from an expense or a vendor bills") diff --git a/addons/sale_quotation_builder/models/sale_order_template.py b/addons/sale_quotation_builder/models/sale_order_template.py index ba7aa199128c6cf1ec67273dffeb3a05c9abaad3..2147a0c088143a218e5be65e4b69c0cd79a0057c 100644 --- a/addons/sale_quotation_builder/models/sale_order_template.py +++ b/addons/sale_quotation_builder/models/sale_order_template.py @@ -23,7 +23,7 @@ class SaleOrderTemplate(models.Model): class SaleOrderTemplateLine(models.Model): _inherit = "sale.order.template.line" - website_description = fields.Html('Website Description', related='product_id.product_tmpl_id.quotation_only_description', translate=html_translate) + website_description = fields.Html('Website Description', related='product_id.product_tmpl_id.quotation_only_description', translate=html_translate, readonly=False) @api.onchange('product_id') def _onchange_product_id(self): diff --git a/addons/sale_stock/models/res_config_settings.py b/addons/sale_stock/models/res_config_settings.py index 5908814e9cf4a9bc398fdc22ba28c4e2bd545f1e..2a80982ba6bffc41679ba437425a44dd83f136cc 100644 --- a/addons/sale_stock/models/res_config_settings.py +++ b/addons/sale_stock/models/res_config_settings.py @@ -7,7 +7,7 @@ from odoo import api, fields, models class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' - security_lead = fields.Float(related='company_id.security_lead', string="Security Lead Time") + security_lead = fields.Float(related='company_id.security_lead', string="Security Lead Time", readonly=False) group_route_so_lines = fields.Boolean("Order-Specific Routes", implied_group='sale_stock.group_route_so_lines') group_display_incoterm = fields.Boolean("Incoterms", implied_group='sale_stock.group_display_incoterm') diff --git a/addons/sale_stock/models/stock.py b/addons/sale_stock/models/stock.py index c9fa2afb52b17c04ac0caeb082164cf87d8c373b..f622c61820e102e1e654ba73a64aa5f7d35a2988 100644 --- a/addons/sale_stock/models/stock.py +++ b/addons/sale_stock/models/stock.py @@ -63,7 +63,7 @@ class StockRule(models.Model): class StockPicking(models.Model): _inherit = 'stock.picking' - sale_id = fields.Many2one(related="group_id.sale_id", string="Sales Order", store=True) + sale_id = fields.Many2one(related="group_id.sale_id", string="Sales Order", store=True, readonly=False) def _log_less_quantities_than_expected(self, moves): diff --git a/addons/sale_timesheet/wizard/project_create_sale_order.py b/addons/sale_timesheet/wizard/project_create_sale_order.py index 781403dddbbafe27565b7a6a396a81d6a854813d..1062722fc12e6561fbb1be44e62e70f97dee7615 100644 --- a/addons/sale_timesheet/wizard/project_create_sale_order.py +++ b/addons/sale_timesheet/wizard/project_create_sale_order.py @@ -31,7 +31,7 @@ class ProjectCreateSalesOrder(models.TransientModel): partner_id = fields.Many2one('res.partner', string="Customer", domain=[('customer', '=', True)], required=True, help="Customer of the sales order") product_id = fields.Many2one('product.product', domain=[('type', '=', 'service'), ('invoice_policy', '=', 'delivery'), ('service_type', '=', 'timesheet')], string="Service", help="Product of the sales order item. Must be a service invoiced based on timesheets on tasks.") price_unit = fields.Float("Unit Price", help="Unit price of the sales order item.") - currency_id = fields.Many2one('res.currency', string="Currency", related='product_id.currency_id') + currency_id = fields.Many2one('res.currency', string="Currency", related='product_id.currency_id', readonly=False) billable_type = fields.Selection([ ('project_rate', 'At Project Rate'), @@ -201,7 +201,7 @@ class ProjectCreateSalesOrderLine(models.TransientModel): product_id = fields.Many2one('product.product', domain=[('type', '=', 'service'), ('invoice_policy', '=', 'delivery'), ('service_type', '=', 'timesheet')], string="Service", required=True, help="Product of the sales order item. Must be a service invoiced based on timesheets on tasks.") price_unit = fields.Float("Unit Price", default=1.0, help="Unit price of the sales order item.") - currency_id = fields.Many2one('res.currency', string="Currency", related='product_id.currency_id') + currency_id = fields.Many2one('res.currency', string="Currency", related='product_id.currency_id', readonly=False) employee_id = fields.Many2one('hr.employee', string="Employee", required=True, help="Employee that has timesheets on the project.") _sql_constraints = [ diff --git a/addons/snailmail/models/res_config_settings.py b/addons/snailmail/models/res_config_settings.py index 7b916ce0e1f6453c642586e3444399202b1a1553..bf79ec83c3d77912758127d4d093f296c66465ce 100644 --- a/addons/snailmail/models/res_config_settings.py +++ b/addons/snailmail/models/res_config_settings.py @@ -7,5 +7,5 @@ from odoo import fields, models class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' - snailmail_color = fields.Boolean(string='Print In Color', related='company_id.snailmail_color') - snailmail_duplex = fields.Boolean(string='Print Both sides', related='company_id.snailmail_duplex') + snailmail_color = fields.Boolean(string='Print In Color', related='company_id.snailmail_color', readonly=False) + snailmail_duplex = fields.Boolean(string='Print Both sides', related='company_id.snailmail_duplex', readonly=False) diff --git a/addons/snailmail_account/models/res_config_settings.py b/addons/snailmail_account/models/res_config_settings.py index 06a1eb9837352755b2e9c5d48b02c3c2c951702d..bab192ef4e19b45edd4341fde1b6ad88c1860d7e 100644 --- a/addons/snailmail_account/models/res_config_settings.py +++ b/addons/snailmail_account/models/res_config_settings.py @@ -7,4 +7,4 @@ from odoo import fields, models class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' - invoice_is_snailmail = fields.Boolean(string='Send by Post', related='company_id.invoice_is_snailmail') + invoice_is_snailmail = fields.Boolean(string='Send by Post', related='company_id.invoice_is_snailmail', readonly=False) diff --git a/addons/stock/models/product.py b/addons/stock/models/product.py index 2e8b73d3ee85ee8d252d9bcc46cc571dc5ab31c2..c6a65af4e76c073bf26923e2147c00891e6f7124 100644 --- a/addons/stock/models/product.py +++ b/addons/stock/models/product.py @@ -451,7 +451,7 @@ class ProductTemplate(models.Model): # TDE FIXME: seems only visible in a view - remove me ? route_from_categ_ids = fields.Many2many( relation="stock.location.route", string="Category Routes", - related='categ_id.total_route_ids') + related='categ_id.total_route_ids', readonly=False) def _is_cost_method_standard(self): return True diff --git a/addons/stock/models/res_config_settings.py b/addons/stock/models/res_config_settings.py index 544209a5cef60c8b7023c291ce60e349034c7774..ebf7d339d395470d1a13bce3dd6a418acb90b3d5 100644 --- a/addons/stock/models/res_config_settings.py +++ b/addons/stock/models/res_config_settings.py @@ -26,7 +26,7 @@ class ResConfigSettings(models.TransientModel): implied_group='stock.group_adv_location', help="Add and customize route operations to process product moves in your warehouse(s): e.g. unload > quality control > stock for incoming products, pick > pack > ship for outgoing products. \n You can also set putaway strategies on warehouse locations in order to send incoming products into specific child locations straight away (e.g. specific bins, racks).") group_warning_stock = fields.Boolean("Warnings for Stock", implied_group='stock.group_warning_stock') - propagation_minimum_delta = fields.Integer(related='company_id.propagation_minimum_delta', string="Minimum Delta for Propagation") + propagation_minimum_delta = fields.Integer(related='company_id.propagation_minimum_delta', string="Minimum Delta for Propagation", readonly=False) use_propagation_minimum_delta = fields.Boolean( string="No Rescheduling Propagation", oldname='default_new_propagation_minimum_delta', diff --git a/addons/stock/models/stock_inventory.py b/addons/stock/models/stock_inventory.py index 486431d1818f904dfb00b702b7747dd2d77318e3..1e66ccffe20dc5d29db8d22a9b604a366637dfc9 100644 --- a/addons/stock/models/stock_inventory.py +++ b/addons/stock/models/stock_inventory.py @@ -352,7 +352,7 @@ class InventoryLine(models.Model): 'Theoretical Quantity', compute='_compute_theoretical_qty', digits=dp.get_precision('Product Unit of Measure'), readonly=True, store=True) inventory_location_id = fields.Many2one( - 'stock.location', 'Inventory Location', related='inventory_id.location_id', related_sudo=False) + 'stock.location', 'Inventory Location', related='inventory_id.location_id', related_sudo=False, readonly=False) product_tracking = fields.Selection('Tracking', related='product_id.tracking', readonly=True) @api.one diff --git a/addons/stock/models/stock_move.py b/addons/stock/models/stock_move.py index 0b10b239fac67ef8c5f99760d0c439fc29543a1f..6b8c9fe85c23fe6af431c82d9071a3ff2fe5a4ba 100644 --- a/addons/stock/models/stock_move.py +++ b/addons/stock/models/stock_move.py @@ -65,7 +65,7 @@ class StockMove(models.Model): # TDE FIXME: make it stored, otherwise group will not work product_tmpl_id = fields.Many2one( 'product.template', 'Product Template', - related='product_id.product_tmpl_id', + related='product_id.product_tmpl_id', readonly=False, help="Technical: used in views") product_packaging = fields.Many2one( 'product.packaging', 'Preferred Packaging', @@ -91,7 +91,7 @@ class StockMove(models.Model): copy=False, help="Optional: previous stock move when chaining them") picking_id = fields.Many2one('stock.picking', 'Transfer Reference', index=True, states={'done': [('readonly', True)]}) - picking_partner_id = fields.Many2one('res.partner', 'Transfer Destination Address', related='picking_id.partner_id') + picking_partner_id = fields.Many2one('res.partner', 'Transfer Destination Address', related='picking_id.partner_id', readonly=False) note = fields.Text('Notes') state = fields.Selection([ ('draft', 'New'), ('cancel', 'Cancelled'), @@ -109,7 +109,7 @@ class StockMove(models.Model): price_unit = fields.Float( 'Unit Price', help="Technical field used to record the product cost set by the user during a picking confirmation (when costing " "method used is 'average price' or 'real'). Value given in company currency and in product uom.", copy=False) # as it's a technical field, we intentionally don't provide the digits attribute - backorder_id = fields.Many2one('stock.picking', 'Back Order of', related='picking_id.backorder_id', index=True) + backorder_id = fields.Many2one('stock.picking', 'Back Order of', related='picking_id.backorder_id', index=True, readonly=False) origin = fields.Char("Source Document") procure_method = fields.Selection([ ('make_to_stock', 'Default: Take From Stock'), @@ -145,9 +145,9 @@ class StockMove(models.Model): restrict_partner_id = fields.Many2one('res.partner', 'Owner ', help="Technical field used to depict a restriction on the ownership of quants to consider when marking this move as 'done'") route_ids = fields.Many2many('stock.location.route', 'stock_location_route_move', 'move_id', 'route_id', 'Destination route', help="Preferred route") warehouse_id = fields.Many2one('stock.warehouse', 'Warehouse', help="Technical field depicting the warehouse to consider for the route selection on the next procurement (if any).") - has_tracking = fields.Selection(related='product_id.tracking', string='Product with Tracking') + has_tracking = fields.Selection(related='product_id.tracking', string='Product with Tracking', readonly=False) quantity_done = fields.Float('Quantity Done', compute='_quantity_done_compute', digits=dp.get_precision('Product Unit of Measure'), inverse='_quantity_done_set') - show_operations = fields.Boolean(related='picking_id.picking_type_id.show_operations') + show_operations = fields.Boolean(related='picking_id.picking_type_id.show_operations', readonly=False) show_details_visible = fields.Boolean('Details Visible', compute='_compute_show_details_visible') show_reserved_availability = fields.Boolean('From Supplier', compute='_compute_show_reserved_availability') picking_code = fields.Selection(related='picking_id.picking_type_id.code', readonly=True) diff --git a/addons/stock/models/stock_move_line.py b/addons/stock/models/stock_move_line.py index 9584fa842ef06b00208d4d425abdebd683db73f9..ccd2aea5a85b7f66774a781568b96fa404a96135 100644 --- a/addons/stock/models/stock_move_line.py +++ b/addons/stock/models/stock_move_line.py @@ -44,12 +44,12 @@ class StockMoveLine(models.Model): lots_visible = fields.Boolean(compute='_compute_lots_visible') picking_type_use_create_lots = fields.Boolean(related='picking_id.picking_type_id.use_create_lots', readonly=True) picking_type_use_existing_lots = fields.Boolean(related='picking_id.picking_type_id.use_existing_lots', readonly=True) - state = fields.Selection(related='move_id.state', store=True, related_sudo=False) - is_initial_demand_editable = fields.Boolean(related='move_id.is_initial_demand_editable') + state = fields.Selection(related='move_id.state', store=True, related_sudo=False, readonly=False) + is_initial_demand_editable = fields.Boolean(related='move_id.is_initial_demand_editable', readonly=False) is_locked = fields.Boolean(related='move_id.is_locked', default=True, readonly=True) consume_line_ids = fields.Many2many('stock.move.line', 'stock_move_line_consume_rel', 'consume_line_id', 'produce_line_id', help="Technical link to see who consumed what. ") produce_line_ids = fields.Many2many('stock.move.line', 'stock_move_line_consume_rel', 'produce_line_id', 'consume_line_id', help="Technical link to see which line was produced with this. ") - reference = fields.Char(related='move_id.reference', store=True, related_sudo=False) + reference = fields.Char(related='move_id.reference', store=True, related_sudo=False, readonly=False) tracking = fields.Selection(related='product_id.tracking', readonly=True) picking_type_entire_packs = fields.Boolean(related='picking_id.picking_type_id.show_entire_packs', readonly=True) diff --git a/addons/stock/models/stock_package_level.py b/addons/stock/models/stock_package_level.py index 1d01face6b586bf2030882753ef4c8540f8b9c4f..a4d0c5be010b5fea16f190d49b9df16572f20b2e 100644 --- a/addons/stock/models/stock_package_level.py +++ b/addons/stock/models/stock_package_level.py @@ -27,7 +27,7 @@ class StockPackageLevel(models.Model): ],string='State', compute='_compute_state') is_fresh_package = fields.Boolean(compute='_compute_fresh_pack') - picking_source_location = fields.Many2one('stock.location', related='picking_id.location_id') + picking_source_location = fields.Many2one('stock.location', related='picking_id.location_id', readonly=False) show_lots_m2o = fields.Boolean(compute='_compute_show_lot') show_lots_text = fields.Boolean(compute='_compute_show_lot') diff --git a/addons/stock/models/stock_picking.py b/addons/stock/models/stock_picking.py index e1aa4ecfd6c362d9d2c0c568c0d430d90097242a..310f7b6bef530e442f2b4f7064d6612542f56ca7 100644 --- a/addons/stock/models/stock_picking.py +++ b/addons/stock/models/stock_picking.py @@ -294,7 +294,7 @@ class Picking(models.Model): 'initial demand. When the picking is done this allows ' 'changing the done quantities.') # Used to search on pickings - product_id = fields.Many2one('product.product', 'Product', related='move_lines.product_id') + product_id = fields.Many2one('product.product', 'Product', related='move_lines.product_id', readonly=False) show_operations = fields.Boolean(compute='_compute_show_operations') show_lots_text = fields.Boolean(compute='_compute_show_lots_text') has_tracking = fields.Boolean(compute='_compute_has_tracking') diff --git a/addons/stock/models/stock_production_lot.py b/addons/stock/models/stock_production_lot.py index 7011c79d142973347cc10e6854762785f256a0d4..584215620e63a652b461dfe153ee60ee9e36fc40 100644 --- a/addons/stock/models/stock_production_lot.py +++ b/addons/stock/models/stock_production_lot.py @@ -19,7 +19,7 @@ class ProductionLot(models.Model): domain=[('type', 'in', ['product', 'consu'])], required=True) product_uom_id = fields.Many2one( 'uom.uom', 'Unit of Measure', - related='product_id.uom_id', store=True) + related='product_id.uom_id', store=True, readonly=False) quant_ids = fields.One2many('stock.quant', 'lot_id', 'Quants', readonly=True) product_qty = fields.Float('Quantity', compute='_product_qty') diff --git a/addons/stock/models/stock_quant.py b/addons/stock/models/stock_quant.py index 123e485697143717f1b0144cb83cdc2b9ed5b7d1..7ad562792fb4ba7deacfc3b45de14e6b701566b7 100644 --- a/addons/stock/models/stock_quant.py +++ b/addons/stock/models/stock_quant.py @@ -24,7 +24,7 @@ class StockQuant(models.Model): # so user can filter on template in webclient product_tmpl_id = fields.Many2one( 'product.template', string='Product Template', - related='product_id.product_tmpl_id') + related='product_id.product_tmpl_id', readonly=False) product_uom_id = fields.Many2one( 'uom.uom', 'Unit of Measure', readonly=True, related='product_id.uom_id') diff --git a/addons/stock/models/stock_rule.py b/addons/stock/models/stock_rule.py index 724edff2df24797acf3b98a190b62f3c168656d4..2ffaf454b57b4e4e016a1b17913c09172bdf2200 100644 --- a/addons/stock/models/stock_rule.py +++ b/addons/stock/models/stock_rule.py @@ -49,7 +49,7 @@ class StockRule(models.Model): default='make_to_stock', required=True, help="""Create Procurement: A procurement will be created in the source location and the system will try to find a rule to resolve it. The available stock will be ignored. Take from Stock: The products will be taken from the available stock.""") - route_sequence = fields.Integer('Route Sequence', related='route_id.sequence', store=True) + route_sequence = fields.Integer('Route Sequence', related='route_id.sequence', store=True, readonly=False) picking_type_id = fields.Many2one( 'stock.picking.type', 'Operation Type', required=True) diff --git a/addons/stock/wizard/stock_change_product_qty.py b/addons/stock/wizard/stock_change_product_qty.py index 7301555d993b75df907a1b85c7702e4da9febfce..f33a6c10e36b604c370c3455ee4c208e07395c6f 100644 --- a/addons/stock/wizard/stock_change_product_qty.py +++ b/addons/stock/wizard/stock_change_product_qty.py @@ -13,7 +13,7 @@ class ProductChangeQuantity(models.TransientModel): # TDE FIXME: strange dfeault method, was present before migration ? to check product_id = fields.Many2one('product.product', 'Product', required=True) product_tmpl_id = fields.Many2one('product.template', 'Template', required=True) - product_variant_count = fields.Integer('Variant Count', related='product_tmpl_id.product_variant_count') + product_variant_count = fields.Integer('Variant Count', related='product_tmpl_id.product_variant_count', readonly=False) new_quantity = fields.Float( 'New Quantity on Hand', default=1, digits=dp.get_precision('Product Unit of Measure'), required=True, diff --git a/addons/stock/wizard/stock_picking_return.py b/addons/stock/wizard/stock_picking_return.py index 103c2a8cb26c80000e4eb1f6636fa3262fbd148e..0a836c934990de2fc8a84bff69df74d760455785 100644 --- a/addons/stock/wizard/stock_picking_return.py +++ b/addons/stock/wizard/stock_picking_return.py @@ -14,7 +14,7 @@ class ReturnPickingLine(models.TransientModel): product_id = fields.Many2one('product.product', string="Product", required=True, domain="[('id', '=', product_id)]") quantity = fields.Float("Quantity", digits=dp.get_precision('Product Unit of Measure'), required=True) - uom_id = fields.Many2one('uom.uom', string='Unit of Measure', related='move_id.product_uom') + uom_id = fields.Many2one('uom.uom', string='Unit of Measure', related='move_id.product_uom', readonly=False) wizard_id = fields.Many2one('stock.return.picking', string="Wizard") move_id = fields.Many2one('stock.move', "Move") diff --git a/addons/stock_landed_costs/models/stock_landed_cost.py b/addons/stock_landed_costs/models/stock_landed_cost.py index d41a53cd6766b83f1e9e3451c11400a31aae94fa..0722183757cdfbca93240eea8f384ebdf1b684d2 100644 --- a/addons/stock_landed_costs/models/stock_landed_cost.py +++ b/addons/stock_landed_costs/models/stock_landed_cost.py @@ -52,7 +52,7 @@ class LandedCost(models.Model): 'account.journal', 'Account Journal', required=True, states={'done': [('readonly', True)]}) company_id = fields.Many2one('res.company', string="Company", - related='account_journal_id.company_id') + related='account_journal_id.company_id', readonly=False) @api.one @api.depends('cost_lines.price_unit') diff --git a/addons/survey/models/survey.py b/addons/survey/models/survey.py index 210c8153ecace34db9d6748da7180a6ba9249409..95a1cc1fdd1b30e88c5835447a20bfbb3e272ae1 100644 --- a/addons/survey/models/survey.py +++ b/addons/survey/models/survey.py @@ -77,7 +77,7 @@ class Survey(models.Model): thank_you_message = fields.Html("Thanks Message", translate=True, help="This message will be displayed when survey is completed") quizz_mode = fields.Boolean("Quizz Mode") active = fields.Boolean("Active", default=True) - is_closed = fields.Boolean("Is closed", related='stage_id.closed') + is_closed = fields.Boolean("Is closed", related='stage_id.closed', readonly=False) def _is_designed(self): for survey in self: @@ -424,7 +424,7 @@ class SurveyQuestion(models.Model): # Question metadata page_id = fields.Many2one('survey.page', string='Survey page', ondelete='cascade', required=True, default=lambda self: self.env.context.get('page_id')) - survey_id = fields.Many2one('survey.survey', related='page_id.survey_id', string='Survey') + survey_id = fields.Many2one('survey.survey', related='page_id.survey_id', string='Survey', readonly=False) sequence = fields.Integer('Sequence', default=10) # Question @@ -716,8 +716,8 @@ class SurveyUserInput(models.Model): user_input_line_ids = fields.One2many('survey.user_input_line', 'user_input_id', string='Answers', copy=True) # URLs used to display the answers - result_url = fields.Char("Public link to the survey results", related='survey_id.result_url') - print_url = fields.Char("Public link to the empty survey", related='survey_id.print_url') + result_url = fields.Char("Public link to the survey results", related='survey_id.result_url', readonly=False) + print_url = fields.Char("Public link to the empty survey", related='survey_id.print_url', readonly=False) quizz_score = fields.Float("Score for the quiz", compute="_compute_quizz_score", default=0.0) @@ -781,8 +781,8 @@ class SurveyUserInputLine(models.Model): user_input_id = fields.Many2one('survey.user_input', string='User Input', ondelete='cascade', required=True) question_id = fields.Many2one('survey.question', string='Question', ondelete='restrict', required=True) - page_id = fields.Many2one(related='question_id.page_id', string="Page") - survey_id = fields.Many2one(related='user_input_id.survey_id', string='Survey', store=True) + page_id = fields.Many2one(related='question_id.page_id', string="Page", readonly=False) + survey_id = fields.Many2one(related='user_input_id.survey_id', string='Survey', store=True, readonly=False) date_create = fields.Datetime('Create Date', default=fields.Datetime.now, required=True) skipped = fields.Boolean('Skipped') answer_type = fields.Selection([ diff --git a/addons/website/models/ir_attachment.py b/addons/website/models/ir_attachment.py index f49611e6e057fe569a899b85d38e3b5eceecc624..8fe190a5a4722459a6db09059545e6b11447354f 100644 --- a/addons/website/models/ir_attachment.py +++ b/addons/website/models/ir_attachment.py @@ -13,7 +13,7 @@ class Attachment(models.Model): _inherit = "ir.attachment" # related for backward compatibility with saas-6 - website_url = fields.Char(string="Website URL", related='local_url', deprecated=True) + website_url = fields.Char(string="Website URL", related='local_url', deprecated=True, readonly=False) key = fields.Char(help='Technical field used to resolve multiple attachments in a multi-website environment.') website_id = fields.Many2one('website') diff --git a/addons/website/models/res_config_settings.py b/addons/website/models/res_config_settings.py index 8dc651707ba4d11ca8b04fd7a6f5281042e20cd8..2c796fd5aeb1465c0026439cddde6ec4648d8b1f 100644 --- a/addons/website/models/res_config_settings.py +++ b/addons/website/models/res_config_settings.py @@ -15,40 +15,40 @@ class ResConfigSettings(models.TransientModel): website_id = fields.Many2one('website', string="website", default=_default_website, ondelete='cascade') - website_name = fields.Char('Website Name', related='website_id.name') - website_domain = fields.Char('Website Domain', related='website_id.domain') - website_country_group_ids = fields.Many2many(related='website_id.country_group_ids') - website_company_id = fields.Many2one(related='website_id.company_id', string='Website Company') - language_ids = fields.Many2many(related='website_id.language_ids', relation='res.lang') + website_name = fields.Char('Website Name', related='website_id.name', readonly=False) + website_domain = fields.Char('Website Domain', related='website_id.domain', readonly=False) + website_country_group_ids = fields.Many2many(related='website_id.country_group_ids', readonly=False) + website_company_id = fields.Many2one(related='website_id.company_id', string='Website Company', readonly=False) + language_ids = fields.Many2many(related='website_id.language_ids', relation='res.lang', readonly=False) language_count = fields.Integer(string='Number of languages', compute='_compute_language_count', readonly=True) website_default_lang_id = fields.Many2one( - string='Default language', related='website_id.default_lang_id', + string='Default language', related='website_id.default_lang_id', readonly=False, relation='res.lang', required=True, oldname='default_lang_id') website_default_lang_code = fields.Char( - 'Default language code', related='website_id.default_lang_code', + 'Default language code', related='website_id.default_lang_code', readonly=False, oldname='default_lang_code') - specific_user_account = fields.Boolean(related='website_id.specific_user_account', + specific_user_account = fields.Boolean(related='website_id.specific_user_account', readonly=False, help='Are newly created user accounts website specific') - google_analytics_key = fields.Char('Google Analytics Key', related='website_id.google_analytics_key') - google_management_client_id = fields.Char('Google Client ID', related='website_id.google_management_client_id') - google_management_client_secret = fields.Char('Google Client Secret', related='website_id.google_management_client_secret') + google_analytics_key = fields.Char('Google Analytics Key', related='website_id.google_analytics_key', readonly=False) + google_management_client_id = fields.Char('Google Client ID', related='website_id.google_management_client_id', readonly=False) + google_management_client_secret = fields.Char('Google Client Secret', related='website_id.google_management_client_secret', readonly=False) - cdn_activated = fields.Boolean(related='website_id.cdn_activated') - cdn_url = fields.Char(related='website_id.cdn_url') - cdn_filters = fields.Text(related='website_id.cdn_filters') + cdn_activated = fields.Boolean(related='website_id.cdn_activated', readonly=False) + cdn_url = fields.Char(related='website_id.cdn_url', readonly=False) + cdn_filters = fields.Text(related='website_id.cdn_filters', readonly=False) module_website_version = fields.Boolean("A/B Testing") module_website_links = fields.Boolean("Link Trackers") - auth_signup_uninvited = fields.Selection("Customer Account", related='website_id.auth_signup_uninvited') + auth_signup_uninvited = fields.Selection("Customer Account", related='website_id.auth_signup_uninvited', readonly=False) - social_twitter = fields.Char(related='website_id.social_twitter') - social_facebook = fields.Char(related='website_id.social_facebook') - social_github = fields.Char(related='website_id.social_github') - social_linkedin = fields.Char(related='website_id.social_linkedin') - social_youtube = fields.Char(related='website_id.social_youtube') - social_googleplus = fields.Char(related='website_id.social_googleplus') - social_instagram = fields.Char(related='website_id.social_instagram') + social_twitter = fields.Char(related='website_id.social_twitter', readonly=False) + social_facebook = fields.Char(related='website_id.social_facebook', readonly=False) + social_github = fields.Char(related='website_id.social_github', readonly=False) + social_linkedin = fields.Char(related='website_id.social_linkedin', readonly=False) + social_youtube = fields.Char(related='website_id.social_youtube', readonly=False) + social_googleplus = fields.Char(related='website_id.social_googleplus', readonly=False) + social_instagram = fields.Char(related='website_id.social_instagram', readonly=False) @api.depends('website_id', 'social_twitter', 'social_facebook', 'social_github', 'social_linkedin', 'social_youtube', 'social_googleplus', 'social_instagram') def has_social_network(self): @@ -67,9 +67,9 @@ class ResConfigSettings(models.TransientModel): has_social_network = fields.Boolean("Configure Social Network", compute=has_social_network, inverse=inverse_has_social_network) - favicon = fields.Binary('Favicon', related='website_id.favicon') + favicon = fields.Binary('Favicon', related='website_id.favicon', readonly=False) - google_maps_api_key = fields.Char(related='website_id.google_maps_api_key') + google_maps_api_key = fields.Char(related='website_id.google_maps_api_key', readonly=False) group_multi_website = fields.Boolean("Multi-website", implied_group="website.group_multi_website") @api.depends('website_id') diff --git a/addons/website/models/website.py b/addons/website/models/website.py index a577f147cb1652a23cdcbcbe1b6146dd12a528fc..7ed335f8d2ed321e99b44416ea1993a247cf55a0 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -56,7 +56,7 @@ class Website(models.Model): company_id = fields.Many2one('res.company', string="Company", default=lambda self: self.env.ref('base.main_company').id, required=True) language_ids = fields.Many2many('res.lang', 'website_lang_rel', 'website_id', 'lang_id', 'Languages', default=_active_languages) default_lang_id = fields.Many2one('res.lang', string="Default Language", default=_default_language, required=True) - default_lang_code = fields.Char("Default language code", related='default_lang_id.code', store=True) + default_lang_code = fields.Char("Default language code", related='default_lang_id.code', store=True, readonly=False) auto_redirect_lang = fields.Boolean('Autoredirect Language', default=True, help="Should users be redirected to their browser's language") def _default_social_facebook(self): @@ -98,7 +98,7 @@ class Website(models.Model): cdn_activated = fields.Boolean('Content Delivery Network (CDN)') cdn_url = fields.Char('CDN Base URL', default='') cdn_filters = fields.Text('CDN Filters', default=lambda s: '\n'.join(DEFAULT_CDN_FILTERS), help="URL matching those filters will be rewritten using the CDN Base URL") - partner_id = fields.Many2one(related='user_id.partner_id', relation='res.partner', string='Public Partner') + partner_id = fields.Many2one(related='user_id.partner_id', relation='res.partner', string='Public Partner', readonly=False) menu_id = fields.Many2one('website.menu', compute='_compute_menu', string='Main Menu') homepage_id = fields.Many2one('website.page', string='Homepage') favicon = fields.Binary(string="Website Favicon", help="This field holds the image used to display a favicon on the website.") @@ -776,7 +776,7 @@ class WebsitePublishedMixin(models.AbstractModel): _name = "website.published.mixin" _description = 'Website Published Mixin' - website_published = fields.Boolean('Visible on current website', related='is_published') + website_published = fields.Boolean('Visible on current website', related='is_published', readonly=False) is_published = fields.Boolean('Is published') website_url = fields.Char('Website URL', compute='_compute_website_url', help='The full URL to access the document through the website.') @@ -815,7 +815,7 @@ class WebsitePublishedMultiMixin(WebsitePublishedMixin): website_published = fields.Boolean(compute='_compute_website_published', inverse='_inverse_website_published', search='_search_website_published', - related=False) + related=False, readonly=False) @api.multi @api.depends('is_published', 'website_id') @@ -870,7 +870,7 @@ class Page(models.Model): header_color = fields.Char() # don't use mixin website_id but use website_id on ir.ui.view instead - website_id = fields.Many2one(related='view_id.website_id', store=True) + website_id = fields.Many2one(related='view_id.website_id', store=True, readonly=False) @api.one def _compute_homepage(self): diff --git a/addons/website_blog/models/website_blog.py b/addons/website_blog/models/website_blog.py index dc6f2d1673658d37dd3f1590cac1ca9cdb156e7c..6616b62ce43e223e334b573f5b0d47d94d1436f1 100644 --- a/addons/website_blog/models/website_blog.py +++ b/addons/website_blog/models/website_blog.py @@ -165,7 +165,7 @@ class BlogPost(models.Model): create_uid = fields.Many2one('res.users', 'Created by', index=True, readonly=True) write_date = fields.Datetime('Last Updated on', index=True, readonly=True) write_uid = fields.Many2one('res.users', 'Last Contributor', index=True, readonly=True) - author_avatar = fields.Binary(related='author_id.image_small', string="Avatar") + author_avatar = fields.Binary(related='author_id.image_small', string="Avatar", readonly=False) visits = fields.Integer('No of Views', copy=False) ranking = fields.Float(compute='_compute_ranking', string='Ranking') diff --git a/addons/website_crm/models/res_config_settings.py b/addons/website_crm/models/res_config_settings.py index 98ba0e20939fcbe79248179e657e9f67b14f5634..f9b3f1c2c33ea5afc3190e6cdd14ebf616f1fcca 100644 --- a/addons/website_crm/models/res_config_settings.py +++ b/addons/website_crm/models/res_config_settings.py @@ -13,9 +13,9 @@ class ResConfigSettings(models.TransientModel): return [('use_opportunities', '=', True)] crm_default_team_id = fields.Many2one( - 'crm.team', string='Default Sales Team', related='website_id.crm_default_team_id', + 'crm.team', string='Default Sales Team', related='website_id.crm_default_team_id', readonly=False, domain=lambda self: self._get_crm_default_team_domain(), help='Default Sales Team for new leads created through the Contact Us form.') crm_default_user_id = fields.Many2one( - 'res.users', string='Default Salesperson', related='website_id.crm_default_user_id', domain=[('share', '=', False)], + 'res.users', string='Default Salesperson', related='website_id.crm_default_user_id', domain=[('share', '=', False)], readonly=False, help='Default salesperson for new leads created through the Contact Us form.') diff --git a/addons/website_event_track/models/event_track.py b/addons/website_event_track/models/event_track.py index 1661167e0cd483f8bc2117f6eb627901ca9cec43..2f35e86bb0e01afc692bc940ebb09d5e2c0376a9 100644 --- a/addons/website_event_track/models/event_track.py +++ b/addons/website_event_track/models/event_track.py @@ -88,7 +88,7 @@ class Track(models.Model): ('0', 'Low'), ('1', 'Medium'), ('2', 'High'), ('3', 'Highest')], 'Priority', required=True, default='1') - image = fields.Binary('Image', related='partner_id.image_medium', store=True, attachment=True) + image = fields.Binary('Image', related='partner_id.image_medium', store=True, attachment=True, readonly=False) @api.multi @api.depends('name') @@ -209,5 +209,5 @@ class Sponsor(models.Model): sponsor_type_id = fields.Many2one('event.sponsor.type', 'Sponsoring Type', required=True) partner_id = fields.Many2one('res.partner', 'Sponsor/Customer', required=True) url = fields.Char('Sponsor Website') - sequence = fields.Integer('Sequence', store=True, related='sponsor_type_id.sequence') - image_medium = fields.Binary(string='Logo', related='partner_id.image_medium', store=True, attachment=True) + sequence = fields.Integer('Sequence', store=True, related='sponsor_type_id.sequence', readonly=False) + image_medium = fields.Binary(string='Logo', related='partner_id.image_medium', store=True, attachment=True, readonly=False) diff --git a/addons/website_form/models/models.py b/addons/website_form/models/models.py index 6ad987f89e669b9160ff6606eac101eddce3eff8..1256ac4935caa3517f8d881632731ab279053f46 100644 --- a/addons/website_form/models/models.py +++ b/addons/website_form/models/models.py @@ -18,7 +18,7 @@ class website_form_config(models.Model): class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' - website_form_enable_metadata = fields.Boolean(related="website_id.website_form_enable_metadata") + website_form_enable_metadata = fields.Boolean(related="website_id.website_form_enable_metadata", readonly=False) class website_form_model(models.Model): diff --git a/addons/website_forum/models/forum.py b/addons/website_forum/models/forum.py index d1dce1b378e8e9d60ce765ce9912ceed64c7b67d..7fb50947993d2a6049b895d10b1f36f30e5f1a4e 100644 --- a/addons/website_forum/models/forum.py +++ b/addons/website_forum/models/forum.py @@ -869,8 +869,8 @@ class Vote(models.Model): user_id = fields.Many2one('res.users', string='User', required=True, default=lambda self: self._uid) vote = fields.Selection([('1', '1'), ('-1', '-1'), ('0', '0')], string='Vote', required=True, default='1') create_date = fields.Datetime('Create Date', index=True, readonly=True) - forum_id = fields.Many2one('forum.forum', string='Forum', related="post_id.forum_id", store=True) - recipient_id = fields.Many2one('res.users', string='To', related="post_id.create_uid", store=True) + forum_id = fields.Many2one('forum.forum', string='Forum', related="post_id.forum_id", store=True, readonly=False) + recipient_id = fields.Many2one('res.users', string='To', related="post_id.create_uid", store=True, readonly=False) def _get_karma_value(self, old_vote, new_vote, up_karma, down_karma): _karma_upd = { diff --git a/addons/website_forum/models/gamification.py b/addons/website_forum/models/gamification.py index 73819aa97f5e32da664e31e9c389f197e9faf612..5c83dcc1ad62f3b4af3f6de0fb9aa867c193faa1 100644 --- a/addons/website_forum/models/gamification.py +++ b/addons/website_forum/models/gamification.py @@ -24,4 +24,4 @@ class UserBadge(models.Model): ('silver', 'silver'), ('gold', 'gold')], string='Forum Badge Level', - related="badge_id.level", store=True) + related="badge_id.level", store=True, readonly=False) diff --git a/addons/website_livechat/models/res_config_settings.py b/addons/website_livechat/models/res_config_settings.py index 6b0c96cd2e0373185d5165e6171bbcfca86b4bb7..9c47f28b83ec1dce092a75d4293191fb0dc19bc8 100644 --- a/addons/website_livechat/models/res_config_settings.py +++ b/addons/website_livechat/models/res_config_settings.py @@ -7,4 +7,4 @@ from odoo import fields, models class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' - channel_id = fields.Many2one('im_livechat.channel', string='Website Live Channel', related='website_id.channel_id') + channel_id = fields.Many2one('im_livechat.channel', string='Website Live Channel', related='website_id.channel_id', readonly=False) diff --git a/addons/website_rating/models/rating.py b/addons/website_rating/models/rating.py index 673299e6df42dc3b9f703d8117915fc2517f67ac..33184ca905146851e9d86d45bb94630ceae5f08f 100644 --- a/addons/website_rating/models/rating.py +++ b/addons/website_rating/models/rating.py @@ -9,4 +9,4 @@ class Rating(models.Model): # Add this related field to mail.message for performance reason # This field may one day be deplaced to another module (like 'website_rating') if it is required for # another usage not related to website_sale. - website_published = fields.Boolean(related='message_id.website_published', store=True) + website_published = fields.Boolean(related='message_id.website_published', store=True, readonly=False) diff --git a/addons/website_sale/models/product.py b/addons/website_sale/models/product.py index ff3fb29f6c607b65ac8688cc1e53f7ee0da04917..727775b902728dde9c43c67c425e19ae8ce1f8e3 100644 --- a/addons/website_sale/models/product.py +++ b/addons/website_sale/models/product.py @@ -185,7 +185,7 @@ class ProductTemplate(models.Model): class Product(models.Model): _inherit = "product.product" - website_id = fields.Many2one(related='product_tmpl_id.website_id') + website_id = fields.Many2one(related='product_tmpl_id.website_id', readonly=False) website_price = fields.Float('Website price', compute='_website_price', digits=dp.get_precision('Product Price')) website_public_price = fields.Float('Website public price', compute='_website_price', digits=dp.get_precision('Product Price')) diff --git a/addons/website_sale/models/res_config_settings.py b/addons/website_sale/models/res_config_settings.py index 44a41472cbcccf62d51c9d28f3c1645c4d7eedb6..bceea238fa6278c6f46f47ae3a70b30834edd0db 100644 --- a/addons/website_sale/models/res_config_settings.py +++ b/addons/website_sale/models/res_config_settings.py @@ -15,7 +15,7 @@ class ResConfigSettings(models.TransientModel): except ValueError: return False - salesperson_id = fields.Many2one('res.users', related='website_id.salesperson_id', string='Salesperson') + salesperson_id = fields.Many2one('res.users', related='website_id.salesperson_id', string='Salesperson', readonly=False) salesteam_id = fields.Many2one('crm.team', related='website_id.salesteam_id', string='Sales Team', domain=[('team_type', '!=', 'pos')]) module_website_sale_delivery = fields.Boolean("eCommerce Shipping Costs") # field used to have a nice radio in form view, resuming the 2 fields above @@ -35,9 +35,9 @@ class ResConfigSettings(models.TransientModel): module_account = fields.Boolean("Invoicing") cart_recovery_mail_template = fields.Many2one('mail.template', string='Cart Recovery Email', domain="[('model', '=', 'sale.order')]", - default=_default_recovery_mail_template, related='website_id.cart_recovery_mail_template_id') + default=_default_recovery_mail_template, related='website_id.cart_recovery_mail_template_id', readonly=False) cart_abandoned_delay = fields.Float("Abandoned Delay", help="Number of hours after which the cart is considered abandoned.", - default=1.0, related='website_id.cart_abandoned_delay') + default=1.0, related='website_id.cart_abandoned_delay', readonly=False) @api.model def get_values(self): diff --git a/addons/website_sale/models/website.py b/addons/website_sale/models/website.py index b5d03aa6d2f590dff7bcef9f92a2f54186cd5e60..570ef96c45f34ec151def30ecd05edbac1a6edc0 100644 --- a/addons/website_sale/models/website.py +++ b/addons/website_sale/models/website.py @@ -14,7 +14,7 @@ class Website(models.Model): _inherit = 'website' pricelist_id = fields.Many2one('product.pricelist', compute='_compute_pricelist_id', string='Default Pricelist') - currency_id = fields.Many2one('res.currency', related='pricelist_id.currency_id', related_sudo=False, string='Default Currency') + currency_id = fields.Many2one('res.currency', related='pricelist_id.currency_id', related_sudo=False, string='Default Currency', readonly=False) salesperson_id = fields.Many2one('res.users', string='Salesperson') salesteam_id = fields.Many2one('crm.team', string='Sales Team') pricelist_ids = fields.One2many('product.pricelist', compute="_compute_pricelist_ids", diff --git a/addons/website_sale_delivery/models/delivery.py b/addons/website_sale_delivery/models/delivery.py index 2e0b878b8da88e7b2276a27cf7471d20e7ca39e7..5a7270c7f1ccf34e2eb1483862dabac5163bd826 100644 --- a/addons/website_sale_delivery/models/delivery.py +++ b/addons/website_sale_delivery/models/delivery.py @@ -8,5 +8,5 @@ class DeliveryCarrier(models.Model): _name = 'delivery.carrier' _inherit = ['delivery.carrier', 'website.published.multi.mixin'] - website_description = fields.Text(related='product_id.description_sale', string='Description for Online Quotations') + website_description = fields.Text(related='product_id.description_sale', string='Description for Online Quotations', readonly=False) website_published = fields.Boolean(default=False) diff --git a/addons/website_slides/models/res_config_settings.py b/addons/website_slides/models/res_config_settings.py index 7ea6470a1273eaf4d98da203614ae38f31472316..77bec337ff0fc2108ea5ee5de8b3b9b74854256d 100644 --- a/addons/website_slides/models/res_config_settings.py +++ b/addons/website_slides/models/res_config_settings.py @@ -7,4 +7,4 @@ from odoo import api, fields, models class ResConfigSettings(models.TransientModel): _inherit = "res.config.settings" - website_slide_google_app_key = fields.Char(related='website_id.website_slide_google_app_key') + website_slide_google_app_key = fields.Char(related='website_id.website_slide_google_app_key', readonly=False) diff --git a/addons/website_twitter/models/res_config_settings.py b/addons/website_twitter/models/res_config_settings.py index b34299f5b62459e2539fe2e31ae97ffcf28921a5..4cb58e52d72fa6a6132d91090aab6cbf5aca3ee4 100644 --- a/addons/website_twitter/models/res_config_settings.py +++ b/addons/website_twitter/models/res_config_settings.py @@ -27,15 +27,15 @@ class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' twitter_api_key = fields.Char( - related='website_id.twitter_api_key', + related='website_id.twitter_api_key', readonly=False, string='API Key', help='Twitter API key you can get it from https://apps.twitter.com/') twitter_api_secret = fields.Char( - related='website_id.twitter_api_secret', + related='website_id.twitter_api_secret', readonly=False, string='API secret', help='Twitter API secret you can get it from https://apps.twitter.com/') twitter_screen_name = fields.Char( - related='website_id.twitter_screen_name', + related='website_id.twitter_screen_name', readonly=False, string='Favorites From', help='Screen Name of the Twitter Account from which you want to load favorites.' 'It does not have to match the API Key/Secret.') diff --git a/odoo/addons/base/models/ir_cron.py b/odoo/addons/base/models/ir_cron.py index 0af758223294d4649e4a72bebea7b8b0e2b6246b..4d8c0d3ea36e6eaccfc3e055d1da5ddb1df707b6 100644 --- a/odoo/addons/base/models/ir_cron.py +++ b/odoo/addons/base/models/ir_cron.py @@ -50,7 +50,7 @@ class ir_cron(models.Model): ir_actions_server_id = fields.Many2one( 'ir.actions.server', 'Server action', delegate=True, ondelete='restrict', required=True) - cron_name = fields.Char('Name', related='ir_actions_server_id.name', store=True) + cron_name = fields.Char('Name', related='ir_actions_server_id.name', store=True, readonly=False) user_id = fields.Many2one('res.users', string='Scheduler User', default=lambda self: self.env.user, required=True) active = fields.Boolean(default=True) interval_number = fields.Integer(default=1, help="Repeat every x.") diff --git a/odoo/addons/base/models/res_bank.py b/odoo/addons/base/models/res_bank.py index 4b5147ed0fee8ae4dcb542f83fdde1fd62ccd47f..88ff7b7984c36b54bc59ca3ee759d0c73e282c5e 100644 --- a/odoo/addons/base/models/res_bank.py +++ b/odoo/addons/base/models/res_bank.py @@ -74,8 +74,8 @@ class ResPartnerBank(models.Model): acc_holder_name = fields.Char(string='Account Holder Name', help="Account holder name, in case it is different than the name of the Account Holder") partner_id = fields.Many2one('res.partner', 'Account Holder', ondelete='cascade', index=True, domain=['|', ('is_company', '=', True), ('parent_id', '=', False)], required=True) bank_id = fields.Many2one('res.bank', string='Bank') - bank_name = fields.Char(related='bank_id.name') - bank_bic = fields.Char(related='bank_id.bic') + bank_name = fields.Char(related='bank_id.name', readonly=False) + bank_bic = fields.Char(related='bank_id.bic', readonly=False) sequence = fields.Integer() currency_id = fields.Many2one('res.currency', string='Currency') company_id = fields.Many2one('res.company', 'Company', default=lambda self: self.env.user.company_id, ondelete='cascade') diff --git a/odoo/addons/base/models/res_company.py b/odoo/addons/base/models/res_company.py index cc5a1fb6175a897ad09a4d8d172eaa88b606b4b0..64fb3ee6fb26cd5a8e0180f59f274df60e77ca09 100644 --- a/odoo/addons/base/models/res_company.py +++ b/odoo/addons/base/models/res_company.py @@ -29,14 +29,14 @@ class Company(models.Model): currency_id = self.env['res.users'].browse(self._uid).company_id.currency_id return currency_id or self._get_euro() - name = fields.Char(related='partner_id.name', string='Company Name', required=True, store=True) + name = fields.Char(related='partner_id.name', string='Company Name', required=True, store=True, readonly=False) sequence = fields.Integer(help='Used to order Companies in the company switcher', default=10) parent_id = fields.Many2one('res.company', string='Parent Company', index=True) child_ids = fields.One2many('res.company', 'parent_id', string='Child Companies') partner_id = fields.Many2one('res.partner', string='Partner', required=True) report_header = fields.Text(string='Company Tagline', help="Appears by default on the top right corner of your printed documents (report header).") report_footer = fields.Text(string='Report Footer', translate=True, help="Footer text displayed at the bottom of all reports.") - logo = fields.Binary(related='partner_id.image', default=_get_logo, string="Company Logo") + logo = fields.Binary(related='partner_id.image', default=_get_logo, string="Company Logo", readonly=False) # logo_web: do not store in attachments, since the image is retrieved in SQL for # performance reasons (see addons/web/controllers/main.py, Binary.company_logo) logo_web = fields.Binary(compute='_compute_logo_web', store=True) @@ -50,10 +50,10 @@ class Company(models.Model): state_id = fields.Many2one('res.country.state', compute='_compute_address', inverse='_inverse_state', string="Fed. State") bank_ids = fields.One2many('res.partner.bank', 'company_id', string='Bank Accounts', help='Bank accounts related to this company') country_id = fields.Many2one('res.country', compute='_compute_address', inverse='_inverse_country', string="Country") - email = fields.Char(related='partner_id.email', store=True) - phone = fields.Char(related='partner_id.phone', store=True) - website = fields.Char(related='partner_id.website') - vat = fields.Char(related='partner_id.vat', string="Tax ID") + email = fields.Char(related='partner_id.email', store=True, readonly=False) + phone = fields.Char(related='partner_id.phone', store=True, readonly=False) + website = fields.Char(related='partner_id.website', readonly=False) + vat = fields.Char(related='partner_id.vat', string="Tax ID", readonly=False) company_registry = fields.Char() paperformat_id = fields.Many2one('report.paperformat', 'Paper format', default=lambda self: self.env.ref('base.paperformat_euro', raise_if_not_found=False)) external_report_layout_id = fields.Many2one('ir.ui.view', 'Document Template') diff --git a/odoo/addons/base/models/res_users.py b/odoo/addons/base/models/res_users.py index 90b4003156b7e428e9dfe43fc16da8032596c28b..b1aee2245f0367c2e712ee5fb51c5b8e421416a4 100644 --- a/odoo/addons/base/models/res_users.py +++ b/odoo/addons/base/models/res_users.py @@ -228,7 +228,7 @@ class Users(models.Model): help="If specified, this action will be opened at log on for this user, in addition to the standard menu.") groups_id = fields.Many2many('res.groups', 'res_groups_users_rel', 'uid', 'gid', string='Groups', default=_default_groups) log_ids = fields.One2many('res.users.log', 'create_uid', string='User log entries') - login_date = fields.Datetime(related='log_ids.create_date', string='Latest connection') + login_date = fields.Datetime(related='log_ids.create_date', string='Latest connection', readonly=False) share = fields.Boolean(compute='_compute_share', compute_sudo=True, string='Share User', store=True, help="External user with limited access, created only for the purpose of sharing data.") companies_count = fields.Integer(compute='_compute_companies_count', string="Number of Companies", default=_companies_count) @@ -248,8 +248,8 @@ class Users(models.Model): # overridden inherited fields to bypass access rights, in case you have # access to the user but not its corresponding partner - name = fields.Char(related='partner_id.name', inherited=True) - email = fields.Char(related='partner_id.email', inherited=True) + name = fields.Char(related='partner_id.name', inherited=True, readonly=False) + email = fields.Char(related='partner_id.email', inherited=True, readonly=False) _sql_constraints = [ ('login_key', 'UNIQUE (login)', 'You can not have two users with the same login !') diff --git a/odoo/addons/test_new_api/models.py b/odoo/addons/test_new_api/models.py index bb55424b9c9cffb9c8e44ecd851f3bbafb856fd7..a932197afc94d2eb7a524bc0f4489fbba909fd69 100644 --- a/odoo/addons/test_new_api/models.py +++ b/odoo/addons/test_new_api/models.py @@ -123,7 +123,7 @@ class Message(models.Model): display_name = fields.Char(string='Abstract', compute='_compute_display_name') size = fields.Integer(compute='_compute_size', search='_search_size') double_size = fields.Integer(compute='_compute_double_size') - discussion_name = fields.Char(related='discussion.name', string="Discussion Name") + discussion_name = fields.Char(related='discussion.name', string="Discussion Name", readonly=False) author_partner = fields.Many2one( 'res.partner', compute='_compute_author_partner', search='_search_author_partner') @@ -239,7 +239,7 @@ class Edition(models.Model): name = fields.Char() res_id = fields.Integer(required=True) res_model_id = fields.Many2one('ir.model', required=True) - res_model = fields.Char(related='res_model_id.model', store=True) + res_model = fields.Char(related='res_model_id.model', store=True, readonly=False) class Book(models.Model): @@ -321,8 +321,8 @@ class Bar(models.Model): name = fields.Char() foo = fields.Many2one('test_new_api.foo', compute='_compute_foo') - value1 = fields.Integer(related='foo.value1') - value2 = fields.Integer(related='foo.value2') + value1 = fields.Integer(related='foo.value1', readonly=False) + value2 = fields.Integer(related='foo.value2', readonly=False) @api.depends('name') def _compute_foo(self): @@ -336,12 +336,12 @@ class Related(models.Model): name = fields.Char() # related fields with a single field - related_name = fields.Char(related='name', string='A related on Name') - related_related_name = fields.Char(related='related_name', string='A related on a related on Name') + related_name = fields.Char(related='name', string='A related on Name', readonly=False) + related_related_name = fields.Char(related='related_name', string='A related on a related on Name', readonly=False) message = fields.Many2one('test_new_api.message') - message_name = fields.Text(related="message.body", related_sudo=False, string='Message Body') - message_currency = fields.Many2one(related="message.author", string='Message Author') + message_name = fields.Text(related="message.body", related_sudo=False, string='Message Body', readonly=False) + message_currency = fields.Many2one(related="message.author", string='Message Author', readonly=False) class ComputeProtected(models.Model): _name = 'test_new_api.compute.protected'