update modules
|
|
@ -10,14 +10,12 @@
|
||||||
#################################################################################
|
#################################################################################
|
||||||
{
|
{
|
||||||
'name': 'Advanced Web Domain Widget',
|
'name': 'Advanced Web Domain Widget',
|
||||||
'version': '14.0.2.0.0',
|
'version': '14.0.3.0.0',
|
||||||
'summary': 'Set all relational fields domain by selecting its records unsing `in, not in` operator.',
|
'summary': 'Set all relational fields domain by selecting its records unsing `in, not in` operator.',
|
||||||
'sequence': 1,
|
'sequence': 1,
|
||||||
'author': 'Terabits Technolab',
|
'author': 'Terabits Technolab',
|
||||||
'category': 'Odex25-base',
|
|
||||||
|
|
||||||
'license': 'OPL-1',
|
'license': 'OPL-1',
|
||||||
'website': 'https://www.terabits.xyz',
|
'website': 'https://www.terabits.xyz/apps/14.0/advanced_web_domain_widget',
|
||||||
'description':"""
|
'description':"""
|
||||||
|
|
||||||
""",
|
""",
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
from . import domain_prepare
|
from . import domain_prepare
|
||||||
|
from . import models
|
||||||
|
|
@ -5,11 +5,9 @@ class BaseModel(models.AbstractModel):
|
||||||
_inherit = 'base'
|
_inherit = 'base'
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def search_read(self, domain=None, fields=None, offset=0, limit=None, order=None, **read_kwargs):
|
def get_widget_name(self, domain=None, fields=None, offset=0, limit=None, order=None, **read_kwargs):
|
||||||
res = super().search_read(domain, fields, offset, limit, order, **read_kwargs)
|
return self.sudo().search_read(domain, ['id', 'display_name'], offset, limit, order)
|
||||||
if self._context.get('web_domain_widget') and hasattr(self, 'company_id'):
|
|
||||||
for rec in res:
|
|
||||||
rec.update({'company_name': self.browse(rec.get('id')).company_id.name})
|
|
||||||
|
|
||||||
return res
|
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def get_widget_count(self, args):
|
||||||
|
return self.sudo().search_count(args)
|
||||||
|
Before Width: | Height: | Size: 401 KiB After Width: | Height: | Size: 2.0 MiB |
|
Before Width: | Height: | Size: 243 KiB After Width: | Height: | Size: 1.6 MiB |
|
Before Width: | Height: | Size: 202 KiB After Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 199 KiB After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 307 KiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 701 KiB |
|
After Width: | Height: | Size: 182 KiB |
|
After Width: | Height: | Size: 389 B |
|
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 1.2 MiB |
55
odex25_base/advanced_web_domain_widget/static/src/js/fields/basic_fields.js
Normal file → Executable file
|
|
@ -12,7 +12,7 @@ var config = require('web.config');
|
||||||
var core = require('web.core');
|
var core = require('web.core');
|
||||||
var Domain = require('web.Domain');
|
var Domain = require('web.Domain');
|
||||||
var DomainSelector = require('advanced_web_domain_widget.TerabitsDomainSelector');
|
var DomainSelector = require('advanced_web_domain_widget.TerabitsDomainSelector');
|
||||||
var DomainSelectorDialog = require('advanced_web_domain_widget.DomainSelectorDialog');
|
var {DomainSelectorDialog, DomainSelectorDialog2} = require('advanced_web_domain_widget.DomainSelectorDialog');
|
||||||
var view_dialogs = require('web.view_dialogs');
|
var view_dialogs = require('web.view_dialogs');
|
||||||
|
|
||||||
require("web.zoomodoo");
|
require("web.zoomodoo");
|
||||||
|
|
@ -439,8 +439,61 @@ var TerabitsFieldDomain = AbstractField.extend({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var TerabitsFieldDomain2 = TerabitsFieldDomain.extend({
|
||||||
|
_replaceContent: function () {
|
||||||
|
if (this._$content) {
|
||||||
|
this._$content.remove();
|
||||||
|
}
|
||||||
|
this._$content = $(qweb.render("TerabitsFieldDomain.content2", {
|
||||||
|
hasModel: !!this._domainModel,
|
||||||
|
isValid: !!this._isValidForModel,
|
||||||
|
nbRecords: this.record.specialData[this.name].nbRecords || 0,
|
||||||
|
inDialogEdit: this.inDialog && this.mode === "edit",
|
||||||
|
isDateFilter: this.value[0] && this.value[0]?.length>0? this.value[0][1] == "date_filter": false
|
||||||
|
}));
|
||||||
|
this._$content.appendTo(this.$el);
|
||||||
|
},
|
||||||
|
|
||||||
|
_render: function () {
|
||||||
|
// If there is no model, only change the non-domain-selector content
|
||||||
|
if (!this._domainModel) {
|
||||||
|
this._replaceContent();
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert char value to array value
|
||||||
|
var value = this.value || "[]";
|
||||||
|
|
||||||
|
// Create the domain selector or change the value of the current one...
|
||||||
|
var def;
|
||||||
|
|
||||||
|
if (!this.domainSelector) {
|
||||||
|
this.domainSelector = new DomainSelector.TerabitsDomainSelector2(this, this._domainModel, value, {
|
||||||
|
readonly: this.mode === "readonly" || this.inDialog,
|
||||||
|
filters: this.fsFilters,
|
||||||
|
debugMode: config.isDebug(),
|
||||||
|
});
|
||||||
|
def = this.domainSelector.prependTo(this.$el);
|
||||||
|
} else {
|
||||||
|
def = this.domainSelector.setDomain(value);
|
||||||
|
}
|
||||||
|
// ... then replace the other content (matched records, etc)
|
||||||
|
return def.then(this._replaceContent.bind(this));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onDialogEditButtonClick: function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
new DomainSelectorDialog2(this, this._domainModel, this.value || "[]", {
|
||||||
|
readonly: this.mode === "readonly",
|
||||||
|
filters: this.fsFilters,
|
||||||
|
debugMode: config.isDebug(),
|
||||||
|
}).open();
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
TerabitsFieldDomain: TerabitsFieldDomain,
|
TerabitsFieldDomain: TerabitsFieldDomain,
|
||||||
|
TerabitsFieldDomain2: TerabitsFieldDomain2
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
2
odex25_base/advanced_web_domain_widget/static/src/js/fields/basic_model.js
Normal file → Executable file
|
|
@ -239,7 +239,7 @@ BasicModel.include({
|
||||||
});
|
});
|
||||||
self._rpc({
|
self._rpc({
|
||||||
model: domainModel,
|
model: domainModel,
|
||||||
method: 'search_count',
|
method: 'get_widget_count',
|
||||||
args: [newDomain],
|
args: [newDomain],
|
||||||
context: context
|
context: context
|
||||||
})
|
})
|
||||||
|
|
|
||||||
1
odex25_base/advanced_web_domain_widget/static/src/js/fields/terabits_fields_registry.js
Normal file → Executable file
|
|
@ -6,6 +6,7 @@ odoo.define('advanced_web_domain_widget._terabits_field_registry', function (req
|
||||||
|
|
||||||
// Basic fields
|
// Basic fields
|
||||||
fieldRegistry.add('terabits_domain', basic_fields.TerabitsFieldDomain);
|
fieldRegistry.add('terabits_domain', basic_fields.TerabitsFieldDomain);
|
||||||
|
fieldRegistry.add('terabits_field_domain', basic_fields.TerabitsFieldDomain2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
320
odex25_base/advanced_web_domain_widget/static/src/js/widget/TerabitsDomainSelector.js
Normal file → Executable file
|
|
@ -5,7 +5,7 @@ odoo.define("advanced_web_domain_widget.TerabitsDomainSelector", function (requi
|
||||||
var datepicker = require("web.datepicker");
|
var datepicker = require("web.datepicker");
|
||||||
var Domain = require("web.Domain");
|
var Domain = require("web.Domain");
|
||||||
var field_utils = require("web.field_utils");
|
var field_utils = require("web.field_utils");
|
||||||
var ModelFieldSelector = require("advanced_web_domain_widget.ModelFieldSelector");
|
var {ModelFieldSelector, ModelFieldSelector2} = require("advanced_web_domain_widget.ModelFieldSelector");
|
||||||
var ModelRecordSelector = require("advanced_web_domain_widget.ModelRecordSelector");
|
var ModelRecordSelector = require("advanced_web_domain_widget.ModelRecordSelector");
|
||||||
var Widget = require("web.Widget");
|
var Widget = require("web.Widget");
|
||||||
var _t = core._t;
|
var _t = core._t;
|
||||||
|
|
@ -451,6 +451,33 @@ odoo.define("advanced_web_domain_widget.TerabitsDomainSelector", function (requi
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var TerabitsDomainTree2 = TerabitsDomainTree.extend({
|
||||||
|
_addChild: function (domain, afterNode) {
|
||||||
|
var i = afterNode ? _.indexOf(this.children, afterNode) : this.children.length;
|
||||||
|
if (i < 0) return false;
|
||||||
|
|
||||||
|
this.children.splice(i + 1, 0, instantiateNode2(this, this.model, domain, this.options));
|
||||||
|
this.trigger_up("domain_changed", { child: this });
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
_addFlattenedChildren: function (domain) {
|
||||||
|
var node = instantiateNode2(this, this.model, domain, this.options);
|
||||||
|
if (node === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!node.children || node.operator !== this.operator) {
|
||||||
|
this.children.push(node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_.each(node.children, (function (child) {
|
||||||
|
child.setParent(this);
|
||||||
|
this.children.push(child);
|
||||||
|
}).bind(this));
|
||||||
|
node.destroy();
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The TerabitsDomainSelector widget can be used to build prefix char domain. It is the
|
* The TerabitsDomainSelector widget can be used to build prefix char domain. It is the
|
||||||
* TerabitsDomainTree specialization to use to have a fully working widget.
|
* TerabitsDomainTree specialization to use to have a fully working widget.
|
||||||
|
|
@ -611,6 +638,154 @@ odoo.define("advanced_web_domain_widget.TerabitsDomainSelector", function (requi
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var TerabitsDomainSelector2 = TerabitsDomainTree2.extend({
|
||||||
|
template: "TerabitsDomainSelector",
|
||||||
|
events: _.extend({}, TerabitsDomainTree.prototype.events, {
|
||||||
|
"click .o_domain_add_first_node_button": "_onAddFirstButtonClick",
|
||||||
|
"change .o_domain_debug_input": "_onDebugInputChange",
|
||||||
|
}),
|
||||||
|
custom_events: _.extend({}, TerabitsDomainTree.prototype.custom_events, {
|
||||||
|
domain_changed: "_onDomainChange",
|
||||||
|
}),
|
||||||
|
|
||||||
|
start: function () {
|
||||||
|
var self = this;
|
||||||
|
return this._super.apply(this, arguments).then(function () {
|
||||||
|
if (self.invalidDomain) {
|
||||||
|
var msg = _t("This domain is not supported.");
|
||||||
|
self.$el.html(msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Public
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the internal domain value and forces a reparsing and rerendering.
|
||||||
|
* If the internal domain value was already equal to the given one, this
|
||||||
|
* does nothing.
|
||||||
|
*
|
||||||
|
* @param {string} domain
|
||||||
|
* @returns {Promise} resolved when the rerendering is finished
|
||||||
|
*/
|
||||||
|
setDomain: function (domain) {
|
||||||
|
if (domain === Domain.prototype.arrayToString(this.getDomain())) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
var parsedDomain = this._parseDomain(domain);
|
||||||
|
if (parsedDomain) {
|
||||||
|
return this._redraw(parsedDomain);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Private
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see TerabitsDomainTree._initialize
|
||||||
|
*/
|
||||||
|
_initialize: function (domain) {
|
||||||
|
// Check if the domain starts with implicit "&" operators and make them
|
||||||
|
// explicit. As the TerabitsDomainSelector is a specialization of a TerabitsDomainTree,
|
||||||
|
// it is waiting for a tree and not a leaf. So [] and [A] will be made
|
||||||
|
// explicit with ["&"], ["&", A] so that tree parsing is made correctly.
|
||||||
|
// Note: the domain is considered to be a valid one
|
||||||
|
if (domain.length > 1) {
|
||||||
|
Domain.prototype.normalizeArray(domain);
|
||||||
|
} else {
|
||||||
|
domain = ["&"].concat(domain);
|
||||||
|
}
|
||||||
|
return this._super(domain);
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* @see TerabitsDomainTree._postRender
|
||||||
|
* Warns the user if the domain is not valid after rendering.
|
||||||
|
*/
|
||||||
|
_postRender: function () {
|
||||||
|
this._super.apply(this, arguments);
|
||||||
|
|
||||||
|
// Display technical domain if in debug mode
|
||||||
|
this.$debugInput = this.$(".o_domain_debug_input");
|
||||||
|
if (this.$debugInput.length) {
|
||||||
|
this.$debugInput.val(Domain.prototype.arrayToString(this.getDomain()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warn the user if the domain is not valid after rendering
|
||||||
|
if (!this._isValid) {
|
||||||
|
this.do_warn(false, _t("Domain not supported"));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* This method is ugly but achieves the right behavior without flickering.
|
||||||
|
*
|
||||||
|
* @param {Array|string} domain
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
_redraw: function (domain) {
|
||||||
|
var oldChildren = this.children.slice();
|
||||||
|
this._initialize(domain || this.getDomain());
|
||||||
|
return this._renderChildrenTo($("<div/>")).then((function () {
|
||||||
|
_.each(oldChildren, function (child) { child.destroy(); });
|
||||||
|
this.renderElement();
|
||||||
|
this._postRender();
|
||||||
|
_.each(this.children, (function (child) {
|
||||||
|
if(child.$el){
|
||||||
|
child.$el.appendTo(this.$childrenContainer);
|
||||||
|
}
|
||||||
|
}).bind(this));
|
||||||
|
}).bind(this));
|
||||||
|
},
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Handlers
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the "add a filter" button is clicked -> adds a first domain
|
||||||
|
* node
|
||||||
|
*/
|
||||||
|
_onAddFirstButtonClick: function () {
|
||||||
|
this._addChild(this.options.default || [["id", "=", 1]]);
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Called when the debug input value is changed -> constructs the tree
|
||||||
|
* representation if valid or warn the user if invalid.
|
||||||
|
*
|
||||||
|
* @param {Event} e
|
||||||
|
*/
|
||||||
|
_onDebugInputChange: function (e) {
|
||||||
|
// When the debug input changes, the string prefix domain is read. If it
|
||||||
|
// is syntax-valid the widget is re-rendered and notifies the parents.
|
||||||
|
// If not, a warning is shown to the user and the input is ignored.
|
||||||
|
var domain;
|
||||||
|
try {
|
||||||
|
domain = Domain.prototype.stringToArray($(e.currentTarget).val());
|
||||||
|
} catch (err) { // If there is a syntax error, just ignore the change
|
||||||
|
this.do_warn(_t("Syntax error"), _t("Domain not properly formed"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._redraw(domain).then((function () {
|
||||||
|
this.trigger_up("domain_changed", { child: this, alreadyRedrawn: true });
|
||||||
|
}).bind(this));
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Called when a (child's) domain has changed -> redraw the entire tree
|
||||||
|
* representation if necessary
|
||||||
|
*
|
||||||
|
* @param {OdooEvent} e
|
||||||
|
*/
|
||||||
|
_onDomainChange: function (e) {
|
||||||
|
// If a subdomain notifies that it underwent some modifications, the
|
||||||
|
// TerabitsDomainSelector catches the message and performs a full re-rendering.
|
||||||
|
if (!e.data.alreadyRedrawn) {
|
||||||
|
this._redraw();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TerabitsDomainNode which handles a domain which cannot be split in another
|
* TerabitsDomainNode which handles a domain which cannot be split in another
|
||||||
* subdomains, i.e. composed of a field chain, an operator and a value.
|
* subdomains, i.e. composed of a field chain, an operator and a value.
|
||||||
|
|
@ -711,13 +886,21 @@ odoo.define("advanced_web_domain_widget.TerabitsDomainSelector", function (requi
|
||||||
const ids = (this.value) ? this.value : [];
|
const ids = (this.value) ? this.value : [];
|
||||||
wDefs.push(this._rpc({
|
wDefs.push(this._rpc({
|
||||||
model: model_rel,
|
model: model_rel,
|
||||||
method: 'search_read',
|
method: 'get_widget_name',
|
||||||
kwargs: {
|
kwargs: {
|
||||||
domain: [['id', 'in', ids]],
|
domain: [['id', 'in', ids]],
|
||||||
fields: ['id', 'display_name'],
|
fields: ['id', 'display_name'],
|
||||||
},
|
},
|
||||||
}).then(function (data) {
|
}).then(function (data) {
|
||||||
self.value = [];
|
self.value = [];
|
||||||
|
if(model_rel == 'res.users' && _.contains(ids,0)){
|
||||||
|
self.tagsvalues.push([0, 'Environment User']);
|
||||||
|
self.value.push(0);
|
||||||
|
}
|
||||||
|
if(model_rel == 'res.company' && _.contains(ids,0)){
|
||||||
|
self.tagsvalues.push([0, 'Environment Company']);
|
||||||
|
self.value.push(0);
|
||||||
|
}
|
||||||
_.each(data, function (rec, index) {
|
_.each(data, function (rec, index) {
|
||||||
self.tagsvalues.push([rec.id, rec.display_name]);
|
self.tagsvalues.push([rec.id, rec.display_name]);
|
||||||
// to remove invalid id which is not in records
|
// to remove invalid id which is not in records
|
||||||
|
|
@ -1065,6 +1248,126 @@ odoo.define("advanced_web_domain_widget.TerabitsDomainSelector", function (requi
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var TerabitsDomainLeaf2 = TerabitsDomainLeaf.extend({
|
||||||
|
willStart: function () {
|
||||||
|
var defs = [this._super.apply(this, arguments)];
|
||||||
|
|
||||||
|
// In edit mode, instantiate a field selector. This is done here in
|
||||||
|
// willStart and prepared by appending it to a dummy element because the
|
||||||
|
// TerabitsDomainLeaf rendering need some information which cannot be computed
|
||||||
|
// before the ModelFieldSelector is fully rendered (TODO).
|
||||||
|
|
||||||
|
this.fieldSelector = new ModelFieldSelector2(
|
||||||
|
this,
|
||||||
|
this.model,
|
||||||
|
this.chain !== undefined ? this.chain.toString().split(".") : [],
|
||||||
|
this.options
|
||||||
|
);
|
||||||
|
defs.push(this.fieldSelector.appendTo($("<div/>")).then((function () {
|
||||||
|
var wDefs = [];
|
||||||
|
var selectedField = this.fieldSelector.getSelectedField() || {};
|
||||||
|
if ((this.operator == 'in' && _.contains(['many2one', 'many2many', 'one2many'], selectedField.type) || selectedField.name == "id") && typeof (this.currentDomain[0][2][0]) == 'string') {
|
||||||
|
this.value = [];
|
||||||
|
} else {
|
||||||
|
this.value = this.currentDomain[0][2];
|
||||||
|
}
|
||||||
|
this.title = selectedField.string;
|
||||||
|
this.recordReader = new ModelRecordSelector(
|
||||||
|
this,
|
||||||
|
selectedField.relation,
|
||||||
|
this.chain !== undefined ? this.chain.toString().split(".") : [],
|
||||||
|
this.options,
|
||||||
|
this.title
|
||||||
|
);
|
||||||
|
if (!this.readonly) {
|
||||||
|
// Set list of operators according to field type
|
||||||
|
this.displayValue = this.value;
|
||||||
|
this.operators = this._getOperatorsFromType(selectedField.type, selectedField.name);
|
||||||
|
if (_.contains(["child_of", "parent_of", "like", "not like", "=like", "=ilike"], this.operator)) {
|
||||||
|
// In case user entered manually or from demo data
|
||||||
|
this.operators[this.operator] = operator_mapping[this.operator];
|
||||||
|
} else if (!this.operators[this.operator]) {
|
||||||
|
// In case the domain uses an unsupported operator for the
|
||||||
|
// field type
|
||||||
|
this.operators[this.operator] = "?";
|
||||||
|
}
|
||||||
|
// Set list of values according to field type
|
||||||
|
|
||||||
|
this.selectionChoices = null;
|
||||||
|
if (selectedField.type === "boolean") {
|
||||||
|
this.selectionChoices = [["1", _t("set (true)")], ["0", _t("not set (false)")]];
|
||||||
|
} else if (selectedField.type === "selection") {
|
||||||
|
this.selectionChoices = selectedField.selection;
|
||||||
|
}
|
||||||
|
else if ((_.contains(['many2one', 'many2many', 'one2many'], selectedField.type) || selectedField.name == "id") && (_.contains(['in', 'not in'], this.operator))) {
|
||||||
|
var model_rel = selectedField.name == "id"? selectedField.model: selectedField.relation
|
||||||
|
// var def = this.get_rec(model_rel)
|
||||||
|
// var model_rel = selectedField.relation
|
||||||
|
this.selectionChoices = null
|
||||||
|
// this.recordReader.appendTo($("<div/>"))
|
||||||
|
var self = this;
|
||||||
|
const ids = (this.value) ? this.value : [];
|
||||||
|
wDefs.push(this._rpc({
|
||||||
|
model: model_rel,
|
||||||
|
method: 'get_widget_name',
|
||||||
|
kwargs: {
|
||||||
|
domain: [['id', 'in', ids]],
|
||||||
|
fields: ['id', 'display_name'],
|
||||||
|
},
|
||||||
|
}).then(function (data) {
|
||||||
|
self.value = [];
|
||||||
|
if(model_rel == 'res.users' && _.contains(ids,0)){
|
||||||
|
self.tagsvalues.push([0, 'Environment User']);
|
||||||
|
self.value.push(0);
|
||||||
|
}
|
||||||
|
if(model_rel == 'res.company' && _.contains(ids,0)){
|
||||||
|
self.tagsvalues.push([0, 'Environment Company']);
|
||||||
|
self.value.push(0);
|
||||||
|
}
|
||||||
|
_.each(data, function (rec, index) {
|
||||||
|
self.tagsvalues.push([rec.id, rec.display_name]);
|
||||||
|
// to remove invalid id which is not in records
|
||||||
|
self.value.push(rec.id);
|
||||||
|
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
|
||||||
|
wDefs.push(this.recordReader.appendTo($('<div/>')).then((function () {
|
||||||
|
this.displayValue = [];
|
||||||
|
// this.value = [];
|
||||||
|
}).bind(this)));
|
||||||
|
}
|
||||||
|
// Adapt display value and operator for rendering
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (selectedField && !selectedField.relation && !_.isArray(this.value)) {
|
||||||
|
this.displayValue = field_utils.format[selectedField.type](this.value, selectedField);
|
||||||
|
}
|
||||||
|
} catch (err) {/**/ }
|
||||||
|
this.displayOperator = this.operator;
|
||||||
|
if (selectedField.type === "boolean") {
|
||||||
|
this.displayValue = this.value ? "1" : "0";
|
||||||
|
} else if ((this.operator === "!=" || this.operator === "=") && this.value === false) {
|
||||||
|
this.displayOperator = this.operator === "!=" ? "set" : "not set";
|
||||||
|
}
|
||||||
|
// TODO the value could be a m2o input, etc...
|
||||||
|
if (_.contains(["date", "datetime"], selectedField.type)) {
|
||||||
|
this.valueWidget = new (selectedField.type === "datetime" ? datepicker.DateTimeWidget : datepicker.DateWidget)(this);
|
||||||
|
wDefs.push(this.valueWidget.appendTo("<div/>").then((function () {
|
||||||
|
this.valueWidget.$el.addClass("o_domain_leaf_value_input");
|
||||||
|
this.valueWidget.setValue(moment(this.value));
|
||||||
|
this.valueWidget.on("datetime_changed", this, function () {
|
||||||
|
this._changeValue(this.valueWidget.getValue());
|
||||||
|
});
|
||||||
|
}).bind(this)));
|
||||||
|
}
|
||||||
|
return Promise.all(wDefs);
|
||||||
|
}
|
||||||
|
}).bind(this)));
|
||||||
|
|
||||||
|
return Promise.all(defs);
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1086,8 +1389,19 @@ odoo.define("advanced_web_domain_widget.TerabitsDomainSelector", function (requi
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function instantiateNode2(parent, model, domain, options) {
|
||||||
|
if (domain.length > 1) {
|
||||||
|
return new TerabitsDomainTree2(parent, model, domain, options);
|
||||||
|
} else if (domain.length === 1) {
|
||||||
|
return new TerabitsDomainLeaf2(parent, model, domain, options);
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
TerabitsDomainSelector:TerabitsDomainSelector,
|
TerabitsDomainSelector:TerabitsDomainSelector,
|
||||||
TerabitsDomainLeaf:TerabitsDomainLeaf
|
TerabitsDomainSelector2:TerabitsDomainSelector2,
|
||||||
|
TerabitsDomainLeaf:TerabitsDomainLeaf,
|
||||||
|
TerabitsDomainLeaf2:TerabitsDomainLeaf2,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
||||||
37
odex25_base/advanced_web_domain_widget/static/src/js/widget/domain_selector_dialog.js
Normal file → Executable file
|
|
@ -10,7 +10,7 @@ odoo.define("advanced_web_domain_widget.DomainSelectorDialog", function (require
|
||||||
/**
|
/**
|
||||||
* @class DomainSelectorDialog
|
* @class DomainSelectorDialog
|
||||||
*/
|
*/
|
||||||
return Dialog.extend({
|
var DomainSelectorDialog = Dialog.extend({
|
||||||
init: function (parent, model, domain, options) {
|
init: function (parent, model, domain, options) {
|
||||||
this.model = model;
|
this.model = model;
|
||||||
this.options = _.extend({
|
this.options = _.extend({
|
||||||
|
|
@ -51,5 +51,40 @@ odoo.define("advanced_web_domain_widget.DomainSelectorDialog", function (require
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var DomainSelectorDialog2 = DomainSelectorDialog.extend({
|
||||||
|
init: function (parent, model, domain, options) {
|
||||||
|
this.model = model;
|
||||||
|
this.options = _.extend({
|
||||||
|
readonly: true,
|
||||||
|
debugMode: false,
|
||||||
|
}, options || {});
|
||||||
|
|
||||||
|
var buttons;
|
||||||
|
if (this.options.readonly) {
|
||||||
|
buttons = [
|
||||||
|
{text: _t("Close"), close: true},
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
buttons = [
|
||||||
|
{text: _t("Save"), classes: "btn-primary", close: true, click: function () {
|
||||||
|
this.trigger_up("domain_selected", {domain: this.domainSelector.getDomain()});
|
||||||
|
}},
|
||||||
|
{text: _t("Discard"), close: true},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
this._super(parent, _.extend({}, {
|
||||||
|
title: _t("Domain"),
|
||||||
|
buttons: buttons,
|
||||||
|
}, options || {}));
|
||||||
|
|
||||||
|
this.domainSelector = new DomainSelector.TerabitsDomainSelector2(this, model, domain, options);
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
DomainSelectorDialog: DomainSelectorDialog,
|
||||||
|
DomainSelectorDialog2: DomainSelectorDialog2
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
61
odex25_base/advanced_web_domain_widget/static/src/js/widget/model_field_selector.js
Normal file → Executable file
|
|
@ -586,7 +586,66 @@ var TerabitsModelFieldSelector = Widget.extend({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return TerabitsModelFieldSelector;
|
var TerabitsModelFieldSelector2 = TerabitsModelFieldSelector.extend({
|
||||||
|
_render: function () {
|
||||||
|
|
||||||
|
// Render the chain value
|
||||||
|
this.$value.html(core.qweb.render(this.template + ".value", {
|
||||||
|
chain: this.chain,
|
||||||
|
pages: this.pages,
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Toggle the warning message
|
||||||
|
this.$valid.toggleClass('d-none', !!this.isValid());
|
||||||
|
|
||||||
|
// Adapt the popover content
|
||||||
|
var page = _.last(this.pages);
|
||||||
|
var title = "";
|
||||||
|
if (this.pages.length > 1) {
|
||||||
|
var prevField = _.findWhere(this.pages[this.pages.length - 2], {
|
||||||
|
name: (this.chain.length === this.pages.length) ? this.chain[this.chain.length - 2] : _.last(this.chain),
|
||||||
|
});
|
||||||
|
if (prevField) title = prevField.string;
|
||||||
|
}
|
||||||
|
this.$(".o_field_selector_popover_header .o_field_selector_title").text(title);
|
||||||
|
|
||||||
|
var lines = _.filter(page, this.options.filter);
|
||||||
|
if (this.searchValue) {
|
||||||
|
var matches = fuzzy.filter(this.searchValue, _.pluck(lines, 'string'));
|
||||||
|
lines = _.map(_.pluck(matches, 'index'), function (i) {
|
||||||
|
return lines[i];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$(".o_field_selector_page").replaceWith(core.qweb.render(this.template + ".page2", {
|
||||||
|
lines: lines,
|
||||||
|
followRelations: this.options.followRelations,
|
||||||
|
debug: this.options.debugMode,
|
||||||
|
}));
|
||||||
|
this.$input.val(this.chain.join("."));
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
_pushPageData: function (model) {
|
||||||
|
var def;
|
||||||
|
if (this.model === model && this.options.fields) {
|
||||||
|
def = Promise.resolve(sortFields(this.options.fields, model, this.options.order));
|
||||||
|
} else {
|
||||||
|
def = this._getModelFieldsFromCache(model, this.options.filters);
|
||||||
|
}
|
||||||
|
return def.then((function (fields) {
|
||||||
|
if(this.pages.length <= 0)
|
||||||
|
this.pages.push(fields);
|
||||||
|
}).bind(this));
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
_onPrevPageClick: function () {
|
||||||
|
// this._goToPrevPage();
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return {ModelFieldSelector: TerabitsModelFieldSelector,
|
||||||
|
ModelFieldSelector2: TerabitsModelFieldSelector2};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows to transform a mapping field name -> field info in an array of the
|
* Allows to transform a mapping field name -> field info in an array of the
|
||||||
|
|
|
||||||
8
odex25_base/advanced_web_domain_widget/static/src/js/widget/model_record_selector.js
Normal file → Executable file
|
|
@ -104,7 +104,7 @@ odoo.define("advanced_web_domain_widget.ModelRecordSelector", function (require)
|
||||||
;
|
;
|
||||||
var def = this._rpc({
|
var def = this._rpc({
|
||||||
model: model,
|
model: model,
|
||||||
method: 'search_read',
|
method: 'get_widget_name',
|
||||||
kwargs: {
|
kwargs: {
|
||||||
domain: [],
|
domain: [],
|
||||||
fields: ['id', 'display_name'],
|
fields: ['id', 'display_name'],
|
||||||
|
|
@ -113,6 +113,12 @@ odoo.define("advanced_web_domain_widget.ModelRecordSelector", function (require)
|
||||||
if (data) {
|
if (data) {
|
||||||
this.records = data
|
this.records = data
|
||||||
}
|
}
|
||||||
|
if(model == 'res.users'){
|
||||||
|
this.records.push({'id': 0, 'display_name': 'Environment User'})
|
||||||
|
}
|
||||||
|
if(model == 'res.company'){
|
||||||
|
this.records.push({'id': 0, 'display_name': 'Environment Company'})
|
||||||
|
}
|
||||||
// if(model == 'res.users'){
|
// if(model == 'res.users'){
|
||||||
// this.records.push({'id':0,'display_name':'Environment User'})
|
// this.records.push({'id':0,'display_name':'Environment User'})
|
||||||
// }
|
// }
|
||||||
|
|
|
||||||
28
odex25_base/advanced_web_domain_widget/static/src/xml/domain_base.xml
Normal file → Executable file
|
|
@ -16,6 +16,22 @@
|
||||||
</div>
|
</div>
|
||||||
<div t-else="">Select a model to add a filter.</div>
|
<div t-else="">Select a model to add a filter.</div>
|
||||||
</t>
|
</t>
|
||||||
|
|
||||||
|
<t t-name="TerabitsFieldDomain.content2">
|
||||||
|
<div t-if="hasModel" class="o_field_domain_panel">
|
||||||
|
<!-- <i class="fa fa-arrow-right" role="img" aria-label="Domain" title="Domain"/>
|
||||||
|
|
||||||
|
<button t-if="isValid" class="btn btn-sm btn-secondary o_domain_show_selection_button" type="button">
|
||||||
|
<t t-esc="nbRecords"/> record(s)
|
||||||
|
</button> -->
|
||||||
|
<t t-if="!isValid">
|
||||||
|
<span class="text-warning" role="alert"><i class="fa fa-exclamation-triangle" role="img" aria-label="Warning" title="Warning"/> Invalid domain</span>
|
||||||
|
</t>
|
||||||
|
|
||||||
|
<button t-if="inDialogEdit" class="btn btn-sm btn-primary o_field_domain_dialog_button">Edit Domain</button>
|
||||||
|
</div>
|
||||||
|
<div t-else="">Select a model to add a filter.</div>
|
||||||
|
</t>
|
||||||
<t t-name="TerabitsDomainNode.ControlPanel">
|
<t t-name="TerabitsDomainNode.ControlPanel">
|
||||||
<div t-if="!widget.readonly && !widget.noControlPanel" class="o_domain_node_control_panel" role="toolbar" aria-label="Domain node">
|
<div t-if="!widget.readonly && !widget.noControlPanel" class="o_domain_node_control_panel" role="toolbar" aria-label="Domain node">
|
||||||
<button class="btn o_domain_delete_node_button" title="Delete node" aria-label="Delete node"><i class="fa fa-times"/></button>
|
<button class="btn o_domain_delete_node_button" title="Delete node" aria-label="Delete node"><i class="fa fa-times"/></button>
|
||||||
|
|
@ -259,6 +275,18 @@
|
||||||
</li>
|
</li>
|
||||||
</t>
|
</t>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<ul t-name="TerabitsModelFieldSelector.page2" class="o_field_selector_page">
|
||||||
|
<t t-foreach="lines" t-as="line">
|
||||||
|
<t t-set="relationToFollow" t-value="followRelations(line) && line.relation"/>
|
||||||
|
<li t-attf-class="o_field_selector_item #{relationToFollow and 'o_field_selector_next_page' or 'o_field_selector_select_button'}#{line_index == 0 and ' active' or ''}"
|
||||||
|
t-att-data-name="line.name">
|
||||||
|
<t t-esc="line.string"/>
|
||||||
|
<div t-if="debug" class="text-muted o_field_selector_item_title"><t t-esc="line.name"/> (<t t-esc="line.type"/>)</div>
|
||||||
|
<!-- <i t-if="relationToFollow" class="fa fa-chevron-right o_field_selector_relation_icon" role="img" aria-label="Relation to follow" title="Relation to follow"/> -->
|
||||||
|
</li>
|
||||||
|
</t>
|
||||||
|
</ul>
|
||||||
<ul t-name="TerabitsModelRecordSelector.page" class="o_record_selector_page">
|
<ul t-name="TerabitsModelRecordSelector.page" class="o_record_selector_page">
|
||||||
<t t-foreach="lines" t-as="line">
|
<t t-foreach="lines" t-as="line">
|
||||||
<!-- <t t-set="relationToFollow" t-value="followRelations(line) && line.relation"/> -->
|
<!-- <t t-set="relationToFollow" t-value="followRelations(line) && line.relation"/> -->
|
||||||
|
|
|
||||||
|
|
@ -14,5 +14,4 @@ def post_install_action_dup_hook(cr, registry):
|
||||||
env = api.Environment(cr, SUPERUSER_ID, {})
|
env = api.Environment(cr, SUPERUSER_ID, {})
|
||||||
action_data_obj = env['action.data']
|
action_data_obj = env['action.data']
|
||||||
for action in env['ir.actions.actions'].search([]):
|
for action in env['ir.actions.actions'].search([]):
|
||||||
print(action.name,"===================")
|
|
||||||
action_data_obj.create({'name':action.name,'action_id':action.id})
|
action_data_obj.create({'name':action.name,'action_id':action.id})
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#################################################################################
|
#################################################################################
|
||||||
# Author : Terabits Technolab (<www.terabits.xyz>)
|
# Author : Terabits Technolab (<www.terabits.xyz>)
|
||||||
# Copyright(c): 2021-23
|
# Copyright(c): 2023-24
|
||||||
# All Rights Reserved.
|
# All Rights Reserved.
|
||||||
#
|
#
|
||||||
# This module is copyright property of the author mentioned above.
|
# This module is copyright property of the author mentioned above.
|
||||||
|
|
@ -11,12 +11,12 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
'name': 'Simplify Access Management',
|
'name': 'Simplify Access Management',
|
||||||
'version': '14.0.11.4.5',
|
'version': '14.0.12.8.5',
|
||||||
'sequence': 5,
|
'sequence': 5,
|
||||||
'author': 'Terabits Technolab',
|
'author': 'Terabits Technolab',
|
||||||
'license': 'OPL-1',
|
'license': 'OPL-1',
|
||||||
'category': 'Odex25-base',
|
'category': 'Services',
|
||||||
'website': 'https://www.terabits.xyz/r/SNS',
|
'website': 'https://www.terabits.xyz/apps/14.0/simplify_access_management',
|
||||||
'summary': """All In One Access Management App for setting the correct access rights for fields, models, menus, views for any module and for any user.
|
'summary': """All In One Access Management App for setting the correct access rights for fields, models, menus, views for any module and for any user.
|
||||||
All in one access management App,
|
All in one access management App,
|
||||||
Easier then Record rules setup,
|
Easier then Record rules setup,
|
||||||
|
|
@ -160,11 +160,11 @@
|
||||||
|
|
||||||
""",
|
""",
|
||||||
"images": ["static/description/banner.gif"],
|
"images": ["static/description/banner.gif"],
|
||||||
"price": "370.99",
|
"price": "280.99",
|
||||||
"currency": "USD",
|
"currency": "USD",
|
||||||
'data': [
|
'data': [
|
||||||
'security/ir.model.access.csv',
|
|
||||||
'security/res_groups.xml',
|
'security/res_groups.xml',
|
||||||
|
'security/ir.model.access.csv',
|
||||||
'data/view_data.xml',
|
'data/view_data.xml',
|
||||||
'views/access_management_view.xml',
|
'views/access_management_view.xml',
|
||||||
'views/assets.xml',
|
'views/assets.xml',
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
# from . import main
|
# from . import main
|
||||||
from . import action
|
from . import action
|
||||||
|
from . import export
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
from odoo import http
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
from odoo.addons.web.controllers.main import Export
|
||||||
|
from odoo.http import request
|
||||||
|
|
||||||
|
class Export(Export):
|
||||||
|
|
||||||
|
def fields_get(self, model):
|
||||||
|
fields=super().fields_get(model)
|
||||||
|
invisible_field_ids = request.env['hide.field'].sudo().search(
|
||||||
|
[('access_management_id.company_ids', 'in', request.env.company.id),
|
||||||
|
('model_id.model', '=', model), ('access_management_id.active', '=', True),
|
||||||
|
('access_management_id.user_ids', 'in', request.env.user.id),
|
||||||
|
('invisible','=',True)])
|
||||||
|
if not invisible_field_ids:
|
||||||
|
return fields
|
||||||
|
else :
|
||||||
|
for key, value in list(fields.items()):
|
||||||
|
for invisible_field in invisible_field_ids.field_id:
|
||||||
|
if key == invisible_field.name and key != "id":
|
||||||
|
del fields[key]
|
||||||
|
return fields
|
||||||
|
|
@ -10,14 +10,15 @@ class access_domain_ah(models.Model):
|
||||||
'ir.model', string='Model', index=True, required=True, ondelete='cascade')
|
'ir.model', string='Model', index=True, required=True, ondelete='cascade')
|
||||||
model_name = fields.Char(string='Model Name', related='model_id.model', readonly=True, store=True)
|
model_name = fields.Char(string='Model Name', related='model_id.model', readonly=True, store=True)
|
||||||
apply_domain = fields.Boolean('Apply Filter')
|
apply_domain = fields.Boolean('Apply Filter')
|
||||||
domain = fields.Char(string='Filter', default='[]')
|
domain = fields.Char(string='Filter', default='[]',
|
||||||
|
help="The create customised domain rule where we can customise rule by selecting specific fields and records")
|
||||||
|
|
||||||
access_management_id = fields.Many2one('access.management','Access Management')
|
access_management_id = fields.Many2one('access.management','Access Management')
|
||||||
|
|
||||||
read_right = fields.Boolean('Read',default=True)
|
read_right = fields.Boolean('Read',default=True, help="The set 'Read' access of the selected model for the specified users")
|
||||||
create_right = fields.Boolean('Create')
|
create_right = fields.Boolean('Create', help="The set 'Create' access of the selected model for the specified users")
|
||||||
write_right = fields.Boolean('Write')
|
write_right = fields.Boolean('Write', help="The set 'Write' access of the selected model for the specified users")
|
||||||
delete_right = fields.Boolean('Delete')
|
delete_right = fields.Boolean('Delete', help="The set 'Delete' access of the selected model for the specified users")
|
||||||
|
|
||||||
@api.onchange('apply_domain')
|
@api.onchange('apply_domain')
|
||||||
def _check_domain(self):
|
def _check_domain(self):
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,8 @@ class access_management(models.Model):
|
||||||
active = fields.Boolean('Active', default=True)
|
active = fields.Boolean('Active', default=True)
|
||||||
|
|
||||||
hide_menu_ids = fields.Many2many('ir.ui.menu', 'access_management_menu_rel_ah', 'access_management_id', 'menu_id',
|
hide_menu_ids = fields.Many2many('ir.ui.menu', 'access_management_menu_rel_ah', 'access_management_id', 'menu_id',
|
||||||
'Hide Menu')
|
'Hide Menu',
|
||||||
|
help="The menu or submenu added on above list will be hidden from the defined users.")
|
||||||
hide_field_ids = fields.One2many('hide.field', 'access_management_id', 'Hide Field', copy=True)
|
hide_field_ids = fields.One2many('hide.field', 'access_management_id', 'Hide Field', copy=True)
|
||||||
|
|
||||||
remove_action_ids = fields.One2many('remove.action', 'access_management_id', 'Remove Action', copy=True)
|
remove_action_ids = fields.One2many('remove.action', 'access_management_id', 'Remove Action', copy=True)
|
||||||
|
|
@ -32,16 +33,21 @@ class access_management(models.Model):
|
||||||
# Chatter
|
# Chatter
|
||||||
hide_chatter_ids = fields.One2many('hide.chatter', 'access_management_id', 'Hide Chatter', copy=True)
|
hide_chatter_ids = fields.One2many('hide.chatter', 'access_management_id', 'Hide Chatter', copy=True)
|
||||||
|
|
||||||
hide_chatter = fields.Boolean('Hide Chatter')
|
hide_chatter = fields.Boolean('Hide Chatter',
|
||||||
hide_send_mail = fields.Boolean('Hide Send Message')
|
help="The Chatter will be hidden in all model from the specified users.")
|
||||||
hide_log_notes = fields.Boolean('Hide Log Notes')
|
hide_send_mail = fields.Boolean('Hide Send Message',
|
||||||
hide_schedule_activity = fields.Boolean('Hide Schedule Activity')
|
help="The Send Message button will be hidden in chatter of all model from the specified users.")
|
||||||
|
hide_log_notes = fields.Boolean('Hide Log Notes',
|
||||||
|
help="The Log Notes button will be hidden in chatter of all model from the specified users.")
|
||||||
|
hide_schedule_activity = fields.Boolean('Hide Schedule Activity',
|
||||||
|
help="The Schedule Activity button will be hidden in chatter of all model from the specified users.")
|
||||||
|
|
||||||
hide_export = fields.Boolean()
|
hide_export = fields.Boolean(help="The Export button will be hidden in all model from the specified users.")
|
||||||
hide_import = fields.Boolean()
|
hide_import = fields.Boolean(help="The Import button will be hidden in all model from the specified users.")
|
||||||
disable_login = fields.Boolean('Disable Login')
|
disable_login = fields.Boolean('Disable Login',help="The Users can not login if this button is chek.")
|
||||||
|
|
||||||
disable_debug_mode = fields.Boolean('Disable Developer Mode')
|
disable_debug_mode = fields.Boolean('Disable Developer Mode',
|
||||||
|
help="Developer mode will be hidden from the defined users.")
|
||||||
|
|
||||||
company_ids = fields.Many2many('res.company', 'access_management_comapnay_rel', 'access_management_id',
|
company_ids = fields.Many2many('res.company', 'access_management_comapnay_rel', 'access_management_id',
|
||||||
'company_id', 'Companies', required=True, default=lambda self: self.env.company)
|
'company_id', 'Companies', required=True, default=lambda self: self.env.company)
|
||||||
|
|
@ -49,6 +55,7 @@ class access_management(models.Model):
|
||||||
hide_filters_groups_ids = fields.One2many('hide.filters.groups', 'access_management_id', 'Hide Filters/Group By',
|
hide_filters_groups_ids = fields.One2many('hide.filters.groups', 'access_management_id', 'Hide Filters/Group By',
|
||||||
copy=True)
|
copy=True)
|
||||||
|
|
||||||
|
is_apply_on_without_company = fields.Boolean()
|
||||||
def _count_total_rules(self):
|
def _count_total_rules(self):
|
||||||
for rec in self:
|
for rec in self:
|
||||||
rule = 0
|
rule = 0
|
||||||
|
|
@ -110,7 +117,7 @@ class access_management(models.Model):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def get_remove_options(self, model):
|
def get_remove_options(self, model):
|
||||||
restrict_export = self.env['access.management'].search([('company_ids', 'in', self.env.company.id),
|
restrict_export = self.env['access.management'].sudo().search([('company_ids', 'in', self.env.company.id),
|
||||||
('active', '=', True),
|
('active', '=', True),
|
||||||
('user_ids', 'in', self.env.user.id),
|
('user_ids', 'in', self.env.user.id),
|
||||||
('hide_export', '=', True)], limit=1).id
|
('hide_export', '=', True)], limit=1).id
|
||||||
|
|
@ -158,7 +165,7 @@ class access_management(models.Model):
|
||||||
hide_schedule_activity = False
|
hide_schedule_activity = False
|
||||||
|
|
||||||
if model and hide_send_mail or hide_log_notes or hide_schedule_activity:
|
if model and hide_send_mail or hide_log_notes or hide_schedule_activity:
|
||||||
hide_ids = self.env['hide.chatter'].search([('access_management_id.company_ids', 'in', company_id),
|
hide_ids = self.env['hide.chatter'].sudo().search([('access_management_id.company_ids', 'in', company_id),
|
||||||
('access_management_id.active', '=', True),
|
('access_management_id.active', '=', True),
|
||||||
('access_management_id.user_ids', 'in', user_id),
|
('access_management_id.user_ids', 'in', user_id),
|
||||||
('model_id.model', '=', model)])
|
('model_id.model', '=', model)])
|
||||||
|
|
@ -192,9 +199,23 @@ class access_management(models.Model):
|
||||||
break
|
break
|
||||||
|
|
||||||
if not hide_export and model:
|
if not hide_export and model:
|
||||||
if self.env['remove.action'].search([('access_management_id', 'in', access_ids.ids),
|
if self.env['remove.action'].sudo().search([('access_management_id', 'in', access_ids.ids),
|
||||||
('model_id.model', '=', model),
|
('model_id.model', '=', model),
|
||||||
('restrict_export', '=', True)]):
|
('restrict_export', '=', True)]):
|
||||||
hide_export = True
|
hide_export = True
|
||||||
|
|
||||||
return hide_export
|
return hide_export
|
||||||
|
|
||||||
|
def get_hidden_field(self, model=False):
|
||||||
|
if model:
|
||||||
|
hidden_fields = []
|
||||||
|
hide_field_obj = self.env['hide.field'].sudo()
|
||||||
|
for hide_field in hide_field_obj.search(
|
||||||
|
[('access_management_id.company_ids', 'in', self.env.company.id),
|
||||||
|
('model_id.model', '=', model), ('access_management_id.active', '=', True),
|
||||||
|
('access_management_id.user_ids', 'in', self._uid), ('invisible', '=', True)]):
|
||||||
|
for field in hide_field.field_id:
|
||||||
|
if field.name:
|
||||||
|
hidden_fields.append(field.name)
|
||||||
|
return hidden_fields
|
||||||
|
return []
|
||||||
|
|
@ -9,7 +9,9 @@ class hide_chatter(models.Model):
|
||||||
access_management_id = fields.Many2one('access.management', 'Access Management')
|
access_management_id = fields.Many2one('access.management', 'Access Management')
|
||||||
model_id = fields.Many2one('ir.model', 'Model')
|
model_id = fields.Many2one('ir.model', 'Model')
|
||||||
|
|
||||||
hide_chatter = fields.Boolean('Chatter')
|
hide_chatter = fields.Boolean('Chatter'
|
||||||
hide_send_mail = fields.Boolean('Send Message')
|
,help="The Chatter will be hidden in selected model from the specified users.")
|
||||||
hide_log_notes = fields.Boolean('Log Notes')
|
hide_send_mail = fields.Boolean('Send Message'
|
||||||
hide_schedule_activity = fields.Boolean('Schedule Activity')
|
,help="The Send Message button will be hidden in chatter of selected model from the specified users.")
|
||||||
|
hide_log_notes = fields.Boolean('Log Notes', help="The Log Notes button will be hidden in chatter of selected model from the specified users.")
|
||||||
|
hide_schedule_activity = fields.Boolean('Schedule Activity',help="The Schedule Activity button will be hidden in chatter of selected model from the specified users.")
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ class hide_field(models.Model):
|
||||||
|
|
||||||
field_id = fields.Many2many('ir.model.fields', 'hide_field_ir_model_fields_rel', 'hide_field_id', 'ir_field_id', 'Field')
|
field_id = fields.Many2many('ir.model.fields', 'hide_field_ir_model_fields_rel', 'hide_field_id', 'ir_field_id', 'Field')
|
||||||
|
|
||||||
invisible = fields.Boolean('Invisible')
|
invisible = fields.Boolean('Invisible', help="Selected Field will be hidden in selected model from the defined users.")
|
||||||
readonly = fields.Boolean('Read-Only')
|
readonly = fields.Boolean('Read-Only', help="Selected Field will be Read only in selected model from the defined users.")
|
||||||
required = fields.Boolean('Required')
|
required = fields.Boolean('Required', help="Selected Field will be set as required for selected model from the defined users.")
|
||||||
external_link = fields.Boolean('Remove External Link')
|
external_link = fields.Boolean('Remove External Link',help="External Link will be hidden for relational fields in selected model from the defined users.")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,11 @@ class hide_filters_groups(models.Model):
|
||||||
model_name = fields.Char(string='Model Name', related='model_id.model', readonly=True, store=True)
|
model_name = fields.Char(string='Model Name', related='model_id.model', readonly=True, store=True)
|
||||||
|
|
||||||
filters_store_model_nodes_ids = fields.Many2many('store.filters.groups', 'filters_hide_filters_groups_store_filters_groups_rel',
|
filters_store_model_nodes_ids = fields.Many2many('store.filters.groups', 'filters_hide_filters_groups_store_filters_groups_rel',
|
||||||
'hide_id', 'store_id', string='Hide Filters', domain="[('node_option','=','filter')]")
|
'hide_id', 'store_id', string='Hide Filters', domain="[('node_option','=','filter')]",
|
||||||
|
help="The Defalut filter are added on list will be hidden in search view of selected model from the specified users.")
|
||||||
groups_store_model_nodes_ids = fields.Many2many('store.filters.groups', 'groups_hide_filters_groups_store_filters_groups_rel',
|
groups_store_model_nodes_ids = fields.Many2many('store.filters.groups', 'groups_hide_filters_groups_store_filters_groups_rel',
|
||||||
'hide_id', 'store_id', string='Hide Groups', domain="[('node_option','=','group')]")
|
'hide_id', 'store_id', string='Hide Groups', domain="[('node_option','=','group')]",
|
||||||
|
help="The Defalut Group are added on list will be hidden in search view of selected model from the specified users.")
|
||||||
|
|
||||||
access_management_id = fields.Many2one('access.management', 'Access Management')
|
access_management_id = fields.Many2one('access.management', 'Access Management')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,12 @@ class hide_view_nodes(models.Model):
|
||||||
|
|
||||||
model_name = fields.Char(string='Model Name', related='model_id.model', readonly=True, store=True)
|
model_name = fields.Char(string='Model Name', related='model_id.model', readonly=True, store=True)
|
||||||
|
|
||||||
btn_store_model_nodes_ids = fields.Many2many('store.model.nodes','btn_hide_view_nodes_store_model_nodes_rel','hide_id','store_id',string='Hide Button',domain="[('node_option','=','button')]")
|
btn_store_model_nodes_ids = fields.Many2many('store.model.nodes','btn_hide_view_nodes_store_model_nodes_rel','hide_id','store_id',string='Hide Button',domain="[('node_option','=','button')]",
|
||||||
page_store_model_nodes_ids = fields.Many2many('store.model.nodes','page_hide_view_nodes_store_model_nodes_rel','hide_id','store_id',string='Hide Tab/Page',domain="[('node_option','=','page')]")
|
help="The Buttons are added on list will be hidden in selected model from the defined users.")
|
||||||
link_store_model_nodes_ids = fields.Many2many('store.model.nodes','link_hide_view_nodes_store_model_nodes_rel','hide_id','store_id',string='Hide Kanban Link',domain="[('node_option','=','link')]")
|
page_store_model_nodes_ids = fields.Many2many('store.model.nodes','page_hide_view_nodes_store_model_nodes_rel','hide_id','store_id',string='Hide Tab/Page',domain="[('node_option','=','page')]",
|
||||||
|
help="The Tabs(pages) are added on list will be hidden in selected model from the defined users.")
|
||||||
|
link_store_model_nodes_ids = fields.Many2many('store.model.nodes','link_hide_view_nodes_store_model_nodes_rel','hide_id','store_id',string='Hide Kanban Link',domain="[('node_option','=','link')]",
|
||||||
|
help="The Kanban view action are added on list will be hidden in selected model from the defined users.")
|
||||||
|
|
||||||
access_management_id = fields.Many2one('access.management','Access Management')
|
access_management_id = fields.Many2one('access.management','Access Management')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import logging
|
import logging
|
||||||
from odoo.http import request
|
from odoo.http import request
|
||||||
from odoo import api, fields, models, tools, _
|
from odoo import api, fields, models, tools,_
|
||||||
from odoo.exceptions import Warning, ValidationError, AccessError
|
from odoo.exceptions import Warning, ValidationError,AccessError
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class ir_model_access(models.Model):
|
class ir_model_access(models.Model):
|
||||||
_inherit = 'ir.model.access'
|
_inherit = 'ir.model.access'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# The context parameter is useful when the method translates error messages.
|
# The context parameter is useful when the method translates error messages.
|
||||||
# But as the method raises an exception in that case, the key 'lang' might
|
# But as the method raises an exception in that case, the key 'lang' might
|
||||||
# not be really necessary as a cache key, unless the `ormcache_context`
|
# not be really necessary as a cache key, unless the `ormcache_context`
|
||||||
|
|
@ -30,6 +31,7 @@ class ir_model_access(models.Model):
|
||||||
_logger.error('Missing model %s', model)
|
_logger.error('Missing model %s', model)
|
||||||
|
|
||||||
self.flush(self._fields)
|
self.flush(self._fields)
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This part is writen to by pass base access rule and apply dynamic rule of access management rule,
|
This part is writen to by pass base access rule and apply dynamic rule of access management rule,
|
||||||
|
|
@ -41,7 +43,7 @@ class ir_model_access(models.Model):
|
||||||
if model:
|
if model:
|
||||||
self._cr.execute("SELECT id FROM ir_model WHERE model='" + model + "'")
|
self._cr.execute("SELECT id FROM ir_model WHERE model='" + model + "'")
|
||||||
model_numeric_id = self._cr.fetchone()[0]
|
model_numeric_id = self._cr.fetchone()[0]
|
||||||
if model_numeric_id and isinstance(model_numeric_id, int) and self.env.user:
|
if model_numeric_id and isinstance(model_numeric_id,int) and self.env.user:
|
||||||
try:
|
try:
|
||||||
self._cr.execute("""
|
self._cr.execute("""
|
||||||
SELECT dm.id
|
SELECT dm.id
|
||||||
|
|
@ -53,13 +55,14 @@ class ir_model_access(models.Model):
|
||||||
IN (SELECT amusr.access_management_id
|
IN (SELECT amusr.access_management_id
|
||||||
FROM access_management_users_rel_ah as amusr
|
FROM access_management_users_rel_ah as amusr
|
||||||
WHERE amusr.user_id=%s))
|
WHERE amusr.user_id=%s))
|
||||||
""", [model_numeric_id, self.env.user.id])
|
""",[model_numeric_id, self.env.user.id])
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
access_domain_ah_ids = self.env['access.domain.ah'].browse(row[0] for row in self._cr.fetchall()).filtered(lambda line: self.env.company in line.access_management_id.company_ids)
|
access_domain_ah_ids = self.env['access.domain.ah'].sudo().browse(row[0] for row in self._cr.fetchall()).filtered(lambda line: self.env.company in line.access_management_id.company_ids)
|
||||||
if access_domain_ah_ids:
|
if access_domain_ah_ids:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
# We check if a specific rule exists
|
# We check if a specific rule exists
|
||||||
self._cr.execute("""SELECT MAX(CASE WHEN perm_{mode} THEN 1 ELSE 0 END)
|
self._cr.execute("""SELECT MAX(CASE WHEN perm_{mode} THEN 1 ELSE 0 END)
|
||||||
FROM ir_model_access a
|
FROM ir_model_access a
|
||||||
|
|
@ -88,7 +91,7 @@ class ir_model_access(models.Model):
|
||||||
msg_heads = {
|
msg_heads = {
|
||||||
# Messages are declared in extenso so they are properly exported in translation terms
|
# Messages are declared in extenso so they are properly exported in translation terms
|
||||||
'read': _("You are not allowed to access '%(document_kind)s' (%(document_model)s) records.", document_kind=document_kind, document_model=model),
|
'read': _("You are not allowed to access '%(document_kind)s' (%(document_model)s) records.", document_kind=document_kind, document_model=model),
|
||||||
'write': _("You are not allowed to modify '%(document_kind)s' (%(document_model)s) records.", document_kind=document_kind, document_model=model),
|
'write': _("You are not allowed to modify '%(document_kind)s' (%(document_model)s) records.", document_kind=document_kind, document_model=model),
|
||||||
'create': _("You are not allowed to create '%(document_kind)s' (%(document_model)s) records.", document_kind=document_kind, document_model=model),
|
'create': _("You are not allowed to create '%(document_kind)s' (%(document_model)s) records.", document_kind=document_kind, document_model=model),
|
||||||
'unlink': _("You are not allowed to delete '%(document_kind)s' (%(document_model)s) records.", document_kind=document_kind, document_model=model),
|
'unlink': _("You are not allowed to delete '%(document_kind)s' (%(document_model)s) records.", document_kind=document_kind, document_model=model),
|
||||||
}
|
}
|
||||||
|
|
@ -102,7 +105,11 @@ class ir_model_access(models.Model):
|
||||||
resolution_info = _("Contact your administrator to request access if necessary.")
|
resolution_info = _("Contact your administrator to request access if necessary.")
|
||||||
|
|
||||||
_logger.info('Access Denied by ACLs for operation: %s, uid: %s, model: %s', mode, self._uid, model)
|
_logger.info('Access Denied by ACLs for operation: %s, uid: %s, model: %s', mode, self._uid, model)
|
||||||
msg = """{operation_error} {group_info} {resolution_info}""".format(
|
msg = """{operation_error}
|
||||||
|
|
||||||
|
{group_info}
|
||||||
|
|
||||||
|
{resolution_info}""".format(
|
||||||
operation_error=operation_error,
|
operation_error=operation_error,
|
||||||
group_info=group_info,
|
group_info=group_info,
|
||||||
resolution_info=resolution_info)
|
resolution_info=resolution_info)
|
||||||
|
|
@ -116,24 +123,22 @@ class ir_model_access(models.Model):
|
||||||
if data and data[0] != 'installed':
|
if data and data[0] != 'installed':
|
||||||
read_value = False
|
read_value = False
|
||||||
if self.env.user.id and read_value:
|
if self.env.user.id and read_value:
|
||||||
company_id = request.httprequest.cookies.get('cids') and request.httprequest.cookies.get('cids').split(',')[0] or request.env.company.id
|
a = "select access_management_id from access_management_comapnay_rel where company_id = " + str(request.httprequest.cookies.get('cids') and request.httprequest.cookies.get('cids').split(',')[0] or request.env.company.id)
|
||||||
a = "select access_management_id from access_management_comapnay_rel where company_id = " + company_id
|
|
||||||
if not company_id:
|
|
||||||
a = "select access_management_id from access_management_comapnay_rel where company_id = NULL"
|
|
||||||
self._cr.execute(a)
|
self._cr.execute(a)
|
||||||
a = self._cr.fetchall()
|
a = self._cr.fetchall()
|
||||||
if a:
|
if a:
|
||||||
a = "select access_management_id from access_management_users_rel_ah where user_id = " + str(self.env.user.id) + " AND access_management_id in " + str(tuple([i[0] for i in a] + [0]))
|
a = "select access_management_id from access_management_users_rel_ah where user_id = " + str(self.env.user.id) + " AND access_management_id in " + str(tuple([i[0] for i in a]+[0]))
|
||||||
self._cr.execute(a)
|
self._cr.execute(a)
|
||||||
a = self._cr.fetchall()
|
a = self._cr.fetchall()
|
||||||
if a:
|
if a:
|
||||||
a = "SELECT id FROM access_management WHERE active='t' AND id in " + str(tuple([i[0] for i in a] + [0])) + " and readonly = True"
|
a = "SELECT id FROM access_management WHERE active='t' AND id in " + str(tuple([i[0] for i in a]+[0])) + " and readonly = True"
|
||||||
self._cr.execute(a)
|
self._cr.execute(a)
|
||||||
a = self._cr.fetchall()
|
a = self._cr.fetchall()
|
||||||
if bool(a):
|
if bool(a):
|
||||||
if mode != 'read':
|
if mode != 'read':
|
||||||
return False
|
return False
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
return bool(r)
|
return bool(r)
|
||||||
|
|
|
||||||
|
|
@ -33,14 +33,14 @@ class ir_rule(models.Model):
|
||||||
model_list = ['mail.activity','res.users.log','res.users','mail.channel','mail.alias','bus.presence','res.lang']
|
model_list = ['mail.activity','res.users.log','res.users','mail.channel','mail.alias','bus.presence','res.lang']
|
||||||
if self.env.user.id and read_value and not all_data:
|
if self.env.user.id and read_value and not all_data:
|
||||||
if model_name not in model_list:
|
if model_name not in model_list:
|
||||||
# self._cr.execute("""SELECT am.id FROM access_management as am
|
self._cr.execute("""SELECT am.id FROM access_management as am
|
||||||
# WHERE active='t' AND readonly = True AND am.id
|
WHERE active='t' AND readonly = True AND am.id
|
||||||
# IN (SELECT au.access_management_id
|
IN (SELECT au.access_management_id
|
||||||
# FROM access_management_users_rel_ah as au
|
FROM access_management_users_rel_ah as au
|
||||||
# WHERE user_id = %s AND am.id
|
WHERE user_id = %s AND am.id
|
||||||
# IN (SELECT ac.access_management_id
|
IN (SELECT ac.access_management_id
|
||||||
# FROM access_management_comapnay_rel as ac
|
FROM access_management_comapnay_rel as ac
|
||||||
# WHERE ac.company_id=%s))"""%(self.env.user.id, self.env.company.id))
|
WHERE ac.company_id=%s))"""%(self.env.user.id, self.env.company.id))
|
||||||
# a = "select access_management_id from access_management_comapnay_rel where company_id = " + str(self.env.company.id)
|
# a = "select access_management_id from access_management_comapnay_rel where company_id = " + str(self.env.company.id)
|
||||||
# self._cr.execute(a)
|
# self._cr.execute(a)
|
||||||
# a = self._cr.fetchall()
|
# a = self._cr.fetchall()
|
||||||
|
|
@ -85,11 +85,13 @@ class ir_rule(models.Model):
|
||||||
""", [model_numeric_id, self.env.user.id])
|
""", [model_numeric_id, self.env.user.id])
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
access_domain_ah_ids = self.env['access.domain.ah'].browse(
|
access_domain_ah_ids = self.env['access.domain.ah'].sudo().browse(
|
||||||
row[0] for row in self._cr.fetchall()).filtered(
|
row[0] for row in self._cr.fetchall()).filtered(
|
||||||
lambda line: self.env.company in line.access_management_id.company_ids)
|
lambda line: self.env.company in line.access_management_id.company_ids)
|
||||||
# access_domain_ah_ids = access_domain_ah_ids.filtered(lambda line: self.env.company in line.access_management_id.company_ids)
|
# access_domain_ah_ids = access_domain_ah_ids.filtered(lambda line: self.env.company in line.access_management_id.company_ids)
|
||||||
if access_domain_ah_ids:
|
if access_domain_ah_ids:
|
||||||
|
all_company = self.env['res.company'].sudo().search([]).ids
|
||||||
|
company_domain = []
|
||||||
domain_list = []
|
domain_list = []
|
||||||
if model_name == 'res.partner':
|
if model_name == 'res.partner':
|
||||||
# jo aya user related jetala partner 6 ana access alag thi apididha 6 error no ave atle
|
# jo aya user related jetala partner 6 ana access alag thi apididha 6 error no ave atle
|
||||||
|
|
@ -99,8 +101,23 @@ class ir_rule(models.Model):
|
||||||
eval_context = self._eval_context()
|
eval_context = self._eval_context()
|
||||||
# only domain records
|
# only domain records
|
||||||
length = len(access_domain_ah_ids.sudo()) if access_domain_ah_ids.sudo() else 0
|
length = len(access_domain_ah_ids.sudo()) if access_domain_ah_ids.sudo() else 0
|
||||||
|
com_domain=[]
|
||||||
for access in access_domain_ah_ids.sudo():
|
for access in access_domain_ah_ids.sudo():
|
||||||
dom = safe_eval(access.domain, eval_context) if access.domain else []
|
dom = safe_eval(access.domain, eval_context) if access.domain else []
|
||||||
|
if not dom and isinstance(dom,list):
|
||||||
|
if length>1:
|
||||||
|
domain_list.insert(0,'|')
|
||||||
|
domain_list += [('id', '!=', False)]
|
||||||
|
length -= 1
|
||||||
|
company_domain=[]
|
||||||
|
if self.env[model_name]._fields.get('company_id'):
|
||||||
|
if res:
|
||||||
|
for domain_tuple in res:
|
||||||
|
|
||||||
|
if isinstance(domain_tuple,tuple) and domain_tuple[0] == 'company_id':
|
||||||
|
all_company = self.env['res.company'].sudo().browse(domain_tuple[2]).ids
|
||||||
|
company_domain_tuple = ('company_id','in',access.access_management_id.company_ids.ids)
|
||||||
|
company_domain.append(company_domain_tuple)
|
||||||
if dom:
|
if dom:
|
||||||
dom = expression.normalize_domain(dom)
|
dom = expression.normalize_domain(dom)
|
||||||
for dom_tuple in dom:
|
for dom_tuple in dom:
|
||||||
|
|
@ -138,14 +155,49 @@ class ir_rule(models.Model):
|
||||||
right_value[zero_index] = self.env.company.id
|
right_value[zero_index] = self.env.company.id
|
||||||
if operator_value == 'date_filter':
|
if operator_value == 'date_filter':
|
||||||
domain_list += prepare_domain_v2(dom_tuple)
|
domain_list += prepare_domain_v2(dom_tuple)
|
||||||
|
domain_list.insert(0,'&')
|
||||||
|
domain_list+= company_domain
|
||||||
else:
|
else:
|
||||||
domain_list.append(dom_tuple)
|
if company_domain:
|
||||||
|
company_domain.append(dom_tuple)
|
||||||
|
domain_list.insert(0,'&')
|
||||||
|
domain_list+= company_domain
|
||||||
|
|
||||||
|
else:
|
||||||
|
domain_list.append(dom_tuple)
|
||||||
else:
|
else:
|
||||||
domain_list.append(dom_tuple)
|
domain_list.append(dom_tuple)
|
||||||
if length > 1:
|
if length > 1:
|
||||||
domain_list.insert(0, '|')
|
domain_list.insert(0, '|')
|
||||||
length -= 1
|
length -= 1
|
||||||
|
|
||||||
|
if self.env[model_name]._fields.get('company_id'):
|
||||||
|
if res:
|
||||||
|
for domain_tuple in res:
|
||||||
|
dom = domain_tuple
|
||||||
|
if isinstance(dom,tuple):
|
||||||
|
if domain_tuple[0] == 'company_id':
|
||||||
|
if len(all_company)>1:
|
||||||
|
for company in access.access_management_id.company_ids.ids:
|
||||||
|
if company in all_company:
|
||||||
|
all_company.remove(company)
|
||||||
|
if all_company and False not in all_company:
|
||||||
|
if access.access_management_id.is_apply_on_without_company:
|
||||||
|
domain = ('company_id','in',all_company+[False])
|
||||||
|
else:
|
||||||
|
domain = ('company_id','in',all_company)
|
||||||
|
if domain not in com_domain:
|
||||||
|
com_domain.append(('company_id','in',all_company))
|
||||||
|
else:
|
||||||
|
if isinstance(domain_tuple[2],list):
|
||||||
|
if domain_tuple[2][0] not in access.access_management_id.company_ids.ids:
|
||||||
|
com_domain.append(domain_tuple)
|
||||||
|
else:
|
||||||
|
com_domain.append(domain_tuple)
|
||||||
if domain_list:
|
if domain_list:
|
||||||
|
if com_domain:
|
||||||
|
domain_list.insert(0, '|')
|
||||||
|
domain_list+=com_domain
|
||||||
return domain_list
|
return domain_list
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,12 @@ class ir_ui_view(models.Model):
|
||||||
hide_button_obj = self.env['hide.view.nodes']
|
hide_button_obj = self.env['hide.view.nodes']
|
||||||
if name_manager.Model._name == 'res.config.settings' and node.tag == 'div' and node.get('string'):
|
if name_manager.Model._name == 'res.config.settings' and node.tag == 'div' and node.get('string'):
|
||||||
for setting_tab in hide_button_obj.sudo().search([('access_management_id.company_ids','in',self.env.company.id),('model_id.model','=',name_manager.Model._name),('access_management_id.active','=',True),('access_management_id.user_ids','in',self._uid)]).mapped('page_store_model_nodes_ids'):
|
for setting_tab in hide_button_obj.sudo().search([('access_management_id.company_ids','in',self.env.company.id),('model_id.model','=',name_manager.Model._name),('access_management_id.active','=',True),('access_management_id.user_ids','in',self._uid)]).mapped('page_store_model_nodes_ids'):
|
||||||
if node.get('string') == setting_tab.attribute_string and node.get('data-key') == setting_tab.attribute_name:
|
if node.get('data-key') == setting_tab.attribute_name:
|
||||||
node_info['modifiers']['invisible'] = True
|
node_info['modifiers']['invisible'] = True
|
||||||
node.set('invisible', '1')
|
node.set('invisible', '1')
|
||||||
if node.tag == 'a':
|
if node.tag == 'a':
|
||||||
if node.text and '\n' not in node.text and 'type' in node.attrib.keys() and node.attrib['type'] and 'name' in node.attrib.keys() and node.attrib['name']:
|
if node.text and '\n' not in node.text and 'type' in node.attrib.keys() and node.attrib['type'] and 'name' in node.attrib.keys() and node.attrib['name']:
|
||||||
if hide_view_node_obj.search([
|
if hide_view_node_obj.sudo().search([
|
||||||
('model_id.model','=',name_manager.Model._name),
|
('model_id.model','=',name_manager.Model._name),
|
||||||
('access_management_id.active','=',True),
|
('access_management_id.active','=',True),
|
||||||
('access_management_id.company_ids','in',self.env.company.id),
|
('access_management_id.company_ids','in',self.env.company.id),
|
||||||
|
|
@ -38,7 +38,7 @@ class ir_ui_view(models.Model):
|
||||||
if hide_field.external_link:
|
if hide_field.external_link:
|
||||||
options_dict = {}
|
options_dict = {}
|
||||||
if 'widget' in node.attrib.keys():
|
if 'widget' in node.attrib.keys():
|
||||||
if node.attrib['widget'] == 'product_configurator':
|
if node.attrib['widget'] == 'product_configurator' or node.attrib['widget'] == 'many2one_avatar_user':
|
||||||
del node.attrib['widget']
|
del node.attrib['widget']
|
||||||
if 'options' in node.attrib.keys():
|
if 'options' in node.attrib.keys():
|
||||||
options_dict = ast.literal_eval(node.attrib['options'])
|
options_dict = ast.literal_eval(node.attrib['options'])
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ class BaseModel(models.AbstractModel):
|
||||||
@api.model
|
@api.model
|
||||||
def load_views(self, views, options=None):
|
def load_views(self, views, options=None):
|
||||||
actions_and_prints = []
|
actions_and_prints = []
|
||||||
for access in self.env['remove.action'].search([('access_management_id.company_ids', 'in', self.env.company.id),
|
for access in self.env['remove.action'].sudo().search([('access_management_id.company_ids', 'in', self.env.company.id),
|
||||||
('access_management_id', 'in',
|
('access_management_id', 'in',
|
||||||
self.env.user.access_management_ids.ids),
|
self.env.user.access_management_ids.ids),
|
||||||
('model_id.model', '=', self._name)]):
|
('model_id.model', '=', self._name)]):
|
||||||
|
|
@ -49,13 +49,13 @@ class BaseModel(models.AbstractModel):
|
||||||
res = super().fields_view_get(view_id, view_type, toolbar, submenu)
|
res = super().fields_view_get(view_id, view_type, toolbar, submenu)
|
||||||
access_management_obj = self.env['access.management']
|
access_management_obj = self.env['access.management']
|
||||||
cids = request.httprequest.cookies.get('cids') and request.httprequest.cookies.get('cids').split(',')[0] or request.env.company.id
|
cids = request.httprequest.cookies.get('cids') and request.httprequest.cookies.get('cids').split(',')[0] or request.env.company.id
|
||||||
readonly_access_id = access_management_obj.search([('company_ids','in',int(cids)),('active','=',True),('user_ids','in',self.env.user.id),('readonly','=',True)])
|
readonly_access_id = access_management_obj.sudo().search([('company_ids','in',int(cids)),('active','=',True),('user_ids','in',self.env.user.id),('readonly','=',True)])
|
||||||
|
|
||||||
access_recs = self.env['access.domain.ah'].search([('access_management_id.company_ids','in',self.env.company.id),('access_management_id.user_ids','in',self.env.user.id),('access_management_id.active','=',True),('model_id.model','=',res['model'])])
|
access_recs = self.env['access.domain.ah'].sudo().search([('access_management_id.company_ids','in',self.env.company.id),('access_management_id.user_ids','in',self.env.user.id),('access_management_id.active','=',True),('model_id.model','=',res['model'])])
|
||||||
access_model_recs = self.env['remove.action'].search([('access_management_id.company_ids','in',self.env.company.id),('access_management_id.user_ids','in',self.env.user.id),('access_management_id.active','=',True),('model_id.model','=',res['model'])])
|
access_model_recs = self.env['remove.action'].sudo().search([('access_management_id.company_ids','in',self.env.company.id),('access_management_id.user_ids','in',self.env.user.id),('access_management_id.active','=',True),('model_id.model','=',res['model'])])
|
||||||
|
|
||||||
if view_type == 'form':
|
if view_type == 'form':
|
||||||
access_management_id = access_management_obj.search([('company_ids', 'in', self.env.company.id),
|
access_management_id = access_management_obj.sudo().search([('company_ids', 'in', self.env.company.id),
|
||||||
('active', '=', True),
|
('active', '=', True),
|
||||||
('user_ids', 'in', self.env.user.id),
|
('user_ids', 'in', self.env.user.id),
|
||||||
('hide_chatter', '=', True)],
|
('hide_chatter', '=', True)],
|
||||||
|
|
@ -66,7 +66,7 @@ class BaseModel(models.AbstractModel):
|
||||||
div.getparent().remove(div)
|
div.getparent().remove(div)
|
||||||
res['arch'] = etree.tostring(doc, encoding='unicode')
|
res['arch'] = etree.tostring(doc, encoding='unicode')
|
||||||
else:
|
else:
|
||||||
if self.env['hide.chatter'].search([('access_management_id.company_ids', 'in', self.env.company.id),
|
if self.env['hide.chatter'].sudo().search([('access_management_id.company_ids', 'in', self.env.company.id),
|
||||||
('access_management_id.active', '=', True),
|
('access_management_id.active', '=', True),
|
||||||
('access_management_id.user_ids', 'in', self.env.user.id),
|
('access_management_id.user_ids', 'in', self.env.user.id),
|
||||||
('model_id.model', '=', self._name),
|
('model_id.model', '=', self._name),
|
||||||
|
|
@ -78,7 +78,7 @@ class BaseModel(models.AbstractModel):
|
||||||
div.getparent().remove(div)
|
div.getparent().remove(div)
|
||||||
res['arch'] = etree.tostring(doc, encoding='unicode')
|
res['arch'] = etree.tostring(doc, encoding='unicode')
|
||||||
|
|
||||||
restrict_import = access_management_obj.search([('company_ids', 'in', self.env.company.id),
|
restrict_import = access_management_obj.sudo().search([('company_ids', 'in', self.env.company.id),
|
||||||
('active', '=', True),
|
('active', '=', True),
|
||||||
('user_ids', 'in', self.env.user.id),
|
('user_ids', 'in', self.env.user.id),
|
||||||
('hide_import', '=', True)], limit=1).id
|
('hide_import', '=', True)], limit=1).id
|
||||||
|
|
@ -187,7 +187,7 @@ class BaseModel(models.AbstractModel):
|
||||||
FROM access_management_users_rel_ah as amusr
|
FROM access_management_users_rel_ah as amusr
|
||||||
WHERE amusr.user_id=%s))
|
WHERE amusr.user_id=%s))
|
||||||
""",[model_numeric_id, self.env.user.id])
|
""",[model_numeric_id, self.env.user.id])
|
||||||
records = self.env['access.domain.ah'].browse(row[0] for row in self._cr.fetchall())
|
records = self.env['access.domain.ah'].sudo().browse(row[0] for row in self._cr.fetchall())
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
return records
|
return records
|
||||||
|
|
@ -214,50 +214,50 @@ class BaseModel(models.AbstractModel):
|
||||||
domain_list += partner_domain
|
domain_list += partner_domain
|
||||||
# eval_context = rec._eval_context()
|
# eval_context = rec._eval_context()
|
||||||
dom = safe_eval(record.domain) if record.domain else []
|
dom = safe_eval(record.domain) if record.domain else []
|
||||||
dom = expression.normalize_domain(dom)
|
if dom:
|
||||||
model_name = self._name
|
dom = expression.normalize_domain(dom)
|
||||||
if isinstance(dom,list):
|
model_name = self._name
|
||||||
remove_tuple = False
|
if isinstance(dom,list):
|
||||||
for dom_tuple in dom:
|
for dom_tuple in dom:
|
||||||
if isinstance(dom_tuple, tuple):
|
if isinstance(dom_tuple, tuple):
|
||||||
left_value = dom_tuple[0]
|
left_value = dom_tuple[0]
|
||||||
operator_value = dom_tuple[1]
|
operator_value = dom_tuple[1]
|
||||||
right_value = dom_tuple[2]
|
right_value = dom_tuple[2]
|
||||||
left_value_split_list = left_value.split('.')
|
left_value_split_list = left_value.split('.')
|
||||||
model_string = model_name
|
model_string = model_name
|
||||||
left_user = False
|
|
||||||
left_company = False
|
|
||||||
for field in left_value_split_list:
|
|
||||||
left_user = False
|
left_user = False
|
||||||
left_company = False
|
left_company = False
|
||||||
model_obj = self.env[model_string]
|
for field in left_value_split_list:
|
||||||
field_type = model_obj.fields_get()[field]['type']
|
left_user = False
|
||||||
if field_type in ['many2one', 'many2many', 'one2many']:
|
left_company = False
|
||||||
field_relation = model_obj.fields_get()[field]['relation']
|
model_obj = self.env[model_string]
|
||||||
model_string = field_relation
|
field_type = model_obj.fields_get()[field]['type']
|
||||||
if model_string == 'res.users':
|
if field_type in ['many2one', 'many2many', 'one2many']:
|
||||||
left_user = True
|
field_relation = model_obj.fields_get()[field]['relation']
|
||||||
if model_string == 'res.company':
|
model_string = field_relation
|
||||||
left_company = True
|
if model_string == 'res.users':
|
||||||
|
left_user = True
|
||||||
|
if model_string == 'res.company':
|
||||||
|
left_company = True
|
||||||
|
|
||||||
if left_user:
|
if left_user:
|
||||||
if operator_value in ['in', 'not in']:
|
if operator_value in ['in', 'not in']:
|
||||||
if isinstance(right_value, list) and 0 in right_value:
|
if isinstance(right_value, list) and 0 in right_value:
|
||||||
zero_index = right_value.index(0)
|
zero_index = right_value.index(0)
|
||||||
right_value[zero_index] = self.env.user.id
|
right_value[zero_index] = self.env.user.id
|
||||||
|
|
||||||
if left_company:
|
if left_company:
|
||||||
if operator_value in ['in', 'not in']:
|
if operator_value in ['in', 'not in']:
|
||||||
if isinstance(right_value, list) and 0 in right_value:
|
if isinstance(right_value, list) and 0 in right_value:
|
||||||
zero_index = right_value.index(0)
|
zero_index = right_value.index(0)
|
||||||
right_value[zero_index] = self.env.company.id
|
right_value[zero_index] = self.env.company.id
|
||||||
already_add = False
|
already_add = False
|
||||||
if operator_value == 'date_filter':
|
if operator_value == 'date_filter':
|
||||||
domain_list += prepare_domain_v2(dom_tuple)
|
domain_list += prepare_domain_v2(dom_tuple)
|
||||||
|
else:
|
||||||
|
domain_list.append(dom_tuple)
|
||||||
else:
|
else:
|
||||||
domain_list.append(dom_tuple)
|
domain_list.append(dom_tuple)
|
||||||
else:
|
|
||||||
domain_list.append(dom_tuple)
|
|
||||||
# if length > 1:
|
# if length > 1:
|
||||||
# domain_list.insert(0, '|')
|
# domain_list.insert(0, '|')
|
||||||
# length -= 1
|
# length -= 1
|
||||||
|
|
|
||||||
|
|
@ -7,16 +7,23 @@ class remove_action(models.Model):
|
||||||
|
|
||||||
access_management_id = fields.Many2one('access.management', 'Access Management')
|
access_management_id = fields.Many2one('access.management', 'Access Management')
|
||||||
model_id = fields.Many2one('ir.model', 'Model')
|
model_id = fields.Many2one('ir.model', 'Model')
|
||||||
view_data_ids = fields.Many2many('view.data', 'remove_action_view_data_rel_ah', 'remove_action_id', 'view_data_id', 'Hide Views')
|
view_data_ids = fields.Many2many('view.data', 'remove_action_view_data_rel_ah', 'remove_action_id', 'view_data_id', 'Hide Views',
|
||||||
server_action_ids = fields.Many2many('action.data' ,'remove_action_server_action_data_rel_ah', 'remove_action_id', 'server_action_id', 'Hide Actions', domain="[('action_id.binding_model_id','=',model_id),('action_id.type','!=','ir.actions.report')]")
|
help="The views are added on list will be hidden in selected model from the defined users.")
|
||||||
report_action_ids = fields.Many2many('action.data' ,'remove_action_report_action_data_rel_ah', 'remove_action_id', 'report_action_id', 'Hide Reports', domain="[('action_id.binding_model_id','=',model_id),('action_id.type','=','ir.actions.report')]")
|
server_action_ids = fields.Many2many('action.data' ,'remove_action_server_action_data_rel_ah', 'remove_action_id', 'server_action_id', 'Hide Actions', domain="[('action_id.binding_model_id','=',model_id),('action_id.type','!=','ir.actions.report')]",
|
||||||
restrict_export = fields.Boolean('Hide Export')
|
help="The actions are added on list will be hidden in selected model from the defined users.")
|
||||||
restrict_import = fields.Boolean('Hide Import')
|
report_action_ids = fields.Many2many('action.data' ,'remove_action_report_action_data_rel_ah', 'remove_action_id', 'report_action_id', 'Hide Reports', domain="[('action_id.binding_model_id','=',model_id),('action_id.type','=','ir.actions.report')]",
|
||||||
|
help="The Reports are added on list will be hidden in selected model from the defined users.")
|
||||||
|
restrict_export = fields.Boolean('Hide Export',
|
||||||
|
help="Export Button will be hidden in selected model from the defined users.")
|
||||||
|
restrict_import = fields.Boolean('Hide Import',
|
||||||
|
help="Import Button will be hidden in selected model from the defined users.")
|
||||||
readonly = fields.Boolean('Read-Only')
|
readonly = fields.Boolean('Read-Only')
|
||||||
|
|
||||||
restrict_create = fields.Boolean('Hide Create')
|
restrict_create = fields.Boolean('Hide Create',help="Create Button will be hidden in selected model from the defined users.")
|
||||||
restrict_edit = fields.Boolean('Hide Edit')
|
restrict_edit = fields.Boolean('Hide Edit',
|
||||||
restrict_delete = fields.Boolean('Hide Delete')
|
help="Edit Button will be hidden in selected model from the defined users.")
|
||||||
restrict_archive_unarchive = fields.Boolean('Hide Archive/Unarchive')
|
restrict_delete = fields.Boolean('Hide Delete',
|
||||||
restrict_duplicate = fields.Boolean('Hide Duplicate')
|
help="Delete Button will be hidden in selected model from the defined users.")
|
||||||
restrict_chatter = fields.Boolean('Hide Chatter')
|
restrict_archive_unarchive = fields.Boolean('Hide Archive/Unarchive',help="Archive and Unarchive action will be hidden in selected model from the defined users.")
|
||||||
|
restrict_duplicate = fields.Boolean('Hide Duplicate',help="Duplicate action will be hidden in selected model from the defined users.")
|
||||||
|
restrict_chatter = fields.Boolean('Hide Chatter',help="The Chatter will be hidden in selected model from the defined users.")
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ class res_users(models.Model):
|
||||||
self = api.Environment(cr, SUPERUSER_ID, {})[cls._name]
|
self = api.Environment(cr, SUPERUSER_ID, {})[cls._name]
|
||||||
access_management_obj = self.env['access.management']
|
access_management_obj = self.env['access.management']
|
||||||
|
|
||||||
if access_management_obj.search([('user_ids','in',res),('disable_login','=',True)]).id:
|
if access_management_obj.sudo().search([('user_ids','in',res),('disable_login','=',True)]).id:
|
||||||
raise AccessDenied()
|
raise AccessDenied()
|
||||||
except AccessDenied:
|
except AccessDenied:
|
||||||
_logger.info("Login failed for db:%s login:%s from ", db, login)
|
_logger.info("Login failed for db:%s login:%s from ", db, login)
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,22 @@
|
||||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||||
access_access_management,access.access.management,model_access_management,,1,1,1,1
|
access_access_management_portal_user,access.access.management.portal.user,model_access_management,,1,0,0,0
|
||||||
access_remove_action,access.remove.action,model_remove_action,,1,1,1,1
|
access_remove_action_portal_user,access.remove.action.portal.user,model_remove_action,,1,0,0,0
|
||||||
access_hide_field,access.hide.field,model_hide_field,,1,1,1,1
|
access_hide_field_portal_user,access.hide.field.portal.user,model_hide_field,,1,0,0,0
|
||||||
|
access_access_domain_ah_portal_user,access.access.domain.ah.portal.user,model_access_domain_ah,,1,0,0,0
|
||||||
|
access_hide_view_nodes_portal_user,access.hide.view.nodes.portal.user,model_hide_view_nodes,,1,0,0,0
|
||||||
|
access_hide_filters_groups_portal_user,access_hide_filters_groups_portal_user,model_hide_filters_groups,base.group_user,1,0,0,0
|
||||||
|
access_hide_chatter_portal_user,access.hide.chatter.portal.user,model_hide_chatter,,1,0,0,0
|
||||||
|
|
||||||
access_action_data,access.action.data,model_action_data,,1,1,1,1
|
access_action_data,access.action.data,model_action_data,,1,1,1,1
|
||||||
access_view_data,access.view.data,model_view_data,,1,1,1,1
|
access_view_data,access.view.data,model_view_data,,1,1,1,1
|
||||||
access_access_domain_ah,access.access.domain.ah,model_access_domain_ah,,1,1,1,1
|
|
||||||
access_hide_view_nodes,access.hide.view.nodes,model_hide_view_nodes,,1,1,1,1
|
|
||||||
access_store_model_nodes,access.store.model.nodes,model_store_model_nodes,,1,1,1,1
|
access_store_model_nodes,access.store.model.nodes,model_store_model_nodes,,1,1,1,1
|
||||||
access_hide_filters_groups,access_hide_filters_groups,model_hide_filters_groups,base.group_user,1,1,1,1
|
|
||||||
access_store_filters_groups,access_store_filters_groups,model_store_filters_groups,base.group_user,1,1,1,1
|
access_store_filters_groups,access_store_filters_groups,model_store_filters_groups,base.group_user,1,1,1,1
|
||||||
access_hide_chatter,access.hide.chatter,model_hide_chatter,,1,1,1,1
|
access_menu_item,access.menu.item,model_menu_item,,1,1,1,1
|
||||||
|
|
||||||
|
access_access_management,access.access.management,model_access_management,simplify_access_management.group_access_management_bits,1,1,1,1
|
||||||
|
access_access_domain_ah,access.access.domain.ah,model_access_domain_ah,simplify_access_management.group_access_management_bits,1,1,1,1
|
||||||
|
access_remove_action,access.remove.action,model_remove_action,simplify_access_management.group_access_management_bits,1,1,1,1
|
||||||
|
access_hide_field,access.hide.field,model_hide_field,simplify_access_management.group_access_management_bits,1,1,1,1
|
||||||
|
access_hide_view_nodes,access.hide.view.nodes,model_hide_view_nodes,simplify_access_management.group_access_management_bits,1,1,1,1
|
||||||
|
access_hide_filters_groups,access_hide_filters_groups,model_hide_filters_groups,simplify_access_management.group_access_management_bits,1,1,1,1
|
||||||
|
access_hide_chatter,access.hide.chatter,model_hide_chatter,simplify_access_management.group_access_management_bits,1,1,1,1
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<data>
|
<data>
|
||||||
<record id="group_access_management_spt" model="res.groups">
|
<record id="group_access_management_bits" model="res.groups">
|
||||||
<field name="name">Access Management</field>
|
<field name="name">Access Management</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|
|
||||||
|
After Width: | Height: | Size: 7.5 MiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 8.3 KiB |
|
|
@ -0,0 +1,35 @@
|
||||||
|
odoo.define("simpily_access_management.custom_filter_item", function (require) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const ControlPanel = require("web.ControlPanel");
|
||||||
|
const { patch } = require("web.utils");
|
||||||
|
var rpc = require("web.rpc");
|
||||||
|
|
||||||
|
patch(ControlPanel, "ControlPanelPatchBits", {
|
||||||
|
async mounted() {
|
||||||
|
var self = this;
|
||||||
|
this._super(...arguments);
|
||||||
|
self.removedFields = await rpc.query({
|
||||||
|
model: "access.management",
|
||||||
|
method: "get_hidden_field",
|
||||||
|
args: ["", this?.props?.view?.model],
|
||||||
|
});
|
||||||
|
this.removedFields.forEach((element) => {
|
||||||
|
delete self.fields[element];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async patched() {
|
||||||
|
var self = this;
|
||||||
|
this._super(...arguments);
|
||||||
|
self.removedFields = await rpc.query({
|
||||||
|
model: "access.management",
|
||||||
|
method: "get_hidden_field",
|
||||||
|
args: ["", this?.props?.view?.model],
|
||||||
|
});
|
||||||
|
this.removedFields.forEach((element) => {
|
||||||
|
delete self.fields[element];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
odoo.define(
|
||||||
|
"simpily_access_management.group_by_menu",
|
||||||
|
function (require) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const { patch } = require("web.utils");
|
||||||
|
const GroupByMenu = require("web.GroupByMenu");
|
||||||
|
var rpc = require("web.rpc");
|
||||||
|
|
||||||
|
patch(GroupByMenu, "GroupByMenuHideFieldPatch", {
|
||||||
|
async willStart() {
|
||||||
|
await this._super(...arguments);
|
||||||
|
const res = await rpc.query({
|
||||||
|
model: "access.management",
|
||||||
|
method: "get_hidden_field",
|
||||||
|
args: ["", this?.env?.searchModel?.config?.modelName],
|
||||||
|
});
|
||||||
|
debugger
|
||||||
|
this.fields = this.fields.filter((ele) => !res.includes(ele.name));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
@ -2,55 +2,60 @@ odoo.define('simplify_access_management.hide_chatter', function (require) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var FormRenderer = require('web.FormRenderer');
|
var FormRenderer = require('web.FormRenderer');
|
||||||
var Session = require("web.Session");
|
var session = require("web.Session");
|
||||||
var rpc = require('web.rpc');
|
var rpc = require('web.rpc');
|
||||||
|
|
||||||
FormRenderer.include({
|
FormRenderer.include({
|
||||||
_render: function () {
|
_render: async function () {
|
||||||
const res = this._super.apply(this, arguments);
|
const res = await this._super.apply(this, arguments);
|
||||||
const self = this;
|
const self = this;
|
||||||
// this._super.apply(this, arguments);
|
// this._super.apply(this, arguments);
|
||||||
|
var hash = window.location.hash.replace("#", '').split("&");
|
||||||
var hash = window.location.hash.substring(1);
|
let cids;
|
||||||
hash = JSON.parse('{"' + hash.replace(/&/g, '","').replace(/=/g,'":"') + '"}', function(key, value) { return key===""?value:decodeURIComponent(value) })
|
if(hash.findIndex(ele => ele.includes("cid")) == -1)
|
||||||
if(!hash.cids) {
|
cids = session.company_id;
|
||||||
const session = this.getSession();
|
else {
|
||||||
hash.cids = String(session.company_id);
|
cids = hash.filter(ele => ele.includes("cid"))[0].split("=")[1].split(",");
|
||||||
|
cids = cids.length > 0? parseInt(cids[0]): session.company_id;
|
||||||
}
|
}
|
||||||
rpc.query({
|
let model = hash.filter(ele=>ele.includes("model"))?.[0];
|
||||||
model:'access.management',
|
model = model? model.split("=")?.[1].split(",")?.[0]: model;
|
||||||
method: 'get_chatter_hide_details',
|
if(cids && model) {
|
||||||
args: [parseInt(hash.cids.charAt(0)), hash.model]
|
rpc.query({
|
||||||
}).then(function(result){
|
model:'access.management',
|
||||||
if(result['hide_send_mail'] == false)
|
method: 'get_chatter_hide_details',
|
||||||
{
|
args: [cids, model]
|
||||||
var btn1 = setInterval(function() {
|
}).then(function(result){
|
||||||
if ($('.o_ChatterTopbar_buttonSendMessage').length) {
|
if(result['hide_send_mail'] == false)
|
||||||
$('.o_ChatterTopbar_buttonSendMessage').remove();
|
{
|
||||||
clearInterval(btn1);
|
var btn1 = setInterval(function() {
|
||||||
}
|
if ($('.o_ChatterTopbar_buttonSendMessage').length) {
|
||||||
}, 50);
|
$('.o_ChatterTopbar_buttonSendMessage').remove();
|
||||||
}
|
clearInterval(btn1);
|
||||||
if(result['hide_log_notes'] == false)
|
}
|
||||||
{
|
}, 50);
|
||||||
var btn2 = setInterval(function() {
|
}
|
||||||
if ($('.o_ChatterTopbar_buttonLogNote').length) {
|
if(result['hide_log_notes'] == false)
|
||||||
$('.o_ChatterTopbar_buttonLogNote').remove();
|
{
|
||||||
clearInterval(btn2);
|
var btn2 = setInterval(function() {
|
||||||
}
|
if ($('.o_ChatterTopbar_buttonLogNote').length) {
|
||||||
}, 50);
|
$('.o_ChatterTopbar_buttonLogNote').remove();
|
||||||
}
|
clearInterval(btn2);
|
||||||
if(result['hide_schedule_activity'] == false)
|
}
|
||||||
{
|
}, 50);
|
||||||
var btn3 = setInterval(function() {
|
}
|
||||||
if ($('.o_ChatterTopbar_buttonScheduleActivity').length) {
|
if(result['hide_schedule_activity'] == false)
|
||||||
$('.o_ChatterTopbar_buttonScheduleActivity').remove();
|
{
|
||||||
clearInterval(btn3);
|
var btn3 = setInterval(function() {
|
||||||
}
|
if ($('.o_ChatterTopbar_buttonScheduleActivity').length) {
|
||||||
}, 50);
|
$('.o_ChatterTopbar_buttonScheduleActivity').remove();
|
||||||
}
|
clearInterval(btn3);
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ odoo.define('simplify_access_management.hide_export', function (require) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var ListRenderer = require('web.ListRenderer');
|
var ListRenderer = require('web.ListRenderer');
|
||||||
var session
|
var session = require("web.Session");
|
||||||
var rpc = require('web.rpc');
|
var rpc = require('web.rpc');
|
||||||
|
|
||||||
ListRenderer.include({
|
ListRenderer.include({
|
||||||
|
|
@ -10,30 +10,34 @@ odoo.define('simplify_access_management.hide_export', function (require) {
|
||||||
_render: function () {
|
_render: function () {
|
||||||
const res = this._super.apply(this, arguments);
|
const res = this._super.apply(this, arguments);
|
||||||
const self = this;
|
const self = this;
|
||||||
// this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
|
|
||||||
var hash = window.location.hash.substring(1);
|
var hash = window.location.hash.replace("#", '').split("&");
|
||||||
hash = JSON.parse('{"' + hash.replace(/&/g, '","').replace(/=/g,'":"') + '"}', function(key, value) { return key===""?value:decodeURIComponent(value) })
|
let cids;
|
||||||
if(!hash.cids) {
|
if(hash.findIndex(ele => ele.includes("cid")) == -1)
|
||||||
const session = this.getSession();
|
cids = session.company_id;
|
||||||
hash.cids = String(session.company_id);
|
else {
|
||||||
|
cids = hash.filter(ele => ele.includes("cid"))[0].split("=")[1].split(",");
|
||||||
|
cids = cids.length > 0? parseInt(cids[0]): session.company_id;
|
||||||
|
}
|
||||||
|
let model = hash.filter(ele=>ele.includes("model"))?.[0];
|
||||||
|
model = model? model.split("=")?.[1].split(",")?.[0]: model;
|
||||||
|
if(cids && model) {
|
||||||
|
rpc.query({
|
||||||
|
model:'access.management',
|
||||||
|
method: 'is_export_hide',
|
||||||
|
args: [cids, model]
|
||||||
|
}).then(function(result){
|
||||||
|
if(result) {
|
||||||
|
var btn1 = setInterval(function() {
|
||||||
|
if ($('.o_list_export_xlsx').length) {
|
||||||
|
$('.o_list_export_xlsx').remove();
|
||||||
|
clearInterval(btn1);
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
rpc.query({
|
|
||||||
model:'access.management',
|
|
||||||
method: 'is_export_hide',
|
|
||||||
args: [parseInt(hash.cids.charAt(0)), hash.model]
|
|
||||||
}).then(function(result){
|
|
||||||
debugger
|
|
||||||
if(result) {
|
|
||||||
debugger
|
|
||||||
var btn1 = setInterval(function() {
|
|
||||||
if ($('.o_list_export_xlsx').length) {
|
|
||||||
$('.o_list_export_xlsx').remove();
|
|
||||||
clearInterval(btn1);
|
|
||||||
}
|
|
||||||
}, 50);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
odoo.define(
|
||||||
|
"simpily_access_management.pivot_renderer_patch",
|
||||||
|
function (require) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const { patch } = require("web.utils");
|
||||||
|
const PivotRenderer = require("web.PivotRenderer");
|
||||||
|
var rpc = require("web.rpc");
|
||||||
|
|
||||||
|
patch(PivotRenderer, "PivotRendererHideFieldPatch", {
|
||||||
|
async _updateTooltip() {
|
||||||
|
await this._super(...arguments);
|
||||||
|
const res = await rpc.query({
|
||||||
|
model: "access.management",
|
||||||
|
method: "get_hidden_field",
|
||||||
|
args: ["", this?.props?.modelName],
|
||||||
|
});
|
||||||
|
this.props.selectionGroupBys = this.props.selectionGroupBys.filter(
|
||||||
|
(ele) => !res.includes(ele.name)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
@ -49,7 +49,6 @@ odoo.define("advanced_web_domain_widget.DomainSelector", function (require) {
|
||||||
if (!this.readonly) {
|
if (!this.readonly) {
|
||||||
// Set list of operators according to field type
|
// Set list of operators according to field type
|
||||||
this.displayValue = this.value;
|
this.displayValue = this.value;
|
||||||
debugger
|
|
||||||
this.operators = this._getOperatorsFromType(selectedField.type, selectedField.name);
|
this.operators = this._getOperatorsFromType(selectedField.type, selectedField.name);
|
||||||
if (_.contains(["child_of", "parent_of", "like", "not like", "=like", "=ilike"], this.operator)) {
|
if (_.contains(["child_of", "parent_of", "like", "not like", "=like", "=ilike"], this.operator)) {
|
||||||
// In case user entered manually or from demo data
|
// In case user entered manually or from demo data
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
<record id="access_management_form_view_ah" model="ir.ui.view">
|
<record id="access_management_form_view_ah" model="ir.ui.view">
|
||||||
<field name="name">access_management_form_view_ah</field>
|
<field name="name">access_management_form_view_ah</field>
|
||||||
<field name="groups_id" eval="[(4, ref('group_access_management_spt'))]"/>
|
<field name="groups_id" eval="[(4, ref('group_access_management_bits'))]"/>
|
||||||
<field name="model">access.management</field>
|
<field name="model">access.management</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<form>
|
<form>
|
||||||
|
|
@ -40,6 +40,7 @@
|
||||||
<group>
|
<group>
|
||||||
<field name="name" default_focus="1" required='1'/>
|
<field name="name" default_focus="1" required='1'/>
|
||||||
<field name="readonly"/>
|
<field name="readonly"/>
|
||||||
|
<field name="is_apply_on_without_company"/>
|
||||||
<field name="company_ids" options="{'no_create': True}" widget="many2many_tags"
|
<field name="company_ids" options="{'no_create': True}" widget="many2many_tags"
|
||||||
groups="base.group_multi_company"/>
|
groups="base.group_multi_company"/>
|
||||||
<field name="self_model_ids" widget="many2many_tags" invisible="1"/>
|
<field name="self_model_ids" widget="many2many_tags" invisible="1"/>
|
||||||
|
|
@ -130,15 +131,17 @@
|
||||||
<!-- <field name="model_id" options="{'no_create': True}" domain="[('id','not in',parent.self_model_ids),('abstract','=',False)]" /> -->
|
<!-- <field name="model_id" options="{'no_create': True}" domain="[('id','not in',parent.self_model_ids),('abstract','=',False)]" /> -->
|
||||||
<field name="model_id" context="{'is_access_rights': True}"
|
<field name="model_id" context="{'is_access_rights': True}"
|
||||||
options="{'no_open': True, 'no_create': True, 'no_create_edit': True}"
|
options="{'no_open': True, 'no_create': True, 'no_create_edit': True}"
|
||||||
required='1' domain="[('id','not in',parent.self_model_ids)]"/>
|
required='1' domain="[('id','not in',parent.self_model_ids)]"
|
||||||
|
width='10'/>
|
||||||
<field name="field_id" context="{'is_access_rights': True}"
|
<field name="field_id" context="{'is_access_rights': True}"
|
||||||
options="{'no_open': True, 'no_create': True, 'no_create_edit': True}"
|
options="{'no_open': True, 'no_create': True, 'no_create_edit': True}"
|
||||||
widget='many2many_tags' domain="[('model_id','=',model_id)]"/>
|
widget='many2many_tags' domain="[('model_id','=',model_id)]"
|
||||||
<field name="invisible" width='1'/>
|
width='10'/>
|
||||||
<field name="readonly" width='1'
|
<field name="invisible" width='10'/>
|
||||||
|
<field name="readonly" width='10'
|
||||||
attrs="{'column_invisible' : [('parent.readonly','=',True)]}"/>
|
attrs="{'column_invisible' : [('parent.readonly','=',True)]}"/>
|
||||||
<field name="required" width='1'/>
|
<field name="required" width='10'/>
|
||||||
<field name="external_link" width='1'/>
|
<field name="external_link" width='10'/>
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
<p role="alert"
|
<p role="alert"
|
||||||
|
|
@ -189,12 +192,12 @@
|
||||||
</sheet>
|
</sheet>
|
||||||
</form>
|
</form>
|
||||||
<tree>
|
<tree>
|
||||||
<field name="model_id"/>
|
<field name="model_id" width='10'/>
|
||||||
<field name="domain"/>
|
<field name="domain" width='10'/>
|
||||||
<field name="read_right"/>
|
<field name="read_right" width='10'/>
|
||||||
<field name="create_right"/>
|
<field name="create_right" width='10'/>
|
||||||
<field name="write_right"/>
|
<field name="write_right" width='10'/>
|
||||||
<field name="delete_right"/>
|
<field name="delete_right" width='10'/>
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
<p role="alert"
|
<p role="alert"
|
||||||
|
|
@ -366,7 +369,7 @@
|
||||||
|
|
||||||
<record id="access_management_tree_view_ah" model="ir.ui.view">
|
<record id="access_management_tree_view_ah" model="ir.ui.view">
|
||||||
<field name="name">access_management_tree_view_ah</field>
|
<field name="name">access_management_tree_view_ah</field>
|
||||||
<field name="groups_id" eval="[(4, ref('group_access_management_spt'))]"/>
|
<field name="groups_id" eval="[(4, ref('group_access_management_bits'))]"/>
|
||||||
<field name="model">access.management</field>
|
<field name="model">access.management</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree decoration-muted="(not active)">
|
<tree decoration-muted="(not active)">
|
||||||
|
|
@ -389,8 +392,8 @@
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<menuitem id="main_menu_simplify_access_management" name="Access Studio" action="action_access_management_ah"
|
<menuitem id="main_menu_simplify_access_management" name="Access Studio" action="action_access_management_ah"
|
||||||
groups="group_access_management_spt"
|
groups="group_access_management_bits"
|
||||||
/>
|
web_icon="simplify_access_management,static/description/icon.png"/>
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,15 @@
|
||||||
<template id="assets_backend" name="simplify_access_management_view assets" inherit_id="web.assets_backend">
|
<template id="assets_backend" name="simplify_access_management_view assets" inherit_id="web.assets_backend">
|
||||||
<xpath expr="." position="inside">
|
<xpath expr="." position="inside">
|
||||||
<script type="text/javascript" src="/simplify_access_management/static/src/js/action_items.js"></script>
|
<script type="text/javascript" src="/simplify_access_management/static/src/js/action_items.js"></script>
|
||||||
<script type="text/javascript" src="/simplify_access_management/static/src/js/widget/DomainSelector.js"></script>
|
<!-- <script type="text/javascript" src="/simplify_access_management/static/src/js/widget/DomainSelector.js"></script>
|
||||||
<script type="text/javascript" src="/simplify_access_management/static/src/js/widget/ModelRecordSelector.js"></script>
|
<script type="text/javascript" src="/simplify_access_management/static/src/js/widget/ModelRecordSelector.js"></script> -->
|
||||||
<script type="text/javascript" src="/simplify_access_management/static/src/js/data_manager.js"></script>
|
<script type="text/javascript" src="/simplify_access_management/static/src/js/data_manager.js"></script>
|
||||||
<script type="text/javascript" src="/simplify_access_management/static/src/js/action_manager.js"></script>
|
<script type="text/javascript" src="/simplify_access_management/static/src/js/action_manager.js"></script>
|
||||||
<script type="text/javascript" src="/simplify_access_management/static/src/js/hide_chatter.js"></script>
|
<script type="text/javascript" src="/simplify_access_management/static/src/js/hide_chatter.js"></script>
|
||||||
<script type="text/javascript" src="/simplify_access_management/static/src/js/hide_export.js"></script>
|
<script type="text/javascript" src="/simplify_access_management/static/src/js/hide_export.js"></script>
|
||||||
|
<script type="text/javascript" src="/simplify_access_management/static/src/js/pivot_renderer_patch.js"></script>
|
||||||
|
<script type="text/javascript" src="/simplify_access_management/static/src/js/custom_filter_item.js"></script>
|
||||||
|
<script type="text/javascript" src="/simplify_access_management/static/src/js/groupby_menu.js"></script>
|
||||||
</xpath>
|
</xpath>
|
||||||
</template>
|
</template>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
<field name="inherit_id" ref="base.view_users_form"/>
|
<field name="inherit_id" ref="base.view_users_form"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<xpath expr="//notebook" position="inside">
|
<xpath expr="//notebook" position="inside">
|
||||||
<page string='Access Management' groups="simplify_access_management.group_access_management_spt">
|
<page string='Access Management' groups="simplify_access_management.group_access_management_bits">
|
||||||
<field name='access_management_ids'>
|
<field name='access_management_ids'>
|
||||||
<tree>
|
<tree>
|
||||||
<field name="name" />
|
<field name="name" />
|
||||||
|
|
|
||||||