[IMP] base: uniform "groups" in back-end view
This revision is to make uniform the behavior of the `groups` attribute on the Python model fields and on the node in the view architecture. In both cases, remove the node from the view completely. Before this revision, in a back-end view: - In the Python model, if a field has the `groups` attribute set and the user is not part of the groups, the field is removed, completely, from the view. - In the view architecture, if a node has the `groups` attribute set and the user is not part of the groups, the node is made invisible (not completely removed, just made invisible). in a front-end view: - if a node has a "groups" or "t-groups" set and the user is not part of the groups, the node is removed from the view. So it's 2/3 cases removing nodes restricted to a group. and 1/3 case making invisible nodes restricted to a group. It's simpler to have a uniform behavior for the 3 cases, simpler to understandard for developers. In addition, this will help for the goal to cache back-end views. It makes possible to convert views using the `groups_id` field by moving the content of these views directly in the view to which they add content which is suppose to be completely removed when the user has not the according group. By getting rid of the `groups_id` many2many field on `ir.ui.view`, it makes possible to cache the view architecture without requiring to use the groups in the cache key. Currently, if we want to cache the view architecture, it would be required to use the intersection of the user groups with the `groups_id` groups of the view, making it costly to compute the cache key, therefore altering the performance point to cache the view architectures. closes odoo/odoo#95729 Related: odoo/enterprise#29592 Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
This commit is contained in:
@@ -2175,7 +2175,11 @@ class AccountMove(models.Model):
|
||||
for key in list(field_onchange):
|
||||
if key == to_del or key.startswith(f"{to_del}."):
|
||||
del field_onchange[key]
|
||||
del values[to_del]
|
||||
# test_01_account_tour
|
||||
# File "/data/build/odoo/addons/account/models/account_move.py", line 2127, in onchange
|
||||
# del values[to_del]
|
||||
# KeyError: 'line_ids'
|
||||
values.pop(to_del, None)
|
||||
return super().onchange(values, field_name, field_onchange)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<field name="model">account.account</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree editable="top" create="1" delete="1" multi_edit="1" string="Chart of accounts">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="code"/>
|
||||
<field name="name"/>
|
||||
<field name="account_type" widget="account_type_selection"/>
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
<field name="priority">1</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Account Journal">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="default_account_id" invisible="1"/>
|
||||
<field name="bank_statements_source" invisible="1"/>
|
||||
<sheet>
|
||||
<div name="button_box" class="oe_button_box">
|
||||
<button class="oe_stat_button" type="action"
|
||||
@@ -241,6 +244,7 @@
|
||||
<field name="priority">1</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree editable="bottom">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="name"/>
|
||||
<field name="excluded_journal_ids" widget="many2many_tags" options="{'no_create': True}"/>
|
||||
@@ -257,6 +261,7 @@
|
||||
<form string="Journal Groups">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="name" placeholder="e.g. GAAP, IFRS, ..."/>
|
||||
<field name="excluded_journal_ids" widget="many2many_tags" options="{'no_create': True}"/>
|
||||
<field name="sequence" groups="base.group_no_one"/>
|
||||
|
||||
@@ -165,6 +165,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Journal Items" create="false" edit="false" expand="context.get('expand', False)" multi_edit="1" sample="1">
|
||||
<field name="date" readonly="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="company_id" groups="base.group_multi_company" optional="hide"/>
|
||||
<field name="journal_id" options='{"no_open":True}' optional="hide"/>
|
||||
<field name="move_name" string="Journal Entry" widget="open_move_widget"/>
|
||||
@@ -706,12 +707,15 @@
|
||||
|
||||
<!-- Invisible fields -->
|
||||
<field name="id" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="journal_id" invisible="1"/>
|
||||
<field name="show_name_warning" invisible="1"/>
|
||||
<field name="posted_before" invisible="1"/>
|
||||
<field name="move_type" invisible="1"/>
|
||||
<field name="payment_state" invisible="1" force_save="1"/>
|
||||
<field name="invoice_filter_type_domain" invisible="1"/>
|
||||
<field name="suitable_journal_ids" invisible="1"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="company_currency_id" invisible="1"/>
|
||||
<field name="commercial_partner_id" invisible="1"/>
|
||||
<field name="bank_partner_id" invisible="1"/>
|
||||
@@ -897,6 +901,9 @@
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="company_currency_id" invisible="1"/>
|
||||
<field name="display_type" force_save="1" invisible="1"/>
|
||||
<!-- /l10n_in_edi.test_edi_json -->
|
||||
<!-- required for @api.onchange('product_id') -->
|
||||
<field name="product_uom_id" invisible="1"/>
|
||||
</tree>
|
||||
<kanban class="o_kanban_mobile">
|
||||
<!-- Displayed fields -->
|
||||
|
||||
@@ -127,6 +127,7 @@
|
||||
<field name="model">account.tax</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Account Tax">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
@@ -149,9 +150,9 @@
|
||||
<div attrs="{'invisible': [('amount_type', '=', 'group')]}">
|
||||
<field name="country_code" invisible="1"/>
|
||||
<label for="invoice_repartition_line_ids"/>
|
||||
<field name="invoice_repartition_line_ids" context="{'default_company_id': company_id}"/>
|
||||
<field name="invoice_repartition_line_ids"/>
|
||||
<label for="refund_repartition_line_ids"/>
|
||||
<field name="refund_repartition_line_ids" context="{'default_company_id': company_id}"/>
|
||||
<field name="refund_repartition_line_ids"/>
|
||||
</div>
|
||||
<field name="children_tax_ids" attrs="{'invisible':['|', ('amount_type','!=','group'), ('type_tax_use','=','none')]}" domain="[('type_tax_use','in',('none',type_tax_use)), ('amount_type','!=','group')]">
|
||||
<tree string="Children Taxes">
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
<group>
|
||||
<group>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="states_count" invisible="1"/>
|
||||
<field name="company_country_id" invisible="1"/>
|
||||
<field name="foreign_vat_header_mode" invisible="1"/>
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
<field name="model">account.analytic.group</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Analytic Account Groups">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
@@ -175,6 +176,7 @@
|
||||
<field name="model">account.analytic.account</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Analytic Account">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<sheet string="Analytic Account">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button" type="action" name="%(account_analytic_line_action)d" icon="fa-usd">
|
||||
@@ -312,6 +314,7 @@
|
||||
<field name="priority">1</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Analytic Entry">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<sheet>
|
||||
<group>
|
||||
<group name="analytic_entry" string="Analytic Entry">
|
||||
|
||||
@@ -34,7 +34,9 @@ class TestPartner(TestCrmCommon):
|
||||
self.assertEqual(child.user_id, self.env.user)
|
||||
|
||||
# test form tool
|
||||
partner_form = Form(self.env['res.partner'], 'base.view_partner_form')
|
||||
# <field name="team_id" groups="base.group_no_one"/>
|
||||
with self.debug_mode():
|
||||
partner_form = Form(self.env['res.partner'], 'base.view_partner_form')
|
||||
partner_form.parent_id = contact_company
|
||||
partner_form.company_type = 'person'
|
||||
partner_form.name = 'Hermes Conrad'
|
||||
@@ -45,7 +47,9 @@ class TestPartner(TestCrmCommon):
|
||||
self.assertEqual(partner_form.user_id, self.env.user)
|
||||
|
||||
# test form tool
|
||||
partner_form = Form(self.env['res.partner'], 'base.view_partner_form')
|
||||
# <field name="team_id" groups="base.group_no_one"/>
|
||||
with self.debug_mode():
|
||||
partner_form = Form(self.env['res.partner'], 'base.view_partner_form')
|
||||
# `parent_id` is invisible when `is_company` is True (`company_type == 'company'`)
|
||||
# and parent_id is not set
|
||||
# So, set a temporary `parent_id` before setting the contact as company
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
</header>
|
||||
<sheet>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="action_schedule_meeting" type="object"
|
||||
class="oe_stat_button" icon="fa-calendar"
|
||||
|
||||
@@ -137,6 +137,7 @@
|
||||
<field name="priority">12</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//sheet" position="before">
|
||||
<field name="use_leads" invisible="1"/>
|
||||
<header>
|
||||
<button name="action_assign_leads" type="object"
|
||||
string="Assign Leads"
|
||||
|
||||
@@ -44,6 +44,9 @@
|
||||
<field string="Opportunities" name="opportunity_count" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
<field name="parent_id" position="before">
|
||||
<field name="team_id" invisible="1"/>
|
||||
</field>
|
||||
<field name="parent_id" position="attributes">
|
||||
<attribute name="context">{'default_is_company': True, 'show_vat': True, 'default_user_id': user_id, 'default_team_id': team_id}</attribute>
|
||||
</field>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
</header>
|
||||
<div class="alert alert-danger text-center my-0" role="alert" attrs="{'invisible': [('error_type', '=', False)]}">
|
||||
<field name="error_type" invisible="1"/>
|
||||
<field name="lead_type" invisible="1"/>
|
||||
<span attrs="{'invisible': [('error_type', '!=', 'credits')]}">
|
||||
<span>You do not have enough credits to submit this request.
|
||||
<button name="action_buy_credits" type="object" class="oe_inline p-0 border-0 align-top text-primary">Buy credits.</button>
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
<group>
|
||||
<group name="provider_details">
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="prod_environment" invisible="1"/>
|
||||
<field name="debug_logging" invisible="1"/>
|
||||
<label for="delivery_type"/>
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
</button>
|
||||
</div>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="legend_blocked" invisible="1"/>
|
||||
<field name="legend_normal" invisible="1"/>
|
||||
<field name="legend_done" invisible="1"/>
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
<h1><field name="name" placeholder="e.g. B2B Fairs"/></h1>
|
||||
</div>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<group name="lead_creation_configuration">
|
||||
<group name="lead_creation_basis" invisible="1">
|
||||
<field name="lead_creation_basis" widget="radio"/>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<field name="model">fleet.vehicle.log.contract</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Contract logs">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<header>
|
||||
<button name="action_open" states="futur" type="object" string="Start Contract" class="oe_highlight" groups="fleet.fleet_group_manager"/>
|
||||
<button name="action_close" states="futur" type="object" string="Cancel" groups="fleet.fleet_group_manager"/>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
<field name="state_id" widget="statusbar" options="{'clickable': '1'}"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="country_code" invisible="1"/>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<field name="model">hr.department</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="department">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button" type="action" name="%(hr.act_employee_from_department)d" icon="fa-users">
|
||||
|
||||
@@ -46,9 +46,11 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Employee" js_class="hr_employee_form" class='o_employee_form'>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<field name="user_partner_id" invisible="1"/>
|
||||
<field name="hr_presence_state" invisible="1"/>
|
||||
<field name="image_128" invisible="1" />
|
||||
<field name="company_id" invisible="1"/>
|
||||
<header>
|
||||
<button name="%(plan_wizard_action)d" string="Launch Plan" type="action" groups="hr.group_hr_manager"/>
|
||||
</header>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Job">
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box"/>
|
||||
<div class="oe_title">
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
<field name="model">hr.plan</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Planning">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<sheet>
|
||||
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
|
||||
<div class="oe_title">
|
||||
@@ -82,6 +83,7 @@
|
||||
<field name="model">hr.plan.activity.type</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Activity">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="activity_type_id"/>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
<field name="model">hr.work.location</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Work Location">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<data>
|
||||
<div name="button_box" position="inside">
|
||||
<field name="contract_warning" invisible="1"/>
|
||||
<field name="employee_type" invisible="1"/>
|
||||
<button name="action_open_contract_history"
|
||||
class="oe_stat_button"
|
||||
icon="fa-book"
|
||||
@@ -153,6 +154,8 @@
|
||||
<group name="top_info">
|
||||
<group name="top_info_left">
|
||||
<field name="active" invisible="1"/>
|
||||
<!-- employee_id = fields.Many2one('hr.employee', string='Employee', tracking=True, domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]") -->
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="employee_id"/>
|
||||
<field name="date_start" string="Contract Start Date"/>
|
||||
<field name="date_end" string="Contract End Date"/>
|
||||
|
||||
@@ -132,6 +132,8 @@
|
||||
<field name="same_currency" invisible="1"/>
|
||||
<field name="is_editable" invisible="1"/>
|
||||
<field name="is_ref_editable" invisible="1"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="company_currency_id" invisible="1"/>
|
||||
<field name="amount_tax_company" invisible="1"/>
|
||||
<field name="unit_amount" invisible="1"/>
|
||||
@@ -688,6 +690,7 @@
|
||||
<form string="Expense Reports" class="o_expense_sheet">
|
||||
<field name="can_reset" invisible="1"/>
|
||||
<field name="can_approve" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<header>
|
||||
<button name="action_submit_sheet" states="draft" string="Submit to Manager" type="object" class="oe_highlight o_expense_sheet_submit" data-hotkey="l"/>
|
||||
<button name="approve_expense_sheets"
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
</div>
|
||||
</group>
|
||||
<group name="alloc_right_col">
|
||||
<field name="employee_id" invisible="1" groups="hr_holidays.group_hr_holidays_user"/>
|
||||
<field name="employee_id" invisible="1"/>
|
||||
<field name="department_id" invisible="1"/>
|
||||
</group>
|
||||
</group>
|
||||
@@ -168,6 +168,8 @@
|
||||
<field name="holiday_type" string="Mode" groups="hr_holidays.group_hr_holidays_user" context="{'employee_id':employee_id}" />
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='employee_id']" position="replace">
|
||||
<!-- :TestLeaveRequests.test_allocation_request -->
|
||||
<field name="employee_id" invisible="1"/>
|
||||
<field name="multi_employee" invisible="1" force_save="1"/>
|
||||
<!-- Employee id is only visible if the allocation is created specifically for that user in `_action_validate_create_childs` -->
|
||||
<field name="employee_id" groups="hr_holidays.group_hr_holidays_user"
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<field name="model">hr.leave.stress.day</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree editable="bottom">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="name"/>
|
||||
<field name="company_id" groups="base.group_multi_company" optional="hide"/>
|
||||
<field name="start_date"/>
|
||||
|
||||
@@ -463,7 +463,6 @@
|
||||
<field name="holiday_status_id" options="{'no_open': True}" context="{'request_type':'leave', 'from_manager_leave_form': True ,'employee_id': employee_id}"/>
|
||||
</h1>
|
||||
</div>
|
||||
<field name="employee_id" position="replace"/>
|
||||
<label id="label_dates" position="before">
|
||||
<field name="multi_employee" invisible="1" force_save="1"/>
|
||||
<field name="employee_id" groups="hr_holidays.group_hr_holidays_user" attrs="{
|
||||
|
||||
@@ -226,6 +226,7 @@
|
||||
<field name="inherit_id" ref="hr.hr_employee_public_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='coach_id']" position="after">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="leave_manager_id"/>
|
||||
</xpath>
|
||||
<xpath expr="//div[@name='button_box']" position="inside">
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
<attribute name="invisible">1</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='date_to']" position="after">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<xpath expr="//field[@name='calendar_id']" position="move"/>
|
||||
</xpath>
|
||||
</field>
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
<field name="model">hr.applicant</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Jobs - Recruitment Form" class="o_applicant_form">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="emp_id" invisible="1"/>
|
||||
<field name="meeting_ids" invisible="1"/>
|
||||
<field name="refuse_reason_id" invisible="1"/>
|
||||
|
||||
@@ -149,6 +149,7 @@
|
||||
<field name="amount" invisible="1"/>
|
||||
<field name="unit_amount" widget="timesheet_uom" decoration-danger="unit_amount > 24"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
|
||||
@@ -243,6 +243,7 @@
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='depend_on_ids']/tree//field[@name='company_id']" position="after">
|
||||
<field name="allow_subtasks" invisible="1" />
|
||||
<field name="progress" invisible="1"/>
|
||||
<field name="planned_hours" widget="timesheet_uom_no_toggle" sum="Initially Planned Hours" optional="hide"/>
|
||||
<field name="effective_hours" widget="timesheet_uom" sum="Effective Hours" optional="hide"/>
|
||||
<field name="subtask_effective_hours" widget="timesheet_uom" attrs="{'invisible' : [('allow_subtasks', '=', False)]}" optional="hide"/>
|
||||
@@ -272,6 +273,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<field name="company_id" position="after">
|
||||
<field name="allow_subtasks" invisible="1"/>
|
||||
<field name="progress" invisible="1"/>
|
||||
<field name="planned_hours" widget="timesheet_uom_no_toggle" sum="Initially Planned Hours" optional="hide"/>
|
||||
<field name="effective_hours" widget="timesheet_uom" sum="Effective Hours" optional="show"/>
|
||||
<field name="subtask_effective_hours" widget="timesheet_uom" attrs="{'invisible' : [('allow_subtasks', '=', False)]}" optional="hide"/>
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
</button>
|
||||
</div>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="applies_on" invisible="1"/>
|
||||
<div class="oe_title">
|
||||
<label for="name" string="Program Name"/>
|
||||
<h1>
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
<field name="model">lunch.product</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Products Form">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<sheet>
|
||||
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<field name="state" widget="statusbar"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<field name="active" invisible="1"/>
|
||||
<widget name="web_ribbon" title="Archived" bg_color="bg-danger"
|
||||
attrs="{'invisible': [('active', '=', True)]}"/>
|
||||
<group>
|
||||
@@ -74,7 +75,6 @@
|
||||
<field name="priority"/>
|
||||
<field name="attach"/>
|
||||
<field name="original"/>
|
||||
<field name="active" invisible="1"/>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<field name="is_mail_blacklist" attrs="{'readonly': [('state','!=', 'manual')]}" groups="base.group_no_one"/>
|
||||
</field>
|
||||
<xpath expr="//field[@name='field_id']//field[@name='copied']" position="after">
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="tracking" attrs="{'readonly': [('state','!=', 'manual')]}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
@@ -33,6 +34,7 @@
|
||||
<field name="inherit_id" ref="base.view_model_fields_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="copied" position="after">
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="tracking" attrs="{'readonly': [('state','!=', 'manual')]}"/>
|
||||
</field>
|
||||
</field>
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<field name="category"/>
|
||||
<field name="default_user_id" options="{'no_create': True}" domain="[('share', '=', False)]"/>
|
||||
<field name="res_model" groups="base.group_no_one"/>
|
||||
<field name="res_model" invisible="1"/>
|
||||
<field name="res_model_change" invisible="1"/>
|
||||
<field name="initial_res_model" invisible="1"/>
|
||||
<field name="summary" placeholder="e.g. "Discuss proposal""/>
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
<field name="state" widget="statusbar" statusbar_visible="outgoing,sent,received,exception,cancel"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<field name="model" invisible="1"/>
|
||||
<field name="res_id" invisible="1"/>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="action_open_document" string="Open Document"
|
||||
type="object" class="oe_link" icon="fa-file-text-o"
|
||||
|
||||
@@ -55,6 +55,8 @@
|
||||
<field name="model">maintenance.request</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Maintenance Request">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="category_id" invisible="1"/>
|
||||
<header>
|
||||
<button string="Cancel" name="archive_equipment_request" type="object" attrs="{'invisible': [('archive', '=', True)]}"/>
|
||||
<button string="Reopen Request" name="reset_equipment_request" type="object" attrs="{'invisible': [('archive', '=', False)]}"/>
|
||||
@@ -336,6 +338,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Equipments">
|
||||
<sheet>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="%(hr_equipment_request_action_from_equipment)d"
|
||||
type="action"
|
||||
|
||||
@@ -457,6 +457,8 @@
|
||||
<attribute name="class" remove="o-aside"/>
|
||||
</xpath>
|
||||
<xpath expr="//notebook/page[@name='mail_body']" position="after">
|
||||
<!-- test_01_mass_mailing_editor_tour -->
|
||||
<field name="body_html" invisible="1"/>
|
||||
<page string="Mail Debug" name="mail_debug" groups="base.group_no_one">
|
||||
<div class="position-relative">
|
||||
<div class="mt-n2">
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
attrs="{'invisible': ['|', ('mailing_mail_count', '=', 0), ('is_mailing_campaign_activated', '=', False)]}"
|
||||
groups="mass_mailing.group_mass_mailing_user">
|
||||
<field name="mailing_mail_count" widget="statinfo" string="Mailings"/>
|
||||
<field name="ab_testing_mailings_count" invisible="1"/>
|
||||
</button>
|
||||
</xpath>
|
||||
<xpath expr="//notebook" position="inside">
|
||||
@@ -46,6 +45,7 @@
|
||||
</page>
|
||||
</xpath>
|
||||
<xpath expr="//notebook" position="after">
|
||||
<field name="ab_testing_mailings_count" invisible="1"/>
|
||||
<group name="ab_test_group" groups="mass_mailing.group_mass_mailing_campaign" attrs="{'invisible': [('ab_testing_mailings_count', '=', 0)]}">
|
||||
<group string="A/B Test">
|
||||
<field name="ab_testing_completed" invisible="1"/>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='stage_id']" position="before">
|
||||
<field name="event_registrations_open" invisible="1"/>
|
||||
<field name="seats_expected" invisible="1"/>
|
||||
<button name="action_invite_contacts" type="object" string="Invite"
|
||||
class="btn btn-primary"
|
||||
groups="mass_mailing.group_mass_mailing_user"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<field name="inherit_id" ref="event.view_event_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='stage_id']" position="before">
|
||||
<field name="track_count" invisible="1"/>
|
||||
<button name="action_mass_mailing_track_speakers" string="Contact Track Speakers" type="object" attrs="{'invisible': [('track_count', '=', 0)]}" groups="mass_mailing.group_mass_mailing_user"/>
|
||||
</xpath>
|
||||
</field>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<field name="inherit_id" ref="website_slides.view_slide_channel_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<button name="action_channel_invite" position="after">
|
||||
<field name="members_count" invisible="1"/>
|
||||
<button name="action_mass_mailing_attendees" string="Contact Attendees" type="object"
|
||||
class="oe_highlight" attrs="{'invisible': [('members_count', '=', 0)]}"
|
||||
groups="mass_mailing.group_mass_mailing_user"/>
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
attrs="{'invisible': ['|', ('mailing_sms_count', '=', 0), ('is_mailing_campaign_activated', '=', False)]}"
|
||||
icon="fa-mobile" groups="mass_mailing.group_mass_mailing_user">
|
||||
<field name="mailing_sms_count" widget="statinfo" string="SMS"/>
|
||||
<field name="ab_testing_mailings_sms_count" invisible="1"/>
|
||||
</button>
|
||||
</xpath>
|
||||
<xpath expr="//sheet" position="inside">
|
||||
<field name="ab_testing_mailings_sms_count" invisible="1"/>
|
||||
</xpath>
|
||||
<xpath expr="//notebook" position="inside">
|
||||
<page string="SMS" name="sms"
|
||||
attrs="{'invisible': ['|', ('mailing_sms_count', '=', 0), ('is_mailing_campaign_activated', '=', False)]}"
|
||||
|
||||
@@ -1822,6 +1822,10 @@ class TestMrpOrder(TestMrpCommon):
|
||||
})
|
||||
self.env['stock.quant']._update_available_quantity(storable_component, self.env.ref('stock.stock_location_stock'), 100)
|
||||
|
||||
# Despite the purpose of this test is to use multi uom
|
||||
# tests the production choose the right uoms on all models without
|
||||
# having the uom fields in the interface views
|
||||
self.env.user.groups_id -= self.env.ref('uom.group_uom')
|
||||
for component in [consumable_component, storable_component]:
|
||||
bom = self.env['mrp.bom'].create({
|
||||
'product_tmpl_id': product.product_tmpl_id.id,
|
||||
|
||||
@@ -51,8 +51,10 @@
|
||||
<group>
|
||||
<group>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="product_tmpl_id" context="{'default_detailed_type': 'product'}"/>
|
||||
<field name="product_uom_category_id" invisible="1"/>
|
||||
<field name="allow_operation_dependencies" invisible="1"/>
|
||||
<field name="product_id" groups="product.group_product_variant" context="{'default_detailed_type': 'product'}"/>
|
||||
<label for="product_qty" string="Quantity"/>
|
||||
<div class="o_row">
|
||||
@@ -79,7 +81,7 @@
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Components" name="components">
|
||||
<field name="bom_line_ids" widget="one2many" context="{'default_parent_product_tmpl_id': product_tmpl_id, 'default_product_id': False, 'default_company_id': company_id, 'default_bom_id': id}">
|
||||
<field name="bom_line_ids" widget="one2many" context="{'default_parent_product_tmpl_id': product_tmpl_id, 'default_product_id': False, 'default_bom_id': id}">
|
||||
<tree string="Components" editable="bottom">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="sequence" widget="handle"/>
|
||||
@@ -108,13 +110,13 @@
|
||||
<field name="operation_ids"
|
||||
attrs="{'invisible': [('type','not in',('normal','phantom'))]}"
|
||||
groups="mrp.group_mrp_routings"
|
||||
context="{'bom_id_invisible': True, 'default_company_id': company_id, 'default_bom_id': id, 'tree_view_ref': 'mrp.mrp_routing_workcenter_bom_tree_view'}" widget="mrp_one2many_with_copy"/>
|
||||
context="{'bom_id_invisible': True, 'default_bom_id': id, 'tree_view_ref': 'mrp.mrp_routing_workcenter_bom_tree_view'}" widget="mrp_one2many_with_copy"/>
|
||||
</page>
|
||||
<page string="By-products"
|
||||
name="by_products"
|
||||
attrs="{'invisible': [('type','!=','normal')]}"
|
||||
groups="mrp.group_mrp_byproducts">
|
||||
<field name="byproduct_ids" context="{'form_view_ref' : 'mrp.mrp_bom_byproduct_form_view', 'default_company_id': company_id, 'default_bom_id': id}">
|
||||
<field name="byproduct_ids" context="{'form_view_ref' : 'mrp.mrp_bom_byproduct_form_view', 'default_bom_id': id}">
|
||||
<tree string="By-products" editable="top">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="product_uom_category_id" invisible="1"/>
|
||||
|
||||
@@ -138,6 +138,7 @@
|
||||
<field name="consumption" invisible="1"/>
|
||||
<field name="is_planned" invisible="1"/>
|
||||
<field name="show_allocation" invisible="1"/>
|
||||
<field name="workorder_ids" invisible="1"/>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="action_view_reception_report" string="Allocation" type="object"
|
||||
class="oe_stat_button" icon="fa-list"
|
||||
@@ -194,6 +195,7 @@
|
||||
<field name="product_id" context="{'default_detailed_type': 'product'}" attrs="{'readonly': [('state', '!=', 'draft')]}" default_focus="1"/>
|
||||
<field name="product_tmpl_id" invisible="1"/>
|
||||
<field name="forecasted_issue" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="product_description_variants" attrs="{'invisible': [('product_description_variants', 'in', (False, ''))], 'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<label for="bom_id" name="bom_label"/>
|
||||
<div class='o_row d-flex' name="bom_div">
|
||||
@@ -213,6 +215,7 @@
|
||||
</button>
|
||||
<label for="product_uom_id" string="" class="oe_inline"/>
|
||||
<field name="product_uom_category_id" invisible="1"/>
|
||||
<field name="product_uom_id" groups="!uom.group_uom" invisible="1"/>
|
||||
<field name="product_uom_id" options="{'no_open': True, 'no_create': True}" groups="uom.group_uom" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<span class='fw-bold'>To Produce</span>
|
||||
<button type="object" name="action_product_forecast_report" title="Forecast Report" icon="fa-area-chart" attrs="{'invisible': [('forecasted_issue', '=', True)]}"/>
|
||||
@@ -267,6 +270,26 @@
|
||||
<!-- Useless as the editable in tree declaration -> For Form Test-->
|
||||
<field name="product_uom_category_id"/>
|
||||
<field name="allowed_operation_ids"/>
|
||||
<!--
|
||||
Required for test_00_mrp_byproduct
|
||||
when changing the mrp.production product_qty
|
||||
`_onchange_producing` is called,
|
||||
calling `_set_qty_producing`,
|
||||
which changes the `quantity_done` of byproducts
|
||||
If byproducts are not in the view (`groups="mrp.group_mrp_byproducts"`)
|
||||
and `quantity_done` is not within the finished move views,
|
||||
(byproduct moves are a subset of finished moves)
|
||||
the `quantity_done` of byproducts is not updated correctly with the onchange
|
||||
Another solution is to add `self.env.user.groups_id += self.env.ref('mrp.group_mrp_byproducts')`
|
||||
to the test `test_00_mrp_byproduct`, which could makes sense as it's a test testing the byproducts features,
|
||||
for which you should have the byproducts group to have access to,
|
||||
but it seemed better to keep the feature working even if you do not see the byproducts features with your user.
|
||||
That being said, the best would be to have the byproducts feature working without relying on anything in the view,
|
||||
e.g. so the byproducts feature works with xmlrpc calls.
|
||||
-->
|
||||
<field name="quantity_done"/>
|
||||
<!-- Required for test_fifo_byproduct -->
|
||||
<field name="cost_share"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
@@ -280,6 +303,8 @@
|
||||
<tree default_order="is_done, manual_consumption desc, sequence" editable="bottom">
|
||||
<field name="product_id" force_save="1" required="1" context="{'default_detailed_type': 'product'}" attrs="{'readonly': ['|', '|', ('move_lines_count', '>', 0), ('state', '=', 'cancel'), '&', ('state', '!=', 'draft'), ('additional', '=', False) ]}"/>
|
||||
<field name="location_id" string="From" readonly="1" groups="stock.group_stock_multi_locations" optional="show"/>
|
||||
<!-- test_immediate_validate_uom_2, test_product_produce_different_uom -->
|
||||
<field name="product_uom" invisible="1"/>
|
||||
<field name="propagate_cancel" invisible="1"/>
|
||||
<field name="price_unit" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
@@ -385,8 +410,10 @@
|
||||
<group>
|
||||
<field name="picking_type_id" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="location_src_id" groups="stock.group_stock_multi_locations" options="{'no_create': True}" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="location_src_id" groups="!stock.group_stock_multi_locations" invisible="1"/>
|
||||
<field name="warehouse_id" invisible="1"/>
|
||||
<field name="location_dest_id" groups="stock.group_stock_multi_locations" options="{'no_create': True}" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="location_dest_id" groups="!stock.group_stock_multi_locations" invisible="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="origin"/>
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
<group>
|
||||
<group name="description">
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="name"/>
|
||||
<field name="bom_id" invisible="context.get('bom_id_invisible', False)" domain="[]" readonly="context.get('default_bom_id', False)"/>
|
||||
<field name="workcenter_id" context="{'default_company_id': company_id}"/>
|
||||
|
||||
@@ -88,6 +88,7 @@
|
||||
<field name="model">mrp.unbuild</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Unbuild Orders">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<header>
|
||||
<button name="action_validate" string="Unbuild" type="object" states="draft" class="oe_highlight" data-hotkey="v"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,done"/>
|
||||
@@ -140,6 +141,7 @@
|
||||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="product_id" invisible="1"/>
|
||||
<field name="bom_id" invisible="1"/>
|
||||
|
||||
@@ -342,12 +342,12 @@
|
||||
<group>
|
||||
<group>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="name" string="Work Center Name" required="True"/>
|
||||
<field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color'}"/>
|
||||
<field
|
||||
name="alternative_workcenter_ids"
|
||||
widget="many2many_tags"
|
||||
context="{'default_company_id': company_id}"
|
||||
/>
|
||||
</group>
|
||||
<group>
|
||||
@@ -388,7 +388,7 @@
|
||||
<field name="note" nolabel="1" placeholder="Description of the work center..."/>
|
||||
</page>
|
||||
<page string="Specific Capacities" name="capacity">
|
||||
<field name="capacity_ids" context="{'default_workcenter_id': id, 'default_company_id': company_id}">
|
||||
<field name="capacity_ids" context="{'default_workcenter_id': id}">
|
||||
<tree editable="bottom">
|
||||
<field name="product_id"/>
|
||||
<field name="product_uom_id" groups="uom.group_uom"/>
|
||||
|
||||
@@ -230,6 +230,7 @@
|
||||
<page string="Blocked By" name="dependencies" attrs="{'invisible': [('allow_workorder_dependencies', '=', False)]}">
|
||||
<field name="blocked_by_workorder_ids" nolabel="1">
|
||||
<tree editable="bottom">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="name" string="Operation"/>
|
||||
<field name="company_id" optional="hide" groups="base.group_multi_company"/>
|
||||
<field name="workcenter_id"/>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<attribute name="groups">stock.group_stock_manager</attribute>
|
||||
</field>
|
||||
<field name="picking_ids" position="after">
|
||||
<field name="target_model" invisible="1"/>
|
||||
<field name="mrp_production_ids"
|
||||
widget="many2many_tags" options="{'no_create_edit': True}"
|
||||
attrs="{'invisible': [('target_model', '!=', 'manufacturing')]}"
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<form create="0" delete="0">
|
||||
<header>
|
||||
<field name="state" widget="statusbar" groups="base.group_user"/>
|
||||
<field name="state" widget="statusbar"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<field name="product_uom_category_id" invisible="1"/>
|
||||
@@ -99,6 +99,7 @@
|
||||
<field name="picking_id" invisible="1"/>
|
||||
<field name="location_dest_id" invisible="1"/>
|
||||
<field name="has_tracking" invisible="1"/>
|
||||
<field name="product_uom" invisible="1"/>
|
||||
<field name="product_uom_qty" invisible="1"/>
|
||||
<group>
|
||||
<field name="order_finished_lot_id"/>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<field name="model">payment.acquirer</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Payment Acquirer">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="is_published" invisible="1"/>
|
||||
<field name="main_currency_id" invisible="1"/>
|
||||
<field name="support_fees" invisible="1"/>
|
||||
@@ -22,6 +23,7 @@
|
||||
<field name="show_auth_msg" invisible="1"/>
|
||||
<field name="show_done_msg" invisible="1"/>
|
||||
<field name="show_cancel_msg" invisible="1"/>
|
||||
<field name="provider" invisible="1"/>
|
||||
<sheet>
|
||||
<!-- === Stat Buttons === -->
|
||||
<div class="oe_button_box" name="button_box">
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
</h1>
|
||||
<group>
|
||||
<field name="id" invisible='1'/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<group name="group_product">
|
||||
<field name="product_id" required='True' attrs="{'readonly': [('id', '!=', False)]}"/>
|
||||
</group>
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
<!-- Scope = coming from a product/product template -->
|
||||
<field name="pricelist_id" string="Pricelist" options="{'no_create_edit':1, 'no_open': 1}"/>
|
||||
<field name="name" string="Applied On"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="categ_id" invisible="1"/>
|
||||
<field name="product_tmpl_id"
|
||||
invisible="context.get('active_model')!='product.category'"
|
||||
@@ -93,6 +94,7 @@
|
||||
<form string="Pricelist Rule">
|
||||
<sheet>
|
||||
<field name="name" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<group name="pricelist_rule_computation" groups="product.group_sale_pricelist" string="Price Computation">
|
||||
<group name="pricelist_rule_method">
|
||||
<field name="compute_price" string="Computation" widget="radio"/>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
<field name='is_product_variant' invisible='1'/>
|
||||
<field name='attribute_line_ids' invisible='1'/>
|
||||
<field name="type" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button"
|
||||
name="open_pricelist_rules"
|
||||
@@ -53,7 +54,7 @@
|
||||
margin-right: 0px;
|
||||
}
|
||||
</style>
|
||||
<div name="options" groups="base.group_user">
|
||||
<div name="options">
|
||||
<span class="d-inline-block">
|
||||
<field name="sale_ok"/>
|
||||
<label for="sale_ok"/>
|
||||
|
||||
@@ -133,7 +133,9 @@ const ProjectFormController = FormController.extend({
|
||||
async _saveRecord(recordID, options) {
|
||||
const task = this.model.get(recordID || this.handle);
|
||||
const result = await this._super(...arguments);
|
||||
let tasksX2ManyFields = result.filter(fieldName => ['child_ids', 'depend_on_ids'].includes(fieldName));
|
||||
// --test-tags /industry_fsm.test_ui
|
||||
// <page name="task_dependencies" groups="project.group_project_task_dependencies"></page>
|
||||
let tasksX2ManyFields = Object.keys(task.data).filter(fieldName => ['child_ids', 'depend_on_ids'].includes(fieldName));
|
||||
if (tasksX2ManyFields.length) {
|
||||
const taskResIds = [];
|
||||
for (const taskX2ManyFieldName of tasksX2ManyFields) {
|
||||
|
||||
@@ -434,6 +434,8 @@
|
||||
<field name="model">project.project</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Project" class="o_form_project_project" js_class="form_description_expander">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="analytic_account_id" invisible="1"/>
|
||||
<header>
|
||||
<button name="%(project.project_share_wizard_action)d" string="Share Readonly" type="action" class="oe_highlight" groups="project.group_project_manager"
|
||||
attrs="{'invisible': [('privacy_visibility', '!=', 'portal')]}" context="{'default_access_mode': 'read'}" data-hotkey="r"/>
|
||||
@@ -444,6 +446,7 @@
|
||||
<sheet string="Project">
|
||||
<div class="oe_button_box" name="button_box" groups="base.group_user">
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="allow_milestones" invisible="1"/>
|
||||
<button class="oe_stat_button" type="object" name="action_view_analytic_account_entries" icon="fa-usd" attrs="{'invisible': [('analytic_account_id', '=', False)]}" groups="analytic.group_analytic_accounting">
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_value">
|
||||
@@ -1080,6 +1083,8 @@
|
||||
<field name="rating_last_value" invisible="1"/>
|
||||
<field name="rating_count" invisible="1"/>
|
||||
<field name="allow_milestones" invisible="1" />
|
||||
<field name="parent_id" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<header>
|
||||
<button name="action_assign_to_me" string="Assign to Me" type="object" attrs="{'invisible': "['|', ('user_ids', 'in', uid), ('user_ids', '=', [])]"}" data-hotkey="q"/>
|
||||
<button name="action_assign_to_me" string="Assign to Me" type="object" class="oe_highlight" attrs="{'invisible' : "['|', ('user_ids', 'in', uid), ('user_ids', '!=', [])]"}" data-hotkey="q"/>
|
||||
@@ -1189,6 +1194,7 @@
|
||||
<page name="sub_tasks_page" string="Sub-tasks" attrs="{'invisible': [('allow_subtasks', '=', False)]}">
|
||||
<field name="child_ids" context="{'default_project_id': project_id if not parent_id or not display_project_id else display_project_id, 'default_user_ids': user_ids, 'default_parent_id': id, 'default_partner_id': partner_id, 'default_milestone_id': allow_milestones and milestone_id}" widget="subtasks_one2many">
|
||||
<tree editable="bottom">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="legend_normal" invisible="1"/>
|
||||
<field name="legend_done" invisible="1"/>
|
||||
<field name="legend_blocked" invisible="1"/>
|
||||
@@ -1226,6 +1232,7 @@
|
||||
<page name="task_dependencies" string="Blocked By" attrs="{'invisible': [('allow_task_dependencies', '=', False)]}" groups="project.group_project_task_dependencies">
|
||||
<field name="depend_on_ids" nolabel="1" context="{'default_project_id' : project_id}">
|
||||
<tree editable="bottom">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="allow_milestones" invisible="1"/>
|
||||
<field name="parent_id" invisible="1" />
|
||||
<field name="display_project_id" invisible="1" />
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<group name="timesheet" groups="base.group_no_one" style="width:50%">
|
||||
<h2>Timesheets</h2>
|
||||
<field name="timesheet_project_id" context="{'active_test': False}"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="timesheet_task_id" context="{'active_test': False, 'default_project_id': timesheet_project_id}" attrs="
|
||||
{'invisible': [('timesheet_project_id', '=', False)], 'required': [('timesheet_project_id', '!=', False)]}"/>
|
||||
<field name="timesheet_generate" invisible="1"/>
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
<xpath expr="//tree" position="attributes">
|
||||
<attribute name="editable">bottom</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//tree" position="inside">
|
||||
<field name="company_id" invisible="1"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='company_id']" position="attributes">
|
||||
<attribute name="readonly">0</attribute>
|
||||
<attribute name="optional">hide</attribute>
|
||||
|
||||
@@ -176,6 +176,7 @@
|
||||
<field name="partner_ref"/>
|
||||
<field name="currency_id" groups="base.group_multi_currency" force_save="1"/>
|
||||
<field name="id" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="date_order" attrs="{'invisible': [('state','in',('purchase','done'))]}"/>
|
||||
@@ -221,6 +222,7 @@
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="product_type" invisible="1"/>
|
||||
<field name="product_uom" invisible="1" groups="!uom.group_uom"/>
|
||||
<field name="product_uom_category_id" invisible="1"/>
|
||||
<field name="invoice_lines" invisible="1"/>
|
||||
<field name="sequence" widget="handle"/>
|
||||
|
||||
@@ -104,6 +104,7 @@
|
||||
<field name="model">purchase.requisition</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Purchase Agreements">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<header>
|
||||
<button name="%(action_purchase_requisition_to_so)d" type="action"
|
||||
string="New Quotation"
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
<field name="description"/>
|
||||
<field name="invoice_state" invisible="1"/>
|
||||
<field name="tracking" invisible="1" attrs="{'readonly': 1}"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="product_id"/>
|
||||
<field name="lot_id" context="{'default_product_id': product_id, 'default_company_id': company_id}" groups="stock.group_production_lot" attrs="{'required':[('tracking', 'in', ['serial', 'lot'])], 'invisible': [('tracking', 'not in', ['serial', 'lot'])], 'readonly': ['|', ('state', '=', 'done'), ('tracking', 'not in', ['serial', 'lot'])]}"/>
|
||||
<field name="product_uom_category_id" invisible="1"/>
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
<form string="Resource">
|
||||
<sheet>
|
||||
<field name="active" invisible="1" />
|
||||
<field name="company_id" invisible="1"/>
|
||||
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
|
||||
<group>
|
||||
<group name="user_details">
|
||||
@@ -57,6 +58,7 @@
|
||||
<field name="model">resource.resource</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Resources" multi_edit="1" default_order="name">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="name" />
|
||||
<field name="user_id" />
|
||||
<field name="company_id" groups="base.group_multi_company" optional="show"/>
|
||||
@@ -125,6 +127,7 @@
|
||||
<field name="model">resource.calendar.leaves</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Leave Detail">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<sheet>
|
||||
<group>
|
||||
<group name="leave_details">
|
||||
|
||||
@@ -272,7 +272,9 @@
|
||||
confirm="This will update all unit prices based on the currently set pricelist."
|
||||
attrs="{'invisible': ['|', ('show_update_pricelist', '=', False), ('state', 'in', ['sale', 'done','cancel'])]}"/>
|
||||
</div>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="pricelist_id" invisible="1"/>
|
||||
<field name="tax_country_id" invisible="1"/>
|
||||
<field name="payment_term_id" options="{'no_open':True,'no_create': True}"/>
|
||||
</group>
|
||||
@@ -318,6 +320,7 @@
|
||||
<field
|
||||
context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom, 'uom_qty_change':True, 'company_id': parent.company_id}"
|
||||
name="product_uom_qty"/>
|
||||
<field name="product_uom" invisible="1" groups="!uom.group_uom"/>
|
||||
<field
|
||||
name="product_uom"
|
||||
force_save="1"
|
||||
@@ -465,6 +468,7 @@
|
||||
/>
|
||||
<field name="qty_to_invoice" invisible="1"/>
|
||||
<field name="product_uom_readonly" invisible="1"/>
|
||||
<field name="product_uom" invisible="1" groups="!uom.group_uom"/>
|
||||
<field
|
||||
name="product_uom"
|
||||
force_save="1"
|
||||
@@ -511,7 +515,7 @@
|
||||
<field name="name"/>
|
||||
<field name="product_id"/>
|
||||
<field name="product_uom_qty"/>
|
||||
<field name="product_uom" groups="uom.group_uom"/>
|
||||
<field name="product_uom"/>
|
||||
<field name="price_subtotal"/>
|
||||
<field name="price_total"/>
|
||||
<field name="price_tax" invisible="1"/>
|
||||
@@ -601,8 +605,11 @@
|
||||
confirm="This will update all taxes based on the currently selected fiscal position."
|
||||
attrs="{'invisible': ['|', ('show_update_fpos', '=', False), ('state', 'in', ['sale', 'done','cancel'])]}"/>
|
||||
</div>
|
||||
<field name="partner_invoice_id" invisible="1"/>
|
||||
<field name="analytic_account_id" context="{'default_partner_id':partner_invoice_id, 'default_name':name}" attrs="{'readonly': [('invoice_count','!=',0),('state','=','sale')]}" groups="analytic.group_analytic_accounting" force_save="1"/>
|
||||
<field name="invoice_status" states="sale,done" groups="base.group_no_one"/>
|
||||
<!-- test_event_configurator -->
|
||||
<field name="invoice_status" invisible="1" groups="!base.group_no_one"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
|
||||
@@ -12,6 +12,12 @@
|
||||
<xpath expr="//field[@name='child_ids']//field[@name='type']" position="attributes">
|
||||
<attribute name="groups">account.group_delivery_invoice_address</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//group/group/span/field[@name='type']" position="after">
|
||||
<field name="type" invisible="1"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='child_ids']//field[@name='type']" position="after">
|
||||
<field name="type" invisible="1"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<group>
|
||||
<group>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<label for="number_of_days" string="Quotation Validity"/>
|
||||
<div id="number_of_days">
|
||||
<field name="number_of_days" class="oe_inline"/> days
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
<field name="inherit_id" ref="sale.view_order_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='order_line']/tree//field[@name='price_unit']" position="after">
|
||||
<field name="price_subtotal" invisible="1"/>
|
||||
<field name="purchase_price" optional="hide"/>
|
||||
<field name="margin" optional="hide"/>
|
||||
<field name="margin_percent"
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
<field name="priority">10</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//button[@name='action_view_invoice']" position="before">
|
||||
<field name="project_ids" invisible="1"/>
|
||||
<field name="is_product_milestone" invisible="1"/>
|
||||
<button type="object" name="action_view_project_ids" class="oe_stat_button" icon="fa-puzzle-piece" attrs="{'invisible': ['|', ('state', 'in', ['draft', 'sent']), ('project_ids', '=', [])]}" groups="project.group_project_user">
|
||||
<field name="project_ids" invisible="1"/>
|
||||
<field name="project_count" widget="statinfo" string="Projects"/>
|
||||
</button>
|
||||
<field name="is_product_milestone" invisible="1"/>
|
||||
<button class="oe_stat_button" name="action_view_milestone" type="object" icon="fa-check-square-o" attrs="{'invisible': ['|', ('is_product_milestone', '=', False), ('project_ids', '=', [])]}" groups="project.group_project_milestone">
|
||||
<field name="milestone_count" widget="statinfo" string="Milestones"/>
|
||||
</button>
|
||||
|
||||
@@ -175,6 +175,7 @@
|
||||
optional="hide"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='remaining_hours']" position="after">
|
||||
<field name="sale_order_id" invisible="1"/>
|
||||
<field name="remaining_hours_available" invisible="1"/>
|
||||
<span id="remaining_hours_so_label" attrs="{'invisible': ['|', '|', '|', '|', ('allow_billable', '=', False), ('sale_order_id', '=', False), ('partner_id', '=', False), ('sale_line_id', '=', False), ('remaining_hours_available', '=', False)]}">
|
||||
<label class="fw-bold" for="remaining_hours_so" string="Remaining Hours on SO"
|
||||
|
||||
@@ -95,6 +95,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Sales Men">
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="is_membership_multi" invisible="1"/>
|
||||
<field name="member_warning" invisible="1"/>
|
||||
<field name="user_in_teams_ids" invisible="1"/>
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
<field name="model">stock.putaway.rule</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Putaway Rules" editable="bottom" sample='1'>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="package_type_ids" invisible="1"/>
|
||||
<field name="sequence" widget="handle"
|
||||
invisible="context.get('invisible_handle', False)"/>
|
||||
<field name="location_in_id" string="When product arrives in"
|
||||
|
||||
@@ -252,6 +252,7 @@
|
||||
attrs="{'invisible': [('type', 'not in', ['consu', 'product'])]}"/>
|
||||
</header>
|
||||
<div name="button_box" position="inside">
|
||||
<field name="tracking" invisible="1"/>
|
||||
<field name="show_on_hand_qty_status_button" invisible="1"/>
|
||||
<field name="show_forecasted_qty_status_button" invisible="1"/>
|
||||
<button class="oe_stat_button"
|
||||
@@ -358,6 +359,7 @@
|
||||
attrs="{'invisible': [('type', 'not in', ['consu', 'product'])]}"/>
|
||||
</header>
|
||||
<div name="button_box" position="inside">
|
||||
<field name="tracking" invisible="1"/>
|
||||
<field name="show_on_hand_qty_status_button" invisible="1"/>
|
||||
<field name="show_forecasted_qty_status_button" invisible="1"/>
|
||||
<button type="object"
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
<field name="model">stock.location</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Stock Location" create="false">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button string="Putaway Rules"
|
||||
@@ -180,6 +181,7 @@
|
||||
<field eval="7" name="priority" />
|
||||
<field name="arch" type="xml">
|
||||
<form string="Route">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<sheet>
|
||||
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
|
||||
<div class="oe_title">
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Lots/Serial Numbers">
|
||||
<sheet>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="display_complete" invisible="1"/>
|
||||
<div class="oe_button_box" name="button_box"
|
||||
attrs="{'invisible': [('display_complete', '=', False)]}">
|
||||
|
||||
@@ -62,6 +62,9 @@
|
||||
<sheet>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="picking_id" invisible="1"/>
|
||||
<field name="location_id" invisible="1"/>
|
||||
<field name="location_dest_id" invisible="1"/>
|
||||
<field name="package_id" invisible="1"/>
|
||||
<field name="product_uom_category_id" invisible="1"/>
|
||||
<group>
|
||||
<group>
|
||||
|
||||
@@ -220,6 +220,9 @@
|
||||
<field name="product_uom_category_id" invisible="1"/>
|
||||
<field name="product_id" invisible="1"/>
|
||||
<field name="package_level_id" invisible="1"/>
|
||||
<field name="location_id" invisible="1"/>
|
||||
<field name="location_dest_id" invisible="1"/>
|
||||
<field name="package_id" invisible="1"/>
|
||||
<field name="location_id" options="{'no_create': True}" attrs="{'readonly': ['&', ('package_level_id', '!=', False), ('parent.picking_type_entire_packs', '=', True)]}" invisible="not context.get('show_source_location')" domain="[('id', 'child_of', parent.location_id), '|', ('company_id', '=', False), ('company_id', '=', company_id), ('usage', '!=', 'view')]" groups="stock.group_stock_multi_locations"/>
|
||||
<field name="location_dest_id" width="0.75" attrs="{'readonly': ['&', ('package_level_id', '!=', False), ('parent.picking_type_entire_packs', '=', True)]}" invisible="not context.get('show_destination_location')" domain="[('id', 'child_of', parent.location_dest_id), '|', ('company_id', '=', False), ('company_id', '=', company_id), ('usage', '!=', 'view')]" groups="stock.group_stock_multi_locations"/>
|
||||
<field name="lot_id" groups="stock.group_production_lot"
|
||||
@@ -263,6 +266,10 @@
|
||||
<field name="move_id" invisible="1"/>
|
||||
<field name="picking_id" invisible="1"/>
|
||||
<field name="product_uom_category_id" invisible="1"/>
|
||||
<field name="package_id" invisible="1"/>
|
||||
<field name="result_package_id" invisible="1"/>
|
||||
<field name="location_id" invisible="1"/>
|
||||
<field name="location_dest_id" invisible="1"/>
|
||||
<field name="location_id" options="{'no_create': True}" attrs="{'column_invisible': [('parent.picking_type_code', '=', 'incoming')]}" groups="stock.group_stock_multi_locations" domain="[('id', 'child_of', parent.location_id), '|', ('company_id', '=', False), ('company_id', '=', company_id), ('usage', '!=', 'view')]"/>
|
||||
<field name="location_dest_id" options="{'no_create': True}" attrs="{'column_invisible': [('parent.picking_type_code', '=', 'outgoing')]}" groups="stock.group_stock_multi_locations" domain="[('id', 'child_of', parent.location_dest_id), '|', ('company_id', '=', False), ('company_id', '=', company_id), ('usage', '!=', 'view')]"/>
|
||||
<field name="package_id" groups="stock.group_tracking_lot"/>
|
||||
@@ -287,6 +294,7 @@
|
||||
<field eval="1" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Stock Moves" create="0" edit="0">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<header>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,confirmed,assigned,done" />
|
||||
</header>
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Reordering Rules" editable="bottom" js_class="stock_orderpoint_list" sample="1" multi_edit="1">
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="product_category_id" invisible="1"/>
|
||||
<field name="product_tmpl_id" invisible="1"/>
|
||||
<field name="product_id" attrs="{'readonly': [('product_id', '!=', False)]}" invisible="context.get('default_product_id')" force_save="1"/>
|
||||
@@ -140,6 +141,7 @@
|
||||
<group>
|
||||
<group>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="route_id" invisible="1"/>
|
||||
<field name="product_id"/>
|
||||
<label for="product_min_qty"/>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,confirmed,assigned,done" />
|
||||
</header>
|
||||
<group>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="picking_id" invisible="1"/>
|
||||
<field name="show_lots_m2o" invisible="1"/>
|
||||
<field name="show_lots_text" invisible="1"/>
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
<group>
|
||||
<group>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="hide_reservation_method" invisible="1"/>
|
||||
<field name="name"/>
|
||||
<field name="sequence_id" groups="base.group_no_one"/>
|
||||
@@ -244,6 +245,7 @@
|
||||
<field name="use_create_lots" invisible="1"/>
|
||||
<field name="show_set_qty_button" invisible="1"/>
|
||||
<field name="show_clear_qty_button" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
|
||||
<header>
|
||||
<button name="action_confirm" attrs="{'invisible': [('show_mark_as_todo', '=', False)]}" string="Mark as Todo" type="object" class="oe_highlight" groups="base.group_user" data-hotkey="x"/>
|
||||
@@ -317,6 +319,8 @@
|
||||
</div>
|
||||
<field name="partner_id" nolabel="1"/>
|
||||
<field name="picking_type_id" attrs="{'invisible': [('hide_picking_type', '=', True)], 'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="location_id" groups="!stock.group_stock_multi_locations" invisible="1"/>
|
||||
<field name="location_dest_id" groups="!stock.group_stock_multi_locations" invisible="1"/>
|
||||
<field name="location_id" options="{'no_create': True}" groups="stock.group_stock_multi_locations" attrs="{'invisible': [('picking_type_code', '=', 'incoming')]}"/>
|
||||
<field name="location_dest_id" options="{'no_create': True}" groups="stock.group_stock_multi_locations" attrs="{'invisible': [('picking_type_code', '=', 'outgoing')]}"/>
|
||||
<field name="backorder_id" attrs="{'invisible': [('backorder_id','=',False)]}"/>
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
<group>
|
||||
<group>
|
||||
<field name="tracking" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="product_id" readonly="0" options="{'no_create': True}"/>
|
||||
<field name="location_id" readonly="0" options="{'no_create': True}"/>
|
||||
<field name="lot_id" groups="stock.group_production_lot"
|
||||
@@ -93,6 +94,7 @@
|
||||
sample="1">
|
||||
<field name="id" invisible="1"/>
|
||||
<field name="tracking" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="product_id" attrs="{'readonly': [('id', '!=', False)]}"
|
||||
readonly="context.get('single_product', False)" force_save="1"
|
||||
options="{'no_create': True}"/>
|
||||
@@ -337,6 +339,7 @@
|
||||
<field name="sn_duplicated" invisible="1"/>
|
||||
<field name="tracking" invisible="1"/>
|
||||
<field name="inventory_quantity_set" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="location_id" domain="[('usage', 'in', ['internal', 'transit'])]" attrs="{'readonly': [('id', '!=', False)]}" invisible="context.get('hide_location', False)" options="{'no_create': True}"/>
|
||||
<field name="storage_category_id" groups="stock.group_stock_storage_categories" invisible="context.get('hide_location', False)" options="{'no_create': True}" optional="hidden"/>
|
||||
<field name="cyclic_inventory_frequency" invisible="context.get('hide_location', False)" options="{'no_create': True}" optional="hidden"/>
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
<group>
|
||||
<group>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="picking_type_code_domain" invisible="1"/>
|
||||
<field name="action"/>
|
||||
<field name="picking_type_id"/>
|
||||
@@ -123,6 +124,9 @@
|
||||
<xpath expr="//group[@name='apply_on']" position="attributes">
|
||||
<attribute name="groups">base.group_multi_company,base.group_no_one</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//form" position="inside">
|
||||
<field name="route_company_id" invisible="1"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
</div>
|
||||
</group>
|
||||
<group>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="lot_id" context="{'default_product_id': product_id, 'default_company_id': company_id}" attrs="{'invisible': ['|',('product_id', '=', False),('tracking', '=', 'none')], 'required': [('tracking', '!=', 'none')]}" groups="stock.group_production_lot"/>
|
||||
<field name="tracking" invisible="1"/>
|
||||
<field name="package_id" groups="stock.group_tracking_lot"/>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<field name="model">stock.storage.category</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Storage Category">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="%(action_storage_category_locations)d" string="Locations" type="action" class="oe_stat_button" icon="fa-arrows-v"/>
|
||||
@@ -86,6 +87,7 @@
|
||||
<field name="quantity"/>
|
||||
<field name="product_uom_id" options="{'no_create': True, 'no_open': True}"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="package_type_id" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
<group>
|
||||
<group>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="code" placeholder="e.g. CW"/>
|
||||
</group>
|
||||
<group>
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
<tree editable="bottom" create="0" delete="0">
|
||||
<field name="id" invisible="1"/>
|
||||
<field name="tracking" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="product_id" attrs="{'readonly': [('id', '!=', False)]}" invisible="context.get('single_product', False)" readonly="context.get('single_product', False)" force_save="1" options="{'no_create': True}"/>
|
||||
<field name="location_id" attrs="{'readonly': [('id', '!=', False)]}" invisible="context.get('hide_location', False)" options="{'no_create': True}"/>
|
||||
<field name="lot_id" groups="stock.group_production_lot" attrs="{
|
||||
|
||||
@@ -111,14 +111,19 @@ class ReturnPicking(models.TransientModel):
|
||||
return vals
|
||||
|
||||
def _prepare_picking_default_values(self):
|
||||
return {
|
||||
vals = {
|
||||
'move_ids': [],
|
||||
'picking_type_id': self.picking_id.picking_type_id.return_picking_type_id.id or self.picking_id.picking_type_id.id,
|
||||
'state': 'draft',
|
||||
'origin': _("Return of %s") % self.picking_id.name,
|
||||
'location_id': self.picking_id.location_dest_id.id,
|
||||
'location_dest_id': self.location_id.id
|
||||
}
|
||||
# TestPickShip.test_mto_moves_return, TestPickShip.test_mto_moves_return_extra,
|
||||
# TestPickShip.test_pick_pack_ship_return, TestPickShip.test_pick_ship_return, TestPickShip.test_return_lot
|
||||
if self.picking_id.location_dest_id:
|
||||
vals['location_id'] = self.picking_id.location_dest_id.id
|
||||
if self.location_id:
|
||||
vals['location_dest_id'] = self.location_id.id
|
||||
return vals
|
||||
|
||||
def _create_returns(self):
|
||||
# TODO sle: the unreserve of the next moves could be less brutal
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<group name="account_property" position="inside">
|
||||
<group name="account_stock_property" string="Account Stock Properties" groups="account.group_account_readonly" attrs="{'invisible':[('property_valuation', '=', 'manual_periodic')]}">
|
||||
<field name="property_valuation" invisible="1"/>
|
||||
<field name="property_stock_valuation_account_id" options="{'no_create': True}" attrs="{'required':[('property_valuation', '=', 'real_time')]}"/>
|
||||
<field name="property_stock_journal" attrs="{'required':[('property_valuation', '=', 'real_time')]}" />
|
||||
<field name="property_stock_account_input_categ_id" attrs="{'required':[ ('property_valuation', '=', 'real_time')]}" />
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<field name="model">stock.landed.cost</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Landed Costs">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="stock_valuation_layer_ids" invisible="1"/>
|
||||
<header>
|
||||
<button name="button_validate" string="Validate" states="draft" class="oe_highlight" type="object"/>
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
<tree editable="top" decoration-muted="state == 'cancel'" string="Move Lines" default_order="location_id">
|
||||
<field name="tracking" invisible="1"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="product_id" context="{'default_detailed_type': 'product'}" required="1" attrs="{'readonly': [('id', '!=', False)]}"/>
|
||||
<field name="picking_id" required="1" attrs="{'readonly': [('id', '!=', False)]}"
|
||||
options="{'no_create_edit': True}" domain="[('id', 'in', parent.picking_ids)]"/>
|
||||
@@ -82,6 +83,7 @@
|
||||
<field name="model">stock.picking.batch</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Stock Batch Transfer">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="show_check_availability" invisible="1"/>
|
||||
<field name="show_validate" invisible="1"/>
|
||||
<field name="show_allocation" invisible="1"/>
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
<field string="Attempts" name="attempts_count" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
<field name="test_entry" invisible="1"/>
|
||||
<widget name="web_ribbon" title="Test Entry" bg_color="bg-info"
|
||||
attrs="{'invisible': [('test_entry', '!=', True)]}"/>
|
||||
<widget name="web_ribbon" title="Failed" bg_color="bg-danger"
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
<field name="seniority_id" attrs="{'invisible': [('contact_filter_type','!=', 'seniority')]}" options="{'no_create_edit': True, 'no_quick_create': True}"/>
|
||||
</group>
|
||||
</group>
|
||||
<field name="lead_type" invisible="1"/>
|
||||
<separator attrs="{'invisible': [('lead_type', '!=', 'lead')]}" string="Lead Data" />
|
||||
<separator attrs="{'invisible': [('lead_type', '!=', 'opportunity')]}" string="Opportunity Data" />
|
||||
<group>
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
<field name="inherit_id" ref="event.view_event_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="company_id" position="after">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="website_id" groups="website.group_multi_website" domain="['|', ('company_id', '=', company_id), ('company_id', '=', False)]" optional="show"/>
|
||||
</field>
|
||||
</field>
|
||||
|
||||
@@ -283,6 +283,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='pricelist_availability']" position="after">
|
||||
<group name="pricelist_website" string="Website">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="website_id" options="{'no_create': True}"/>
|
||||
<field name="selectable"/>
|
||||
<field name="code"/>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<field name="model">coupon.share</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Share Loyalty Card" edit="1" create="0">
|
||||
<field name="website_id" invisible="1"/>
|
||||
<field name="program_website_id" invisible="1"/>
|
||||
<group attrs="{'invisible': [('website_id', '=', False)]}">
|
||||
<div colspan="2">
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
<div class="row mt16"
|
||||
id="website_warehouse_setting"
|
||||
groups="stock.group_stock_multi_warehouses">
|
||||
<field name="website_company_id" invisible="1"/>
|
||||
<label for="website_warehouse_id" string="Warehouse" class="col-lg-3 o_light_label" />
|
||||
<field name="website_warehouse_id"/>
|
||||
</div>
|
||||
|
||||
@@ -974,16 +974,11 @@ actual arch.
|
||||
|
||||
def _apply_groups(self, node, name_manager, node_info):
|
||||
""" Apply group restrictions: elements with a 'groups' attribute should
|
||||
be made invisible to people who are not members.
|
||||
be removed from the view to people who are not members.
|
||||
"""
|
||||
if node.get('groups'):
|
||||
can_see = self.user_has_groups(groups=node.get('groups'))
|
||||
if not can_see:
|
||||
node.set('invisible', '1')
|
||||
node_info['modifiers']['invisible'] = True
|
||||
if 'attrs' in node.attrib:
|
||||
del node.attrib['attrs'] # avoid making field visible later
|
||||
del node.attrib['groups']
|
||||
if not self.user_has_groups(groups=node.get('groups')):
|
||||
node.getparent().remove(node)
|
||||
|
||||
def _get_view_refs(self, node):
|
||||
""" Extract the `[view_type]_view_ref` keys and values from the node context attribute,
|
||||
@@ -1145,10 +1140,10 @@ actual arch.
|
||||
def _postprocess_tag_calendar(self, node, name_manager, node_info):
|
||||
for additional_field in ('date_start', 'date_delay', 'date_stop', 'color', 'all_day'):
|
||||
if node.get(additional_field):
|
||||
name_manager.has_field(node.get(additional_field).split('.', 1)[0])
|
||||
name_manager.has_field(node, node.get(additional_field).split('.', 1)[0])
|
||||
for f in node:
|
||||
if f.tag == 'filter':
|
||||
name_manager.has_field(f.get('name'))
|
||||
name_manager.has_field(node, f.get('name'))
|
||||
|
||||
def _postprocess_tag_field(self, node, name_manager, node_info):
|
||||
if node.get('name'):
|
||||
@@ -1203,7 +1198,7 @@ actual arch.
|
||||
node.set('can_create', 'true' if can_create else 'false')
|
||||
node.set('can_write', 'true' if can_write else 'false')
|
||||
|
||||
name_manager.has_field(node.get('name'), attrs)
|
||||
name_manager.has_field(node, node.get('name'), attrs)
|
||||
|
||||
field_info = name_manager.field_info.get(node.get('name'))
|
||||
if field_info:
|
||||
@@ -1225,7 +1220,7 @@ actual arch.
|
||||
self.with_context(
|
||||
base_model_name=name_manager.model._name,
|
||||
)._postprocess_view(node, field.comodel_name, editable=False, parent_name_manager=name_manager)
|
||||
name_manager.has_field(name)
|
||||
name_manager.has_field(node, name)
|
||||
|
||||
def _postprocess_tag_label(self, node, name_manager, node_info):
|
||||
if node.get('for'):
|
||||
@@ -1355,10 +1350,10 @@ actual arch.
|
||||
def _validate_tag_calendar(self, node, name_manager, node_info):
|
||||
for additional_field in ('date_start', 'date_delay', 'date_stop', 'color', 'all_day'):
|
||||
if node.get(additional_field):
|
||||
name_manager.has_field(node.get(additional_field).split('.', 1)[0])
|
||||
name_manager.has_field(node, node.get(additional_field).split('.', 1)[0])
|
||||
for f in node:
|
||||
if f.tag == 'filter':
|
||||
name_manager.has_field(f.get('name'))
|
||||
name_manager.has_field(node, f.get('name'))
|
||||
|
||||
def _validate_tag_search(self, node, name_manager, node_info):
|
||||
if node_info['validate'] and not node.iterdescendants(tag="field"):
|
||||
@@ -1397,7 +1392,7 @@ actual arch.
|
||||
fnames, vnames = self._get_domain_identifiers(node, domain, desc)
|
||||
self._check_field_paths(node, fnames, field.comodel_name, f"{desc} ({domain})")
|
||||
if vnames:
|
||||
name_manager.must_have_fields(vnames, f"{desc} ({domain})")
|
||||
name_manager.must_have_fields(node, vnames, f"{desc} ({domain})")
|
||||
|
||||
elif validate and node.get('domain'):
|
||||
msg = _(
|
||||
@@ -1413,8 +1408,9 @@ actual arch.
|
||||
sub_manager = self._validate_view(
|
||||
child, field.comodel_name, editable=node_info['editable'], full=validate,
|
||||
)
|
||||
for fname, use in sub_manager.mandatory_parent_fields.items():
|
||||
name_manager.must_have_field(fname, use)
|
||||
for fname, groups_uses in sub_manager.mandatory_parent_fields.items():
|
||||
for groups, use in groups_uses.items():
|
||||
name_manager.must_have_field(node, fname, use, groups=groups)
|
||||
|
||||
elif validate and name not in name_manager.field_info:
|
||||
msg = _(
|
||||
@@ -1423,7 +1419,7 @@ actual arch.
|
||||
)
|
||||
self._raise_view_error(msg, node)
|
||||
|
||||
name_manager.has_field(name, {'id': node.get('id'), 'select': node.get('select')})
|
||||
name_manager.has_field(node, name, {'id': node.get('id'), 'select': node.get('select')})
|
||||
|
||||
if validate:
|
||||
for attribute in ('invisible', 'readonly', 'required'):
|
||||
@@ -1447,7 +1443,7 @@ actual arch.
|
||||
fnames, vnames = self._get_domain_identifiers(node, domain, desc)
|
||||
self._check_field_paths(node, fnames, name_manager.model._name, f"{desc} ({domain})")
|
||||
if vnames:
|
||||
name_manager.must_have_fields(vnames, f"{desc} ({domain})")
|
||||
name_manager.must_have_fields(node, vnames, f"{desc} ({domain})")
|
||||
|
||||
def _validate_tag_button(self, node, name_manager, node_info):
|
||||
if not node_info['validate']:
|
||||
@@ -1535,7 +1531,7 @@ actual arch.
|
||||
fnames, vnames = self._get_domain_identifiers(node, domain, desc)
|
||||
self._check_field_paths(node, fnames, field.comodel_name, f"{desc} ({domain})")
|
||||
if vnames:
|
||||
name_manager.must_have_fields(vnames, f"{desc} ({domain})")
|
||||
name_manager.must_have_fields(node, vnames, f"{desc} ({domain})")
|
||||
|
||||
# move all children nodes into a new node <groupby>
|
||||
groupby_node = E.groupby(*node)
|
||||
@@ -1543,9 +1539,10 @@ actual arch.
|
||||
sub_manager = self._validate_view(
|
||||
groupby_node, field.comodel_name, editable=False, full=node_info['validate'],
|
||||
)
|
||||
name_manager.has_field(name)
|
||||
for fname, use in sub_manager.mandatory_parent_fields.items():
|
||||
name_manager.must_have_field(fname, use)
|
||||
name_manager.has_field(node, name)
|
||||
for fname, groups_uses in sub_manager.mandatory_parent_fields.items():
|
||||
for groups, use in groups_uses.items():
|
||||
name_manager.must_have_field(node, fname, use, groups=groups)
|
||||
|
||||
elif node_info['validate']:
|
||||
msg = _(
|
||||
@@ -1639,11 +1636,11 @@ actual arch.
|
||||
# domains in attrs are used for readonly, invisible, ...
|
||||
# and thus are only executed client side
|
||||
fnames, vnames = self._get_domain_identifiers(node, val_ast, attr, expr)
|
||||
name_manager.must_have_fields(fnames | vnames, f"attrs ({expr})")
|
||||
name_manager.must_have_fields(node, fnames | vnames, f"attrs ({expr})")
|
||||
else:
|
||||
vnames = get_variable_names(val_ast)
|
||||
if vnames:
|
||||
name_manager.must_have_fields(vnames, f"attrs ({expr})")
|
||||
name_manager.must_have_fields(node, vnames, f"attrs ({expr})")
|
||||
|
||||
elif attr == 'context':
|
||||
for key, val_ast in get_dict_asts(expr).items():
|
||||
@@ -1665,7 +1662,7 @@ actual arch.
|
||||
else:
|
||||
vnames = get_variable_names(val_ast)
|
||||
if vnames:
|
||||
name_manager.must_have_fields(vnames, f"context ({expr})")
|
||||
name_manager.must_have_fields(node, vnames, f"context ({expr})")
|
||||
|
||||
elif attr == 'groups':
|
||||
for group in expr.replace('!', '').split(','):
|
||||
@@ -1688,7 +1685,7 @@ actual arch.
|
||||
elif attr.startswith('decoration-'):
|
||||
vnames = get_variable_names(expr)
|
||||
if vnames:
|
||||
name_manager.must_have_fields(vnames, f"{attr}={expr}")
|
||||
name_manager.must_have_fields(node, vnames, f"{attr}={expr}")
|
||||
|
||||
elif attr == 'data-bs-toggle' and expr == 'tab':
|
||||
if node.get('role') != 'tab':
|
||||
@@ -2194,11 +2191,11 @@ class NameManager:
|
||||
|
||||
def __init__(self, model, parent=None):
|
||||
self.model = model
|
||||
self.available_fields = collections.defaultdict(dict) # {field_name: field_info}
|
||||
self.available_fields = collections.defaultdict(dict) # {field_name: {'groups': groups, 'info': field_info}}
|
||||
self.available_actions = set()
|
||||
self.available_names = set()
|
||||
self.mandatory_fields = dict() # {field_name: use}
|
||||
self.mandatory_parent_fields = dict() # {field_name: use}
|
||||
self.mandatory_fields = collections.defaultdict(dict) # {field_name: {'groups': 'use}}
|
||||
self.mandatory_parent_fields = collections.defaultdict(dict) # {field_name: {'groups': use}}
|
||||
self.mandatory_names = dict() # {name: use}
|
||||
self.parent = parent
|
||||
self.children = []
|
||||
@@ -2215,26 +2212,36 @@ class NameManager:
|
||||
info['states'] = {}
|
||||
return field_info
|
||||
|
||||
def has_field(self, name, info=frozendict()):
|
||||
self.available_fields[name].update(info)
|
||||
def has_field(self, node, name, info=frozendict()):
|
||||
groups = self._get_node_groups(node)
|
||||
self.available_fields[name].setdefault('info', {}).update(info)
|
||||
self.available_fields[name].setdefault('groups', []).append(groups)
|
||||
self.available_names.add(info.get('id') or name)
|
||||
|
||||
def has_action(self, name):
|
||||
self.available_actions.add(name)
|
||||
|
||||
def must_have_field(self, name, use):
|
||||
if name.startswith('parent.'):
|
||||
self.mandatory_parent_fields[name[7:]] = use
|
||||
def must_have_field(self, node, name, use, groups=None):
|
||||
node_groups = self._get_node_groups(node)
|
||||
if groups:
|
||||
groups = groups + node_groups
|
||||
else:
|
||||
self.mandatory_fields[name] = use
|
||||
groups = node_groups
|
||||
if name.startswith('parent.'):
|
||||
self.mandatory_parent_fields[name[7:]][groups] = use
|
||||
else:
|
||||
self.mandatory_fields[name][groups] = use
|
||||
|
||||
def must_have_fields(self, names, use):
|
||||
def must_have_fields(self, node, names, use, groups=None):
|
||||
for name in names:
|
||||
self.must_have_field(name, use)
|
||||
self.must_have_field(node, name, use, groups=groups)
|
||||
|
||||
def must_have_name(self, name, use):
|
||||
self.mandatory_names[name] = use
|
||||
|
||||
def _get_node_groups(self, node):
|
||||
return tuple(tuple(n.get('groups').split(',')) for n in node.xpath('ancestor-or-self::*[@groups]'))
|
||||
|
||||
def check(self, view):
|
||||
# context for translations below
|
||||
context = view.env.context # pylint: disable=unused-variable
|
||||
@@ -2252,7 +2259,8 @@ class NameManager:
|
||||
message = _("Field `%(name)s` does not exist", name=name)
|
||||
view._raise_view_error(message)
|
||||
|
||||
for name, use in self.mandatory_fields.items():
|
||||
for name, groups_uses in self.mandatory_fields.items():
|
||||
use = next(iter(groups_uses.values()))
|
||||
if name == 'id': # always available
|
||||
continue
|
||||
if "." in name:
|
||||
@@ -2261,7 +2269,7 @@ class NameManager:
|
||||
definition=name, use=use,
|
||||
)
|
||||
view._raise_view_error(msg)
|
||||
info = self.available_fields.get(name)
|
||||
info = self.available_fields[name].get('info')
|
||||
if info is None:
|
||||
msg = _(
|
||||
"Field %(name)r used in %(use)s must be present in view but is missing.",
|
||||
@@ -2275,6 +2283,104 @@ class NameManager:
|
||||
)
|
||||
view._raise_view_error(msg)
|
||||
|
||||
def combinate(groups):
|
||||
# [['A'], ['B', 'C'], ['D', 'E']]
|
||||
# returns
|
||||
# [['A', 'B', 'D'], ['A', 'C', 'D'], ['A', 'B', 'E'], ['A', 'C', 'E']]
|
||||
|
||||
# [['!A', '!B'], ['C', 'D']]
|
||||
# returns
|
||||
# [['!A', '!B', 'C'], ['!A', '!B', 'D']]
|
||||
|
||||
# [['A', 'B'], ['!C', '!D']]
|
||||
# returns
|
||||
# [['A', '!C', '!D'], ['B', '!C', '!D']]
|
||||
|
||||
# [['!A', '!B', 'C', 'D'], ['E', 'F']]
|
||||
# returns
|
||||
# [['!A', '!B', 'C', 'E'], ['!A', '!B', 'D', 'E'], ['!A', '!B', 'C', 'F'], ['!A', '!B', 'D', 'F']]
|
||||
if not groups:
|
||||
return []
|
||||
positive = [(group,) for group in groups[0] if not group or not group.startswith('!')]
|
||||
negative = tuple(group for group in groups[0] if group and group.startswith('!'))
|
||||
combinations = [negative + p for p in positive] if positive else [negative]
|
||||
if len(groups) > 1:
|
||||
combinations = [group + tuple(c) for c in combinate(groups[1:]) for group in combinations]
|
||||
return [set(combination) for combination in set(tuple(combination) for combination in combinations)]
|
||||
|
||||
for mandatory_for_groups, use in groups_uses.items():
|
||||
mandatory_combinations = combinate(mandatory_for_groups or [(None,)])
|
||||
available_combinations = [
|
||||
combination
|
||||
for available_for_groups in self.available_fields[name]['groups']
|
||||
for combination in combinate(available_for_groups or [(None,)])
|
||||
]
|
||||
if (
|
||||
# If (None,) is in available_combinations,
|
||||
# it means the field is in the view without any group restriction,
|
||||
# and is therefore available for anyone / any group
|
||||
{None} not in available_combinations
|
||||
# If there are two mutually exclusive combinations,
|
||||
# it means the field is available for anyone / any group
|
||||
and not any(
|
||||
{group[1:] if group.startswith('!') else '!' + group for group in combination}
|
||||
in available_combinations
|
||||
for combination in available_combinations
|
||||
)
|
||||
# For all mandatory combinations, find an available combination
|
||||
# which is included in the mandatory combination
|
||||
# e.g.
|
||||
# mandatory combination: A B C
|
||||
# available combination: A B
|
||||
# The above is valid, the field will be available for users having both A and B groups
|
||||
# and the field is mandatory only for users having A B and C groups.
|
||||
and not all(
|
||||
any(
|
||||
available_combination.issubset(mandatory_combination)
|
||||
for available_combination in available_combinations
|
||||
) for mandatory_combination in mandatory_combinations
|
||||
)
|
||||
# Same than above but take into account implied groups (e.g. group_system includes group_erp_manager and group_user)
|
||||
# for positive groups
|
||||
and not all(
|
||||
any(
|
||||
available_combination.issubset(combination)
|
||||
for available_combination in available_combinations
|
||||
for combination in
|
||||
(
|
||||
mandatory_combination - {group} | {trans_group}
|
||||
for group in mandatory_combination if group and not group.startswith('!')
|
||||
for trans_group in view.env.ref(group).trans_implied_ids.get_external_id().values()
|
||||
)
|
||||
)
|
||||
for mandatory_combination in mandatory_combinations
|
||||
)
|
||||
# Same than above but take into account implied groups (e.g. group_system includes group_erp_manager and group_user)
|
||||
# for negative groups
|
||||
and not all(
|
||||
any(
|
||||
combination.issubset(mandatory_combination)
|
||||
for available_combination in available_combinations
|
||||
for combination in
|
||||
(
|
||||
available_combination - {group} | {'!' + trans_group}
|
||||
for group in available_combination if group and group.startswith('!')
|
||||
for trans_group in view.env.ref(group[1:]).trans_implied_ids.get_external_id().values()
|
||||
)
|
||||
) for mandatory_combination in mandatory_combinations
|
||||
)
|
||||
):
|
||||
msg = _(
|
||||
"Field %(name)r used in %(use)s is restricted to the group(s) %(groups)s.",
|
||||
name=name, use=use, groups=','.join(
|
||||
group
|
||||
for availability in self.available_fields[name]['groups']
|
||||
for combination in availability
|
||||
for group in combination
|
||||
)
|
||||
)
|
||||
view._raise_view_error(msg)
|
||||
|
||||
def update_available_fields(self):
|
||||
for name, info in self.available_fields.items():
|
||||
info.update(self.field_info.get(name, ()))
|
||||
|
||||
@@ -1308,7 +1308,7 @@ class GroupsView(models.Model):
|
||||
else:
|
||||
group_no_one = view.env.ref('base.group_no_one')
|
||||
group_employee = view.env.ref('base.group_user')
|
||||
xml1, xml2, xml3 = [], [], []
|
||||
xml0, xml1, xml2, xml3 = [], [], [], []
|
||||
xml_by_category = {}
|
||||
xml1.append(E.separator(string='User Type', colspan="2", groups='base.group_no_one'))
|
||||
|
||||
@@ -1327,6 +1327,11 @@ class GroupsView(models.Model):
|
||||
if app.xml_id == 'base.module_category_user_type':
|
||||
# application name with a selection field
|
||||
field_name = name_selection_groups(gs.ids)
|
||||
# test_reified_groups, put the user category type in invisible
|
||||
# as it's used in domain of attrs of other fields,
|
||||
# and the normal user category type field node is wrapped in a `groups="base.no_one"`,
|
||||
# and is therefore removed when not in debug mode.
|
||||
xml0.append(E.field(name=field_name, invisible="1", on_change="1"))
|
||||
user_type_field_name = field_name
|
||||
user_type_readonly = str({'readonly': [(user_type_field_name, '!=', group_employee.id)]})
|
||||
attrs['widget'] = 'radio'
|
||||
@@ -1369,6 +1374,7 @@ class GroupsView(models.Model):
|
||||
xml2.append(E.group(*(xml_by_category[xml_cat]), col="2", string=master_category_name))
|
||||
|
||||
xml = E.field(
|
||||
*(xml0),
|
||||
E.group(*(xml1), col="2", groups="base.group_no_one"),
|
||||
E.group(*(xml2), col="2", attrs=str(user_type_attrs)),
|
||||
E.group(*(xml3), col="4", attrs=str(user_type_attrs), groups="base.group_no_one"), name="groups_id", position="replace")
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user