mirror of https://github.com/OCA/web.git
commit
6741af5986
|
@ -0,0 +1,22 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# This module copyright (C) 2014 Therp BV (<http://therp.nl>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from . import model
|
||||
from . import wizard
|
|
@ -0,0 +1,79 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# This module copyright (C) 2014 Therp BV (<http://therp.nl>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
{
|
||||
"name": "Advanced filters",
|
||||
"version": "1.0",
|
||||
"author": "Therp BV",
|
||||
"license": "AGPL-3",
|
||||
"complexity": "normal",
|
||||
"description": """
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This addon allows users to apply set operations on filters: Remove or add
|
||||
certain ids from/to a selection, but also to remove or add another filter's
|
||||
outcome from/to a filter. This can be stacked, so the filter domain can be
|
||||
arbitrarily complicated.
|
||||
|
||||
The math is hidden from the user as far as possible, in the hope it's still
|
||||
user friendly.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
After this addon is installed, every list view shows a new menu 'Advanced
|
||||
filters'. Here the set operations can be applied as necessary.
|
||||
|
||||
Caution
|
||||
-------
|
||||
|
||||
Deinstalling this module will leave you with filters with empty domains. Use
|
||||
this query before uninstalling to avoid that:
|
||||
|
||||
``alter table ir_filters rename domain_this to domain``
|
||||
""",
|
||||
"category": "Tools",
|
||||
"depends": [
|
||||
'base',
|
||||
'web',
|
||||
],
|
||||
"data": [
|
||||
"data/migration.xml",
|
||||
"wizard/ir_filters_combine_with_existing.xml",
|
||||
"view/ir_filters.xml",
|
||||
],
|
||||
"js": [
|
||||
'static/src/js/web_advanced_filters.js',
|
||||
],
|
||||
"css": [
|
||||
'static/src/css/web_advanced_filters.css',
|
||||
],
|
||||
"qweb": [
|
||||
],
|
||||
"test": [
|
||||
],
|
||||
"auto_install": False,
|
||||
"installable": True,
|
||||
"application": False,
|
||||
"external_dependencies": {
|
||||
'python': [],
|
||||
},
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
<function name="_migrate_name_change" model="ir.filters" />
|
||||
</data>
|
||||
</openerp>
|
|
@ -0,0 +1,195 @@
|
|||
# Translation of OpenERP Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * web_advanced_filters
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 7.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2014-07-29 10:55+0000\n"
|
||||
"PO-Revision-Date: 2014-07-29 10:55+0000\n"
|
||||
"Last-Translator: <>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters:0
|
||||
msgid "Save filter"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: selection:ir.filters.combine.with.existing,action:0
|
||||
msgid "Union"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters:0
|
||||
msgid "Add the result of following filters"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters:0
|
||||
#: view:ir.filters.combine.with.existing:0
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters:0
|
||||
msgid "Freeze filter"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#. openerp-web
|
||||
#: code:addons/web_advanced_filters/static/src/js/web_advanced_filters.js:94
|
||||
#: code:addons/web_advanced_filters/static/src/js/web_advanced_filters.js:114
|
||||
#, python-format
|
||||
msgid "Remove from existing selection"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: code:addons/web_advanced_filters/model/ir_filters.py:131
|
||||
#, python-format
|
||||
msgid "Testing %s"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters:0
|
||||
#: view:ir.filters.combine.with.existing:0
|
||||
msgid "or"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: field:ir.filters,complement_filter_ids:0
|
||||
msgid "Remove result of filters"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#. openerp-web
|
||||
#: code:addons/web_advanced_filters/static/src/js/web_advanced_filters.js:86
|
||||
#: code:addons/web_advanced_filters/static/src/js/web_advanced_filters.js:106
|
||||
#, python-format
|
||||
msgid "To existing selection"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters.combine.with.existing:0
|
||||
msgid "Combine with existing filter"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters:0
|
||||
msgid "Have this filter contain extly the records it currently contains, with no changes in the future. Be careful, you can't undo this operation!"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#. openerp-web
|
||||
#: code:addons/web_advanced_filters/static/src/js/web_advanced_filters.js:32
|
||||
#, python-format
|
||||
msgid "Advanced filters"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: field:ir.filters,active:0
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#. openerp-web
|
||||
#: code:addons/web_advanced_filters/static/src/js/web_advanced_filters.js:74
|
||||
#, python-format
|
||||
msgid "Marked records"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: field:ir.filters,is_frozen:0
|
||||
msgid "Frozen"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: field:ir.filters.combine.with.existing,filter_id:0
|
||||
msgid "Filter"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters:0
|
||||
msgid "Test filter"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#. openerp-web
|
||||
#: code:addons/web_advanced_filters/static/src/js/web_advanced_filters.js:78
|
||||
#, python-format
|
||||
msgid "To new selection"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: field:ir.filters,domain_this:0
|
||||
msgid "This filter's own domain"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters:0
|
||||
msgid "Remove the result of following filters"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: field:ir.filters.combine.with.existing,context:0
|
||||
msgid "Context"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: field:ir.filters.combine.with.existing,action:0
|
||||
msgid "Action"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: field:ir.filters.combine.with.existing,model:0
|
||||
msgid "Model"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: field:ir.filters.combine.with.existing,domain:0
|
||||
msgid "Domain"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: field:ir.filters,union_filter_ids:0
|
||||
msgid "Add result of filters"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: model:ir.model,name:web_advanced_filters.model_ir_filters_combine_with_existing
|
||||
msgid "Combine a selection with an existing filter"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters:0
|
||||
msgid "Are you sure? You can't undo this operation!"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: model:ir.model,name:web_advanced_filters.model_ir_filters
|
||||
msgid "Filters"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters:0
|
||||
#: view:ir.filters.combine.with.existing:0
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#. openerp-web
|
||||
#: code:addons/web_advanced_filters/static/src/js/web_advanced_filters.js:102
|
||||
#, python-format
|
||||
msgid "Whole selection"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: selection:ir.filters.combine.with.existing,action:0
|
||||
msgid "Complement"
|
||||
msgstr ""
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
# This file contains the translation of the following modules:
|
||||
# * web_advanced_filters
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 7.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2014-07-29 09:54+0000\n"
|
||||
"PO-Revision-Date: 2014-07-29 09:54+0000\n"
|
||||
"Last-Translator: <>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters:0
|
||||
msgid "Save filter"
|
||||
msgstr "Opslaan filter"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: selection:ir.filters.combine.with.existing,action:0
|
||||
msgid "Union"
|
||||
msgstr "Union"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters:0
|
||||
msgid "Add the result of following filters"
|
||||
msgstr "Voeg resultaat van onderstaande filteringen toe aan filter"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters:0
|
||||
#: view:ir.filters.combine.with.existing:0
|
||||
msgid "Save"
|
||||
msgstr "Opslaan"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters:0
|
||||
msgid "Freeze filter"
|
||||
msgstr "Bevries filter"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#. openerp-web
|
||||
#: code:addons/web_advanced_filters/static/src/js/web_advanced_filters.js:94
|
||||
#: code:addons/web_advanced_filters/static/src/js/web_advanced_filters.js:114
|
||||
#, python-format
|
||||
msgid "Remove from existing filter"
|
||||
msgstr "Verwijder uit bestaand filter"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: code:addons/web_advanced_filters/model/ir_filters.py:131
|
||||
#, python-format
|
||||
msgid "Testing %s"
|
||||
msgstr "Testen %s"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters:0
|
||||
#: view:ir.filters.combine.with.existing:0
|
||||
msgid "or"
|
||||
msgstr "or"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: field:ir.filters,complement_filter_ids:0
|
||||
msgid "Remove result of filters"
|
||||
msgstr "Verwijder resultaat van filters"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#. openerp-web
|
||||
#: code:addons/web_advanced_filters/static/src/js/web_advanced_filters.js:86
|
||||
#: code:addons/web_advanced_filters/static/src/js/web_advanced_filters.js:106
|
||||
#, python-format
|
||||
msgid "To existing filter"
|
||||
msgstr "Voeg toe aan bestaand filter"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters.combine.with.existing:0
|
||||
msgid "Combine with existing filter"
|
||||
msgstr "Combineer met bestaande filter"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters:0
|
||||
msgid "Have this filter contain exactly the records it currently contains, with no changes in the future. Be careful, you can't undo this operation!"
|
||||
msgstr "Laat deze filter precies deze records bevatten, zonder veranderingen in de toekomst. Wees voorzichtig, je kan dit niet meer veranderen!"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#. openerp-web
|
||||
#: code:addons/web_advanced_filters/static/src/js/web_advanced_filters.js:32
|
||||
#, python-format
|
||||
msgid "Advanced filters"
|
||||
msgstr "Geavanceerde filters"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: field:ir.filters,active:0
|
||||
msgid "Active"
|
||||
msgstr "Actief"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#. openerp-web
|
||||
#: code:addons/web_advanced_filters/static/src/js/web_advanced_filters.js:74
|
||||
#, python-format
|
||||
msgid "Marked records"
|
||||
msgstr "Aangevinkte records (verzameling)"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: field:ir.filters,is_frozen:0
|
||||
msgid "Frozen"
|
||||
msgstr "Bevroren"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: field:ir.filters.combine.with.existing,filter_id:0
|
||||
msgid "Filter"
|
||||
msgstr "Filter"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters:0
|
||||
msgid "Test filter"
|
||||
msgstr "Test filter"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#. openerp-web
|
||||
#: code:addons/web_advanced_filters/static/src/js/web_advanced_filters.js:78
|
||||
#, python-format
|
||||
msgid "To new filter"
|
||||
msgstr "Opslaan als nieuw filter"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: field:ir.filters,domain_this:0
|
||||
msgid "This filter's own domain"
|
||||
msgstr "Deze filters eigen domein"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters:0
|
||||
msgid "Remove the result of following filters"
|
||||
msgstr "Verwijder resultaat van onderstaande filteringen uit filter"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: field:ir.filters.combine.with.existing,context:0
|
||||
msgid "Context"
|
||||
msgstr "Context"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: field:ir.filters.combine.with.existing,action:0
|
||||
msgid "Action"
|
||||
msgstr "Actie"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: field:ir.filters.combine.with.existing,model:0
|
||||
msgid "Model"
|
||||
msgstr "Model"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#. openerp-web
|
||||
#: code:addons/web_advanced_filters/static/src/js/web_advanced_filters.js:102
|
||||
#, python-format
|
||||
msgid "Whole selection (criteria)"
|
||||
msgstr "Alle records (als criteria)"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: field:ir.filters.combine.with.existing,domain:0
|
||||
msgid "Domain"
|
||||
msgstr "Domein"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: field:ir.filters,union_filter_ids:0
|
||||
msgid "Add result of filters"
|
||||
msgstr "Voeg resultaat toe aan filters"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: model:ir.model,name:web_advanced_filters.model_ir_filters_combine_with_existing
|
||||
msgid "Combine a selection with an existing filter"
|
||||
msgstr "Combineer een selectie met een bestaande filter"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters:0
|
||||
msgid "Are you sure? You can't undo this operation!"
|
||||
msgstr "Weet u het zeker? U kan deze operatie niet meer ongedaan maken"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: model:ir.model,name:web_advanced_filters.model_ir_filters
|
||||
msgid "Filters"
|
||||
msgstr "Filters"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: view:ir.filters:0
|
||||
#: view:ir.filters.combine.with.existing:0
|
||||
msgid "Cancel"
|
||||
msgstr "Annuleren"
|
||||
|
||||
#. module: web_advanced_filters
|
||||
#: selection:ir.filters.combine.with.existing,action:0
|
||||
msgid "Complement"
|
||||
msgstr "Aanvullen"
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# This module copyright (C) 2014 Therp BV (<http://therp.nl>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from . import ir_filters
|
|
@ -0,0 +1,175 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# This module copyright (C) 2014 Therp BV (<http://therp.nl>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
import itertools
|
||||
from openerp.osv.orm import Model
|
||||
from openerp.osv import fields, expression
|
||||
from openerp.tools.safe_eval import safe_eval
|
||||
from openerp.tools.translate import _
|
||||
|
||||
|
||||
class IrFilters(Model):
|
||||
_inherit = 'ir.filters'
|
||||
|
||||
def _is_frozen_get(self, cr, uid, ids, field_name, args, context=None):
|
||||
'''determine if this is fixed list of ids'''
|
||||
result = {}
|
||||
for this in self.browse(cr, uid, ids, context=context):
|
||||
try:
|
||||
domain = safe_eval(this.domain)
|
||||
except:
|
||||
domain = [expression.FALSE_LEAF]
|
||||
result[this.id] = (len(domain) == 1 and
|
||||
expression.is_leaf(domain[0]) and
|
||||
domain[0][0] == 'id')
|
||||
return result
|
||||
|
||||
def _domain_get(self, cr, uid, ids, field_name, args, context=None):
|
||||
'''combine our domain with all domains to union/complement,
|
||||
this works recursively'''
|
||||
def eval_n(domain):
|
||||
'''parse a domain and normalize it'''
|
||||
try:
|
||||
domain = safe_eval(domain)
|
||||
except:
|
||||
domain = [expression.FALSE_LEAF]
|
||||
return expression.normalize_domain(
|
||||
domain or [expression.FALSE_LEAF])
|
||||
|
||||
result = {}
|
||||
for this in self.read(
|
||||
cr, uid, ids,
|
||||
['domain_this', 'union_filter_ids', 'complement_filter_ids'],
|
||||
context=context):
|
||||
domain = eval_n(this['domain_this'])
|
||||
domain = expression.OR(
|
||||
[domain] +
|
||||
[eval_n(u['domain']) for u in self.read(
|
||||
cr, uid, this['union_filter_ids'], ['domain'],
|
||||
context=context)])
|
||||
for c in self.read(cr, uid, this['complement_filter_ids'],
|
||||
['domain'], context=context):
|
||||
domain = expression.AND([
|
||||
domain,
|
||||
['!'] + eval_n(c['domain'])])
|
||||
result[this['id']] = str(domain)
|
||||
return result
|
||||
|
||||
def _domain_set(self, cr, uid, ids, field_name, field_value, args,
|
||||
context=None):
|
||||
self.write(cr, uid, ids, {'domain_this': field_value})
|
||||
|
||||
_columns = {
|
||||
'is_frozen': fields.function(
|
||||
_is_frozen_get, type='boolean', string='Frozen'),
|
||||
'union_filter_ids': fields.many2many(
|
||||
'ir.filters', 'ir_filters_union_rel', 'left_filter_id',
|
||||
'right_filter_id', 'Add result of filters',
|
||||
domain=['|', ('active', '=', False), ('active', '=', True)]),
|
||||
'complement_filter_ids': fields.many2many(
|
||||
'ir.filters', 'ir_filters_complement_rel', 'left_filter_id',
|
||||
'right_filter_id', 'Remove result of filters',
|
||||
domain=['|', ('active', '=', False), ('active', '=', True)]),
|
||||
'active': fields.boolean('Active'),
|
||||
'domain': fields.function(
|
||||
_domain_get, type='text', string='Domain',
|
||||
fnct_inv=_domain_set),
|
||||
'domain_this': fields.text(
|
||||
'This filter\'s own domain', oldname='domain'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'active': True,
|
||||
}
|
||||
|
||||
def _evaluate(self, cr, uid, ids, context=None):
|
||||
assert len(ids) == 1
|
||||
this = self.browse(cr, uid, ids[0], context=context)
|
||||
return self.pool[this.model_id].search(
|
||||
cr, uid, safe_eval(this.domain), context=safe_eval(this.context))
|
||||
|
||||
def button_save(self, cr, uid, ids, context=None):
|
||||
return {'type': 'ir.actions.act_window.close'}
|
||||
|
||||
def button_freeze(self, cr, uid, ids, context=None):
|
||||
'''evaluate the filter and write a fixed [('id', 'in', [])] domain'''
|
||||
for this in self.browse(cr, uid, ids, context=context):
|
||||
ids = this._evaluate()
|
||||
removed_filter_ids = [f.id for f in itertools.chain(
|
||||
this.union_filter_ids, this.complement_filter_ids)]
|
||||
this.write({
|
||||
'domain': str([('id', 'in', ids)]),
|
||||
'union_filter_ids': [(6, 0, [])],
|
||||
'complement_filter_ids': [(6, 0, [])],
|
||||
})
|
||||
# if we removed inactive filters which are orphaned now, delete
|
||||
# them
|
||||
cr.execute('''delete from ir_filters
|
||||
where
|
||||
not active and id in %s
|
||||
and not exists (select right_filter_id
|
||||
from ir_filters_union_rel where left_filter_id=id)
|
||||
and not exists (select right_filter_id
|
||||
from ir_filters_complement_rel where
|
||||
left_filter_id=id)
|
||||
''',
|
||||
(tuple(removed_filter_ids),))
|
||||
|
||||
def button_test(self, cr, uid, ids, context=None):
|
||||
for this in self.browse(cr, uid, ids, context=context):
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': _('Testing %s') % this.name,
|
||||
'res_model': this.model_id,
|
||||
'domain': this.domain,
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree',
|
||||
'context': {
|
||||
'default_filter_id': this.id,
|
||||
},
|
||||
}
|
||||
|
||||
def _auto_init(self, cr, context=None):
|
||||
cr.execute(
|
||||
'SELECT count(attname) FROM pg_attribute '
|
||||
'WHERE attrelid = '
|
||||
'( SELECT oid FROM pg_class WHERE relname = %s) '
|
||||
'AND attname = %s', (self._table, 'domain_this'))
|
||||
if not cr.fetchone()[0]:
|
||||
cr.execute(
|
||||
'ALTER table %s RENAME domain TO domain_this' % self._table)
|
||||
return super(IrFilters, self)._auto_init(cr, context=context)
|
||||
|
||||
def _migrate_name_change(self, cr, uid, context=None):
|
||||
cr.execute(
|
||||
"select id from ir_module_module where name='advanced_filters' "
|
||||
"and author='Therp BV'")
|
||||
old_name_installed = cr.fetchall()
|
||||
if not old_name_installed:
|
||||
return
|
||||
cr.execute(
|
||||
"delete from ir_model_data where module='web_advanced_filters'")
|
||||
cr.execute(
|
||||
"update ir_model_data set module='web_advanced_filters' "
|
||||
"where module='advanced_filters'")
|
||||
cr.execute(
|
||||
"update ir_module_module set state='to remove' where "
|
||||
"name='advanced_filters' and state not in "
|
||||
"('uninstalled', 'to remove')")
|
|
@ -0,0 +1,14 @@
|
|||
li.oe_advanced_filters_header
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
.openerp .oe_dropdown_menu > li.oe_advanced_filters_header:hover
|
||||
{
|
||||
background-color: inherit;
|
||||
background-image: inherit;
|
||||
box-shadow: none;
|
||||
}
|
||||
.openerp .oe_dropdown_menu > li.oe_advanced_filters_header a:hover
|
||||
{
|
||||
cursor: default !important;
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
|
@ -0,0 +1,270 @@
|
|||
//-*- coding: utf-8 -*-
|
||||
//############################################################################
|
||||
//
|
||||
// OpenERP, Open Source Management Solution
|
||||
// This module copyright (C) 2014 Therp BV (<http://therp.nl>).
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//############################################################################
|
||||
|
||||
openerp.web_advanced_filters = function(instance)
|
||||
{
|
||||
var _t = instance.web._t;
|
||||
|
||||
instance.web.Sidebar.include({
|
||||
init: function()
|
||||
{
|
||||
var result = this._super.apply(this, arguments);
|
||||
this.sections.push({
|
||||
'name': 'advanced_filters',
|
||||
'label': _t('Advanced filters'),
|
||||
});
|
||||
this.items.advanced_filters = [];
|
||||
return result;
|
||||
},
|
||||
});
|
||||
instance.web.ListView.include({
|
||||
do_select: function (ids, records)
|
||||
{
|
||||
var result = this._super(this, arguments);
|
||||
this.advanced_filters_show(ids);
|
||||
return result;
|
||||
},
|
||||
load_list: function(data)
|
||||
{
|
||||
var result = this._super.apply(this, arguments),
|
||||
self = this;
|
||||
if(!this.sidebar || this.sidebar.items.advanced_filters.length)
|
||||
{
|
||||
this.advanced_filters_show([]);
|
||||
return result;
|
||||
}
|
||||
this.sidebar.add_items(
|
||||
'advanced_filters',
|
||||
[
|
||||
{
|
||||
label: _t('Whole selection (criteria)'),
|
||||
classname: 'oe_advanced_filters_header',
|
||||
},
|
||||
{
|
||||
label: _t('To new filter'),
|
||||
callback: function ()
|
||||
{
|
||||
self.advanced_filters_save_criteria.apply(
|
||||
self, arguments);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: _t('To existing filter'),
|
||||
callback: function (item)
|
||||
{
|
||||
self.advanced_filters_combine_with_existing.apply(
|
||||
self, ['union', 'domain', item]);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: _t('Remove from existing filter'),
|
||||
callback: function (item)
|
||||
{
|
||||
self.advanced_filters_combine_with_existing.apply(
|
||||
self, ['complement', 'domain', item]);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: _t('Marked records'),
|
||||
classname: 'oe_advanced_filters_header',
|
||||
},
|
||||
{
|
||||
label: _t('To new filter'),
|
||||
callback: function ()
|
||||
{
|
||||
self.advanced_filters_save_selection.apply(
|
||||
self, arguments);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: _t('To existing filter'),
|
||||
callback: function (item)
|
||||
{
|
||||
self.advanced_filters_combine_with_existing.apply(
|
||||
self, ['union', 'ids', item]);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: _t('Remove from existing filter'),
|
||||
callback: function (item)
|
||||
{
|
||||
self.advanced_filters_combine_with_existing.apply(
|
||||
self, ['complement', 'ids', item]);
|
||||
},
|
||||
},
|
||||
]
|
||||
);
|
||||
this.do_select([], []);
|
||||
return result;
|
||||
},
|
||||
advanced_filters_show: function(ids)
|
||||
{
|
||||
var self = this;
|
||||
if(this.sidebar)
|
||||
{
|
||||
this.sidebar.$el.show();
|
||||
this.sidebar.$el.children().children().each(function(i, e)
|
||||
{
|
||||
$e = jQuery(e)
|
||||
if($e.find('li.oe_advanced_filters_header').length)
|
||||
{
|
||||
var search = self.ViewManager.searchview
|
||||
.build_search_data();
|
||||
$e.find('a[data-index="0"],a[data-index="1"],' +
|
||||
'a[data-index="2"],a[data-index="3"]')
|
||||
.parent().toggle(
|
||||
search.contexts.length > 0 ||
|
||||
search.domains.length > 0);
|
||||
$e.find('a[data-index="4"],a[data-index="5"],' +
|
||||
'a[data-index="6"],a[data-index="7"]')
|
||||
.parent().toggle(ids.length > 0);
|
||||
$e.toggle(
|
||||
search.contexts.length > 0 ||
|
||||
search.domains.length > 0 ||
|
||||
ids.length > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
$e.toggle(ids.length > 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
advanced_filters_save_criteria: function(item)
|
||||
{
|
||||
var search = this.ViewManager.searchview.build_search_data(),
|
||||
self = this;
|
||||
instance.web.pyeval.eval_domains_and_contexts({
|
||||
domains: search.domains,
|
||||
contexts: search.contexts,
|
||||
group_by_seq: search.groupbys || []
|
||||
}).done(function(search)
|
||||
{
|
||||
var ctx = search.context;
|
||||
_(_.keys(instance.session.user_context)).each(
|
||||
function (key) {delete ctx[key]});
|
||||
self.do_action({
|
||||
name: item.label,
|
||||
type: 'ir.actions.act_window',
|
||||
res_model: 'ir.filters',
|
||||
views: [[false, 'form']],
|
||||
target: 'new',
|
||||
context: {
|
||||
default_model_id: self.dataset._model.name,
|
||||
default_domain: JSON.stringify(search.domain),
|
||||
default_context: JSON.stringify(ctx),
|
||||
form_view_ref: 'web_advanced_filters.form_ir_filters_save_new',
|
||||
},
|
||||
},
|
||||
{
|
||||
on_close: function()
|
||||
{
|
||||
self.ViewManager.setup_search_view(
|
||||
self.ViewManager.searchview.view_id,
|
||||
self.ViewManager.searchview.defaults);
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
advanced_filters_save_selection: function(item)
|
||||
{
|
||||
var self = this;
|
||||
this.do_action({
|
||||
name: item.label,
|
||||
type: 'ir.actions.act_window',
|
||||
res_model: 'ir.filters',
|
||||
views: [[false, 'form']],
|
||||
target: 'new',
|
||||
context: {
|
||||
default_model_id: this.dataset._model.name,
|
||||
default_domain: JSON.stringify(
|
||||
[
|
||||
['id', 'in', this.groups.get_selection().ids],
|
||||
]
|
||||
),
|
||||
default_context: JSON.stringify({}),
|
||||
form_view_ref: 'web_advanced_filters.form_ir_filters_save_new',
|
||||
},
|
||||
},
|
||||
{
|
||||
on_close: function()
|
||||
{
|
||||
self.ViewManager.setup_search_view(
|
||||
self.ViewManager.searchview.view_id,
|
||||
self.ViewManager.searchview.defaults);
|
||||
},
|
||||
});
|
||||
},
|
||||
advanced_filters_combine_with_existing: function(action, type, item)
|
||||
{
|
||||
var search = this.ViewManager.searchview.build_search_data(),
|
||||
self = this;
|
||||
instance.web.pyeval.eval_domains_and_contexts({
|
||||
domains: search.domains,
|
||||
contexts: search.contexts,
|
||||
group_by_seq: search.groupbys || []
|
||||
}).done(function(search)
|
||||
{
|
||||
var domain = [], ctx = {};
|
||||
switch(type)
|
||||
{
|
||||
case 'domain':
|
||||
domain = search.domain;
|
||||
ctx = search.context;
|
||||
_(_.keys(instance.session.user_context)).each(
|
||||
function (key) {delete ctx[key]});
|
||||
break;
|
||||
case 'ids':
|
||||
domain = [
|
||||
['id', 'in', self.groups.get_selection().ids],
|
||||
]
|
||||
ctx = {};
|
||||
break;
|
||||
}
|
||||
self.do_action({
|
||||
name: item.label,
|
||||
type: 'ir.actions.act_window',
|
||||
res_model: 'ir.filters.combine.with.existing',
|
||||
views: [[false, 'form']],
|
||||
target: 'new',
|
||||
context: _.extend({
|
||||
default_model: self.dataset._model.name,
|
||||
default_domain: JSON.stringify(domain),
|
||||
default_action: action,
|
||||
default_context: JSON.stringify(ctx),
|
||||
},
|
||||
self.dataset.context.default_filter_id ? {
|
||||
default_filter_id:
|
||||
self.dataset.context.default_filter_id,
|
||||
} : {}),
|
||||
},
|
||||
{
|
||||
on_close: function()
|
||||
{
|
||||
self.ViewManager.setup_search_view(
|
||||
self.ViewManager.searchview.view_id,
|
||||
self.ViewManager.searchview.defaults);
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="ir_filters_view_form" model="ir.ui.view">
|
||||
<field name="model">ir.filters</field>
|
||||
<field name="inherit_id" ref="base.ir_filters_view_form" />
|
||||
<field name="arch" type="xml">
|
||||
<sheet position="before">
|
||||
<header>
|
||||
<button type="object" string="Test filter" name="button_test" class="oe_highlight" />
|
||||
<button type="object" string="Freeze filter" name="button_freeze" attrs="{'invisible': [('is_frozen', '=', True)]}" help="Have this filter contain extly the records it currently contains, with no changes in the future. Be careful, you can't undo this operation!" confirm="Are you sure? You can't undo this operation!" />
|
||||
</header>
|
||||
</sheet>
|
||||
<group position="after">
|
||||
<field name="is_frozen" invisible="True" />
|
||||
<field name="id" invisible="True" />
|
||||
<group string="Add the result of following filters">
|
||||
<field name="union_filter_ids" nolabel="1" domain="[('user_id', 'in', [False, uid]), ('id', '!=', id), ('model_id', '=', model_id)]" />
|
||||
</group>
|
||||
<group string="Remove the result of following filters">
|
||||
<field name="complement_filter_ids" nolabel="1" domain="[('user_id', 'in', [False, uid]),('id', '!=', id), ('model_id', '=', model_id)]" />
|
||||
</group>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
<record id="form_ir_filters_save_new" model="ir.ui.view">
|
||||
<field name="model">ir.filters</field>
|
||||
<field name="priority">999</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Save filter" version="7.0">
|
||||
<group>
|
||||
<field name="name" />
|
||||
<field name="is_default"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button class="oe_highlight" type="object" name="button_save" string="Save" />
|
||||
or
|
||||
<button class="oe_link" special="cancel" string="Cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
|
@ -0,0 +1,21 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# This module copyright (C) 2014 Therp BV (<http://therp.nl>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from . import ir_filters_combine_with_existing
|
|
@ -0,0 +1,87 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# This module copyright (C) 2014 Therp BV (<http://therp.nl>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
import time
|
||||
from openerp.osv.orm import TransientModel
|
||||
from openerp.osv import fields, expression
|
||||
from openerp.tools.safe_eval import safe_eval
|
||||
|
||||
|
||||
class IrFiltersCombineWithExisting(TransientModel):
|
||||
_name = 'ir.filters.combine.with.existing'
|
||||
_description = 'Combine a selection with an existing filter'
|
||||
|
||||
_columns = {
|
||||
'action': fields.selection(
|
||||
[('union', 'Union'), ('complement', 'Complement')],
|
||||
'Action', required=True),
|
||||
'domain': fields.char('Domain', required=True),
|
||||
'context': fields.char('Context', required=True),
|
||||
'model': fields.char('Model', required=True),
|
||||
'filter_id': fields.many2one('ir.filters', 'Filter', required=True),
|
||||
}
|
||||
|
||||
def button_save(self, cr, uid, ids, context=None):
|
||||
assert len(ids) == 1
|
||||
this = self.browse(cr, uid, ids[0], context=context)
|
||||
domain = safe_eval(this.domain)
|
||||
is_frozen = (len(domain) == 1 and
|
||||
expression.is_leaf(domain[0]) and
|
||||
domain[0][0] == 'id')
|
||||
|
||||
if this.action == 'union':
|
||||
if is_frozen and this.filter_id.is_frozen:
|
||||
domain[0][2] = list(set(domain[0][2]).union(
|
||||
set(safe_eval(this.filter_id.domain)[0][2])))
|
||||
this.filter_id.write({'domain': str(domain)})
|
||||
else:
|
||||
this.filter_id.write(
|
||||
{
|
||||
'union_filter_ids': [(0, 0, {
|
||||
'name': '%s_%s_%d' % (
|
||||
this.filter_id.name, 'add', time.time()),
|
||||
'active': False,
|
||||
'domain': str(domain),
|
||||
'context': this.context,
|
||||
'model_id': this.model,
|
||||
'user_id': uid,
|
||||
})],
|
||||
})
|
||||
elif this.action == 'complement':
|
||||
if is_frozen and this.filter_id.is_frozen:
|
||||
complement_set = set(safe_eval(this.filter_id.domain)[0][2])
|
||||
domain[0][2] = list(
|
||||
complement_set.difference(set(domain[0][2])))
|
||||
this.filter_id.write({'domain': str(domain)})
|
||||
else:
|
||||
this.filter_id.write(
|
||||
{
|
||||
'complement_filter_ids': [(0, 0, {
|
||||
'name': '%s_%s_%d' % (
|
||||
this.filter_id.name, 'remove', time.time()),
|
||||
'active': False,
|
||||
'domain': str(domain),
|
||||
'context': this.context,
|
||||
'model_id': this.model,
|
||||
'user_id': uid,
|
||||
})],
|
||||
})
|
||||
|
||||
return {'type': 'ir.actions.act_window.close'}
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="form_ir_filters_combine_with_existing" model="ir.ui.view">
|
||||
<field name="model">ir.filters.combine.with.existing</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Combine with existing filter" version="7.0">
|
||||
<group>
|
||||
<field name="model" invisible="1" />
|
||||
<field name="filter_id" domain="[('model_id', '=', model)]" />
|
||||
</group>
|
||||
<footer>
|
||||
<button class="oe_highlight" type="object" name="button_save" string="Save" />
|
||||
or
|
||||
<button class="oe_link" special="cancel" string="Cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
Loading…
Reference in New Issue