10.0 imp bi sql editor (#1)
* [IMP] is_materialized field non readonly on sql_valid state ; [FIX] block possibility to set indexes on non materialized view * [FIX] set domain_force, group_ids readonly if state > sql_valid * [IMP] better display of the field group_ids * [IMP] possibility to reorder menu items from sql views * [IMP] Do not warn user when setting sql view to draft if state is sql_valid * [REF] * [FIX] Set Date of the first execution in the action namepull/670/head
parent
4c4f50e7ab
commit
e92a43103b
|
@ -31,6 +31,7 @@ class BaseModel(models.AbstractModel):
|
||||||
|
|
||||||
class BiSQLView(models.Model):
|
class BiSQLView(models.Model):
|
||||||
_name = 'bi.sql.view'
|
_name = 'bi.sql.view'
|
||||||
|
_order = 'sequence'
|
||||||
_inherit = ['sql.request.mixin']
|
_inherit = ['sql.request.mixin']
|
||||||
|
|
||||||
_sql_prefix = 'x_bi_sql_view_'
|
_sql_prefix = 'x_bi_sql_view_'
|
||||||
|
@ -64,7 +65,10 @@ class BiSQLView(models.Model):
|
||||||
|
|
||||||
is_materialized = fields.Boolean(
|
is_materialized = fields.Boolean(
|
||||||
string='Is Materialized View', default=True, readonly=True,
|
string='Is Materialized View', default=True, readonly=True,
|
||||||
states={'draft': [('readonly', False)]})
|
states={
|
||||||
|
'draft': [('readonly', False)],
|
||||||
|
'sql_valid': [('readonly', False)],
|
||||||
|
})
|
||||||
|
|
||||||
materialized_text = fields.Char(
|
materialized_text = fields.Char(
|
||||||
compute='_compute_materialized_text', store=True)
|
compute='_compute_materialized_text', store=True)
|
||||||
|
@ -94,13 +98,17 @@ class BiSQLView(models.Model):
|
||||||
"FROM my_table")
|
"FROM my_table")
|
||||||
|
|
||||||
domain_force = fields.Text(
|
domain_force = fields.Text(
|
||||||
string='Extra Rule Definition', default="[]", help="Define here"
|
string='Extra Rule Definition', default="[]", readonly=True,
|
||||||
" access restriction to data.\n"
|
help="Define here access restriction to data.\n"
|
||||||
" Take care to use field name prefixed by 'x_'."
|
" Take care to use field name prefixed by 'x_'."
|
||||||
" A global 'ir.rule' will be created."
|
" A global 'ir.rule' will be created."
|
||||||
" A typical Multi Company rule is for exemple \n"
|
" A typical Multi Company rule is for exemple \n"
|
||||||
" ['|', ('x_company_id','child_of', [user.company_id.id]),"
|
" ['|', ('x_company_id','child_of', [user.company_id.id]),"
|
||||||
"('x_company_id','=',False)].")
|
"('x_company_id','=',False)].",
|
||||||
|
states={
|
||||||
|
'draft': [('readonly', False)],
|
||||||
|
'sql_valid': [('readonly', False)],
|
||||||
|
})
|
||||||
|
|
||||||
has_group_changed = fields.Boolean(copy=False)
|
has_group_changed = fields.Boolean(copy=False)
|
||||||
|
|
||||||
|
@ -137,6 +145,23 @@ class BiSQLView(models.Model):
|
||||||
rule_id = fields.Many2one(
|
rule_id = fields.Many2one(
|
||||||
string='Odoo Rule', comodel_name='ir.rule', readonly=True)
|
string='Odoo Rule', comodel_name='ir.rule', readonly=True)
|
||||||
|
|
||||||
|
group_ids = fields.Many2many(
|
||||||
|
comodel_name='res.groups', readonly=True, states={
|
||||||
|
'draft': [('readonly', False)],
|
||||||
|
'sql_valid': [('readonly', False)],
|
||||||
|
})
|
||||||
|
|
||||||
|
sequence = fields.Integer(string='sequence')
|
||||||
|
|
||||||
|
# Constrains Section
|
||||||
|
@api.constrains('is_materialized')
|
||||||
|
@api.multi
|
||||||
|
def _check_index_materialized(self):
|
||||||
|
for rec in self.filtered(lambda x: not x.is_materialized):
|
||||||
|
if rec.bi_sql_view_field_ids.filtered(lambda x: x.is_index):
|
||||||
|
raise UserError(_(
|
||||||
|
'You can not create indexes on non materialized views'))
|
||||||
|
|
||||||
@api.constrains('view_order')
|
@api.constrains('view_order')
|
||||||
@api.multi
|
@api.multi
|
||||||
def _check_view_order(self):
|
def _check_view_order(self):
|
||||||
|
@ -175,6 +200,14 @@ class BiSQLView(models.Model):
|
||||||
self.has_group_changed = True
|
self.has_group_changed = True
|
||||||
|
|
||||||
# Overload Section
|
# Overload Section
|
||||||
|
@api.multi
|
||||||
|
def write(self, vals):
|
||||||
|
res = super(BiSQLView, self).write(vals)
|
||||||
|
if vals.get('sequence', False):
|
||||||
|
for rec in self.filtered(lambda x: x.menu_id):
|
||||||
|
rec.menu_id.sequence = rec.sequence
|
||||||
|
return res
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def unlink(self):
|
def unlink(self):
|
||||||
if any(view.state not in ('draft', 'sql_valid') for view in self):
|
if any(view.state not in ('draft', 'sql_valid') for view in self):
|
||||||
|
@ -399,7 +432,7 @@ class BiSQLView(models.Model):
|
||||||
else:
|
else:
|
||||||
view_id = self.graph_view_id.id
|
view_id = self.graph_view_id.id
|
||||||
return {
|
return {
|
||||||
'name': self.name,
|
'name': self._prepare_action_name(),
|
||||||
'res_model': self.model_id.model,
|
'res_model': self.model_id.model,
|
||||||
'type': 'ir.actions.act_window',
|
'type': 'ir.actions.act_window',
|
||||||
'view_mode': view_mode,
|
'view_mode': view_mode,
|
||||||
|
@ -407,6 +440,15 @@ class BiSQLView(models.Model):
|
||||||
'search_view_id': self.search_view_id.id,
|
'search_view_id': self.search_view_id.id,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def _prepare_action_name(self):
|
||||||
|
self.ensure_one()
|
||||||
|
if not self.is_materialized:
|
||||||
|
return self.name
|
||||||
|
return "%s (%s)" % (
|
||||||
|
self.name,
|
||||||
|
datetime.utcnow().strftime(_("%m/%d/%Y %H:%M:%S UTC")))
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def _prepare_menu(self):
|
def _prepare_menu(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
|
@ -414,6 +456,7 @@ class BiSQLView(models.Model):
|
||||||
'name': self.name,
|
'name': self.name,
|
||||||
'parent_id': self.env.ref('bi_sql_editor.menu_bi_sql_editor').id,
|
'parent_id': self.env.ref('bi_sql_editor.menu_bi_sql_editor').id,
|
||||||
'action': 'ir.actions.act_window,%s' % (self.action_id.id),
|
'action': 'ir.actions.act_window,%s' % (self.action_id.id),
|
||||||
|
'sequence': self.sequence,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Custom Section
|
# Custom Section
|
||||||
|
@ -570,8 +613,7 @@ class BiSQLView(models.Model):
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def _refresh_materialized_view(self):
|
def _refresh_materialized_view(self):
|
||||||
for sql_view in self:
|
for sql_view in self.filtered(lambda x: x.is_materialized):
|
||||||
if sql_view.is_materialized:
|
|
||||||
req = "REFRESH %s VIEW %s" % (
|
req = "REFRESH %s VIEW %s" % (
|
||||||
sql_view.materialized_text, sql_view.view_name)
|
sql_view.materialized_text, sql_view.view_name)
|
||||||
self._log_execute(req)
|
self._log_execute(req)
|
||||||
|
@ -579,9 +621,7 @@ class BiSQLView(models.Model):
|
||||||
if sql_view.action_id:
|
if sql_view.action_id:
|
||||||
# Alter name of the action, to display last refresh
|
# Alter name of the action, to display last refresh
|
||||||
# datetime of the materialized view
|
# datetime of the materialized view
|
||||||
sql_view.action_id.name = "%s (%s)" % (
|
sql_view.action_id.name = sql_view._prepare_action_name()
|
||||||
self.name,
|
|
||||||
datetime.utcnow().strftime(_("%m/%d/%Y %H:%M:%S UTC")))
|
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def _refresh_size(self):
|
def _refresh_size(self):
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from odoo import api, fields, models
|
from odoo import _, api, fields, models
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
|
||||||
|
|
||||||
class BiSQLViewField(models.Model):
|
class BiSQLViewField(models.Model):
|
||||||
|
@ -100,6 +101,15 @@ class BiSQLViewField(models.Model):
|
||||||
help="For 'Many2one' Odoo field.\n"
|
help="For 'Many2one' Odoo field.\n"
|
||||||
" Comodel of the field.")
|
" Comodel of the field.")
|
||||||
|
|
||||||
|
# Constrains Section
|
||||||
|
@api.constrains('is_index')
|
||||||
|
@api.multi
|
||||||
|
def _check_index_materialized(self):
|
||||||
|
for rec in self.filtered(lambda x: x.is_index):
|
||||||
|
if not rec.bi_sql_view_id.is_materialized:
|
||||||
|
raise UserError(_(
|
||||||
|
'You can not create indexes on non materialized views'))
|
||||||
|
|
||||||
# Compute Section
|
# Compute Section
|
||||||
@api.multi
|
@api.multi
|
||||||
def _compute_index_name(self):
|
def _compute_index_name(self):
|
||||||
|
|
|
@ -11,6 +11,7 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
<field name="model">bi.sql.view</field>
|
<field name="model">bi.sql.view</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree decoration-info="state=='draft'" decoration-warning="state in ('sql_valid', 'model_valid')">
|
<tree decoration-info="state=='draft'" decoration-warning="state in ('sql_valid', 'model_valid')">
|
||||||
|
<field name="sequence" widget="handle"/>
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
<field name="technical_name"/>
|
<field name="technical_name"/>
|
||||||
<field name="size"/>
|
<field name="size"/>
|
||||||
|
@ -26,7 +27,9 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
<header>
|
<header>
|
||||||
<button name="button_validate_sql_expression" type="object" states="draft"
|
<button name="button_validate_sql_expression" type="object" states="draft"
|
||||||
string="Validate SQL Expression" class="oe_highlight"/>
|
string="Validate SQL Expression" class="oe_highlight"/>
|
||||||
<button name="button_set_draft" type="object" states="sql_valid,model_valid,ui_valid"
|
<button name="button_set_draft" type="object" states="sql_valid"
|
||||||
|
string="Set to Draft" groups="sql_request_abstract.group_sql_request_manager"/>
|
||||||
|
<button name="button_set_draft" type="object" states="model_valid,ui_valid"
|
||||||
string="Set to Draft" groups="sql_request_abstract.group_sql_request_manager"
|
string="Set to Draft" groups="sql_request_abstract.group_sql_request_manager"
|
||||||
confirm="Are you sure you want to set to draft this SQL View. It will delete the materialized view, and all the previous mapping realized with the columns"/>
|
confirm="Are you sure you want to set to draft this SQL View. It will delete the materialized view, and all the previous mapping realized with the columns"/>
|
||||||
<button name="button_preview_sql_expression" type="object" states="draft" string="Preview SQL Expression" />
|
<button name="button_preview_sql_expression" type="object" states="draft" string="Preview SQL Expression" />
|
||||||
|
@ -98,12 +101,10 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
<group string="Rule Definition">
|
<group string="Rule Definition">
|
||||||
<field name="domain_force" nolabel="1" colspan="4"/>
|
<field name="domain_force" nolabel="1" colspan="4"/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
|
||||||
<group string="Allowed Groups">
|
<group string="Allowed Groups">
|
||||||
<field name="group_ids" nolabel="1"/>
|
<field name="group_ids" nolabel="1" colspan="4"/>
|
||||||
<field name="has_group_changed" invisible="1"/>
|
<field name="has_group_changed" invisible="1"/>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
|
||||||
</page>
|
</page>
|
||||||
<page string="Extras Information">
|
<page string="Extras Information">
|
||||||
<group>
|
<group>
|
||||||
|
|
Loading…
Reference in New Issue