From 933adca053d003b133660d5949e61839bdb76b3a Mon Sep 17 00:00:00 2001 From: Jaydeep Barot Date: Wed, 2 Apr 2014 14:23:56 +0530 Subject: [PATCH 1/6] [IMP] In list view of journal items, user can sort using Reconcile ref field currently. bzr revid: jar@tinyerp.com-20140402085356-4bqscthp64r8ssph --- addons/account/account_move_line.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index b48e842caf5..b328792b571 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -445,7 +445,7 @@ class account_move_line(osv.osv): 'statement_id': fields.many2one('account.bank.statement', 'Statement', help="The bank statement used for bank reconciliation", select=1), 'reconcile_id': fields.many2one('account.move.reconcile', 'Reconcile', readonly=True, ondelete='set null', select=2), 'reconcile_partial_id': fields.many2one('account.move.reconcile', 'Partial Reconcile', readonly=True, ondelete='set null', select=2), - 'reconcile': fields.function(_get_reconcile, type='char', string='Reconcile Ref'), + 'reconcile': fields.function(_get_reconcile, type='char', string='Reconcile Ref', store=True), 'amount_currency': fields.float('Amount Currency', help="The amount expressed in an optional other currency if it is a multi-currency entry.", digits_compute=dp.get_precision('Account')), 'amount_residual_currency': fields.function(_amount_residual, string='Residual Amount in Currency', multi="residual", help="The residual amount on a receivable or payable of a journal entry expressed in its currency (maybe different of the company currency)."), 'amount_residual': fields.function(_amount_residual, string='Residual Amount', multi="residual", help="The residual amount on a receivable or payable of a journal entry expressed in the company currency."), From a55015b8eb2574948d0d079e1f8ff90ae12a9e82 Mon Sep 17 00:00:00 2001 From: Jaydeep Barot Date: Thu, 24 Apr 2014 12:23:06 +0530 Subject: [PATCH 2/6] [IMP] remove store=true and add store={} in recouncile field bzr revid: jar@tinyerp.com-20140424065306-e6q3g48cjee1ybni --- addons/account/account_move_line.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index b328792b571..a79aff58c20 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -430,6 +430,19 @@ class account_move_line(osv.osv): elif line.reconcile_partial_id: res[line.id] = str(line.reconcile_partial_id.name) return res + + def _get_move_from_reconcile(self, cr, uid, ids, context=None): + move = {} + for r in self.pool.get('account.move.reconcile').browse(cr, uid, ids, context=context): + for line in r.line_partial_ids: + move[line.move_id.id] = True + for line in r.line_id: + move[line.move_id.id] = True + move_line_ids = [] + if move: + move_line_ids = self.pool.get('account.move.line').search(cr, uid, [('journal_id','in',move.keys())], context=context) + return move_line_ids + _columns = { 'name': fields.char('Name', size=64, required=True), @@ -445,7 +458,8 @@ class account_move_line(osv.osv): 'statement_id': fields.many2one('account.bank.statement', 'Statement', help="The bank statement used for bank reconciliation", select=1), 'reconcile_id': fields.many2one('account.move.reconcile', 'Reconcile', readonly=True, ondelete='set null', select=2), 'reconcile_partial_id': fields.many2one('account.move.reconcile', 'Partial Reconcile', readonly=True, ondelete='set null', select=2), - 'reconcile': fields.function(_get_reconcile, type='char', string='Reconcile Ref', store=True), + 'reconcile': fields.function(_get_reconcile, type='char', string='Reconcile Ref', store={ + 'account.move.line': (lambda self, cr, uid, ids, c={}: ids, ['reconcile_id','reconcile_partial_id'], 50),'account.move.reconcile': (_get_move_from_reconcile, None, 50)}), 'amount_currency': fields.float('Amount Currency', help="The amount expressed in an optional other currency if it is a multi-currency entry.", digits_compute=dp.get_precision('Account')), 'amount_residual_currency': fields.function(_amount_residual, string='Residual Amount in Currency', multi="residual", help="The residual amount on a receivable or payable of a journal entry expressed in its currency (maybe different of the company currency)."), 'amount_residual': fields.function(_amount_residual, string='Residual Amount', multi="residual", help="The residual amount on a receivable or payable of a journal entry expressed in the company currency."), From fb4507386d34256641ca35c030d43f9e0c59ba11 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Fri, 25 Apr 2014 01:08:01 +0200 Subject: [PATCH 3/6] [REM] project_gtd deprecated by notes bzr revid: al@openerp.com-20140424230801-zmzp2byyk41e7uxf --- addons/project_gtd/__init__.py | 24 ---- addons/project_gtd/__openerp__.py | 56 -------- addons/project_gtd/project_gtd.py | 122 ---------------- addons/project_gtd/project_gtd_data.xml | 40 ------ addons/project_gtd/project_gtd_demo.xml | 35 ----- addons/project_gtd/project_gtd_view.xml | 132 ------------------ .../project_gtd/security/ir.model.access.csv | 5 - .../project_gtd/static/description/icon.png | Bin 7547 -> 0 bytes addons/project_gtd/test/task_timebox.yml | 45 ------ addons/project_gtd/wizard/__init__.py | 26 ---- .../project_gtd/wizard/project_gtd_empty.py | 66 --------- .../wizard/project_gtd_empty_view.xml | 37 ----- addons/project_gtd/wizard/project_gtd_fill.py | 60 -------- .../wizard/project_gtd_fill_view.xml | 46 ------ 14 files changed, 694 deletions(-) delete mode 100644 addons/project_gtd/__init__.py delete mode 100644 addons/project_gtd/__openerp__.py delete mode 100644 addons/project_gtd/project_gtd.py delete mode 100644 addons/project_gtd/project_gtd_data.xml delete mode 100644 addons/project_gtd/project_gtd_demo.xml delete mode 100644 addons/project_gtd/project_gtd_view.xml delete mode 100644 addons/project_gtd/security/ir.model.access.csv delete mode 100644 addons/project_gtd/static/description/icon.png delete mode 100644 addons/project_gtd/test/task_timebox.yml delete mode 100644 addons/project_gtd/wizard/__init__.py delete mode 100644 addons/project_gtd/wizard/project_gtd_empty.py delete mode 100644 addons/project_gtd/wizard/project_gtd_empty_view.xml delete mode 100644 addons/project_gtd/wizard/project_gtd_fill.py delete mode 100644 addons/project_gtd/wizard/project_gtd_fill_view.xml diff --git a/addons/project_gtd/__init__.py b/addons/project_gtd/__init__.py deleted file mode 100644 index cb17064b6b8..00000000000 --- a/addons/project_gtd/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (). -# -# 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 . -# -############################################################################## -import project_gtd -import wizard -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/addons/project_gtd/__openerp__.py b/addons/project_gtd/__openerp__.py deleted file mode 100644 index ee14df38101..00000000000 --- a/addons/project_gtd/__openerp__.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (). -# -# 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 . -# -############################################################################## - - -{ - 'name': 'Todo Lists', - 'version': '1.0', - 'category': 'Project Management', - 'sequence': 100, - 'summary': 'Personal Tasks, Contexts, Timeboxes', - 'description': """ -Implement concepts of the "Getting Things Done" methodology -=========================================================== - -This module implements a simple personal to-do list based on tasks. It adds an editable list of tasks simplified to the minimum required fields in the project application. - -The to-do list is based on the GTD methodology. This world-wide used methodology is used for personal time management improvement. - -Getting Things Done (commonly abbreviated as GTD) is an action management method created by David Allen, and described in a book of the same name. - -GTD rests on the principle that a person needs to move tasks out of the mind by recording them externally. That way, the mind is freed from the job of remembering everything that needs to be done, and can concentrate on actually performing those tasks. - """, - 'author': 'OpenERP SA', - 'images': ['images/project_gtd.jpeg'], - 'depends': ['project'], - 'data': [ - 'project_gtd_data.xml', - 'project_gtd_view.xml', - 'security/ir.model.access.csv', - 'wizard/project_gtd_empty_view.xml', - 'wizard/project_gtd_fill_view.xml', - ], - 'demo': ['project_gtd_demo.xml'], - 'test':['test/task_timebox.yml'], - 'installable': True, - 'auto_install': False, -} -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_gtd/project_gtd.py b/addons/project_gtd/project_gtd.py deleted file mode 100644 index 47569e863aa..00000000000 --- a/addons/project_gtd/project_gtd.py +++ /dev/null @@ -1,122 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (). -# -# 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 . -# -############################################################################## - -import sys - -from openerp.osv import fields, osv -from openerp import tools -from openerp.tools.translate import _ - -class project_gtd_context(osv.osv): - _name = "project.gtd.context" - _description = "Context" - _columns = { - 'name': fields.char('Context', size=64, required=True, select=1, translate=1), - 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of contexts."), - } - _defaults = { - 'sequence': 1 - } - _order = "sequence, name" - - - -class project_gtd_timebox(osv.osv): - _name = "project.gtd.timebox" - _order = "sequence" - _columns = { - 'name': fields.char('Timebox', size=64, required=True, select=1, translate=1), - 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of timebox."), - 'icon': fields.selection(tools.icons, 'Icon', size=64), - } - - -class project_task(osv.osv): - _inherit = "project.task" - _columns = { - 'timebox_id': fields.many2one('project.gtd.timebox', "Timebox",help="Time-laps during which task has to be treated"), - 'context_id': fields.many2one('project.gtd.context', "Context",help="The context place where user has to treat task"), - } - - def copy_data(self, cr, uid, id, default=None, context=None): - if context is None: - context = {} - if not default: - default = {} - default['timebox_id'] = False - default['context_id'] = False - return super(project_task,self).copy_data(cr, uid, id, default, context) - - def _get_context(self, cr, uid, context=None): - ids = self.pool.get('project.gtd.context').search(cr, uid, [], context=context) - return ids and ids[0] or False - - _defaults = { - 'context_id': _get_context - } - def next_timebox(self, cr, uid, ids, *args): - timebox_obj = self.pool.get('project.gtd.timebox') - timebox_ids = timebox_obj.search(cr,uid,[]) - if not timebox_ids: return True - for task in self.browse(cr,uid,ids): - timebox = task.timebox_id.id - if not timebox: - self.write(cr, uid, task.id, {'timebox_id': timebox_ids[0]}) - elif timebox_ids.index(timebox) != len(timebox_ids)-1: - index = timebox_ids.index(timebox) - self.write(cr, uid, task.id, {'timebox_id': timebox_ids[index+1]}) - return True - - def prev_timebox(self, cr, uid, ids, *args): - timebox_obj = self.pool.get('project.gtd.timebox') - timebox_ids = timebox_obj.search(cr,uid,[]) - for task in self.browse(cr,uid,ids): - timebox = task.timebox_id.id - if timebox: - if timebox_ids.index(timebox): - index = timebox_ids.index(timebox) - self.write(cr, uid, task.id, {'timebox_id': timebox_ids[index - 1]}) - else: - self.write(cr, uid, task.id, {'timebox_id': False}) - return True - - def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): - if not context: context = {} - res = super(project_task,self).fields_view_get(cr, uid, view_id, view_type, context, toolbar=toolbar, submenu=submenu) - search_extended = False - timebox_obj = self.pool.get('project.gtd.timebox') - if (res['type'] == 'search') and context.get('gtd', False): - tt = timebox_obj.browse(cr, uid, timebox_obj.search(cr,uid,[]), context=context) - search_extended ='' - for time in tt: - if time.icon: - icon = time.icon - else : - icon="" - search_extended += '''\n''' - search_extended +='''''' - - res['arch'] = tools.ustr(res['arch']).replace('', search_extended) - - return res - - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_gtd/project_gtd_data.xml b/addons/project_gtd/project_gtd_data.xml deleted file mode 100644 index 9d8c99f23ff..00000000000 --- a/addons/project_gtd/project_gtd_data.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - Office - 0 - - - Travel - 2 - - - - Today - terp-go-today - - - This Week - terp-go-week - - - Long Term - terp-project - - - - - - - mail.group - - notification - - Todo Lists application installed! - Add todo items on project tasks, to help you organize your work.

-This application supports the Getting Things Done (GTD) methodology, based on David Allen's book.

]]>
-
- -
-
diff --git a/addons/project_gtd/project_gtd_demo.xml b/addons/project_gtd/project_gtd_demo.xml deleted file mode 100644 index 00ba897c4e2..00000000000 --- a/addons/project_gtd/project_gtd_demo.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - Home - 3 - - - Car - 1 - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/addons/project_gtd/project_gtd_view.xml b/addons/project_gtd/project_gtd_view.xml deleted file mode 100644 index 0ae335d9bfb..00000000000 --- a/addons/project_gtd/project_gtd_view.xml +++ /dev/null @@ -1,132 +0,0 @@ - - - - - project.gtd.context.tree - project.gtd.context - - - - - - - - - - project.gtd.context.form - project.gtd.context - -
- - - - -
-
-
- - - Contexts - project.gtd.context - Contexts are defined in the "Getting Things Done" methodology. It allows you to categorize your tasks according to the context in which they have to be done: at the office, at home, when I take my car, etc. - - - - - - project.gtd.timebox.tree - project.gtd.timebox - - - - - - - - - - - project.gtd.timebox.form - project.gtd.timebox - -
- - - - - -
-
-
- - - Timeboxes - project.gtd.timebox - form - tree,form - - Timeboxes are defined in the "Getting Things Done" methodology. A timebox defines a period of time in order to categorize your tasks: today, this week, this month, long term. - - - - - - project.task.tree.timebox - project.task - - - - - - - - - - - project.task.form.timebox - project.task - - - - - - - - - - - project.task.gtd.search - project.task - 50 - - - - - - - - - - - - - - - - - - - My Tasks - project.task - - {'set_editable':True,'set_visible':True,'gtd':True,'user_invisible':True, "search_default_open": 1} - [('user_id','=',uid)] - form - kanban,tree,form,calendar,gantt,graph - - - - -
-
diff --git a/addons/project_gtd/security/ir.model.access.csv b/addons/project_gtd/security/ir.model.access.csv deleted file mode 100644 index d85ac8a5d0c..00000000000 --- a/addons/project_gtd/security/ir.model.access.csv +++ /dev/null @@ -1,5 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_project_gtd_context_user,project.gtd.context project user,model_project_gtd_context,project.group_project_user,1,0,0,0 -access_project_gtd_timebox_user,project.gtd.timebox project user,model_project_gtd_timebox,project.group_project_user,1,0,0,0 -access_project_gtd_context_manager,project.gtd.context project manager,model_project_gtd_context,project.group_project_manager,1,1,1,1 -access_project_gtd_timebox_manager,project.gtd.timebox project manager,model_project_gtd_timebox,project.group_project_manager,1,1,1,1 diff --git a/addons/project_gtd/static/description/icon.png b/addons/project_gtd/static/description/icon.png deleted file mode 100644 index 2f888a90a60212982a6495f0994c440a121bc6cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7547 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 diff --git a/addons/project_gtd/test/task_timebox.yml b/addons/project_gtd/test/task_timebox.yml deleted file mode 100644 index 8efa7219b21..00000000000 --- a/addons/project_gtd/test/task_timebox.yml +++ /dev/null @@ -1,45 +0,0 @@ -- - In order to test the process of Timebox in Project Management module, - I set my task from Daily to Weekly Timebox through Plannify Timebox -- - !record {model: project.timebox.fill.plan, id: plan_id}: - task_ids: [project.project_task_10] - timebox_id: timebox_daily - timebox_to_id: timebox_weekly -- - I set the task from Daily Timebox to Weekly Timebox -- - !python {model: project.timebox.fill.plan}: | - self.process(cr, uid, [ref("plan_id")]) -- - I check task is set to Weekly Timebox -- - !assert {model: project.task, id: project.project_task_10, string: Task should be set to weekly timebox}: - - timebox_id.id == ref("timebox_weekly") -- - I Empty the Weekly Timebox -- - !python {model: project.timebox.empty}: | - self._empty(cr, uid, {"active_model": "project.gtd.timebox", - "active_ids":[ref("timebox_weekly")], - "active_id": ref("timebox_weekly"), - }) -- - I check task 'Develop Module in Sale Management' is no more in Weekly Timebox -- - !assert {model: project.task, id: project.project_task_10 , string: Task is not in Weekly Timebox }: - - timebox_id.id != ref("timebox_weekly") -- - I set Previous Timebox on task -- - !python {model: project.task}: | - previous_timebox = self.prev_timebox(cr, uid, [ref("project.project_task_10")], - {'active_ids': [ref("project_gtd.menu_open_gtd_timebox_tree")],}) - assert previous_timebox == True, "I set Previous Timebox on task" -- - I set Next Timebox on task -- - !python {model: project.task}: | - next_timebox = self.next_timebox(cr, uid, [ref("project.project_task_10")], - {'active_ids': [ref("project_gtd.menu_open_gtd_timebox_tree")],}) - assert next_timebox == True, "I set Next Timebox on task" \ No newline at end of file diff --git a/addons/project_gtd/wizard/__init__.py b/addons/project_gtd/wizard/__init__.py deleted file mode 100644 index aa2bbc22c45..00000000000 --- a/addons/project_gtd/wizard/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (). -# -# 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 . -# -############################################################################## - -import project_gtd_empty -import project_gtd_fill - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/addons/project_gtd/wizard/project_gtd_empty.py b/addons/project_gtd/wizard/project_gtd_empty.py deleted file mode 100644 index b477c12567a..00000000000 --- a/addons/project_gtd/wizard/project_gtd_empty.py +++ /dev/null @@ -1,66 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (). -# -# 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 . -# -############################################################################## - -from openerp.osv import fields, osv -from openerp.tools.translate import _ - -class project_timebox_empty(osv.osv_memory): - - _name = 'project.timebox.empty' - _description = 'Project Timebox Empty' - _columns = { - 'name': fields.char('Name', size=32) - } - - def view_init(self, cr, uid, fields_list, context=None): - if context is None: - context = {} - self._empty(cr, uid, context=context) - pass - - def _empty(self, cr, uid, context=None): - close = [] - up = [] - obj_tb = self.pool.get('project.gtd.timebox') - obj_task = self.pool.get('project.task') - - if context is None: - context = {} - if not 'active_id' in context: - return {} - - ids = obj_tb.search(cr, uid, [], context=context) - if not len(ids): - raise osv.except_osv(_('Error!'), _('No timebox child of this one!')) - tids = obj_task.search(cr, uid, [('timebox_id', '=', context['active_id'])]) - for task in obj_task.browse(cr, uid, tids, context): - if (task.stage_id and task.stage_id.fold) or (task.user_id.id <> uid): - close.append(task.id) - else: - up.append(task.id) - if up: - obj_task.write(cr, uid, up, {'timebox_id':ids[0]}) - if close: - obj_task.write(cr, uid, close, {'timebox_id':False}) - return {} - - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_gtd/wizard/project_gtd_empty_view.xml b/addons/project_gtd/wizard/project_gtd_empty_view.xml deleted file mode 100644 index 053c0013e73..00000000000 --- a/addons/project_gtd/wizard/project_gtd_empty_view.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - Empty Timebox - project.timebox.empty - -
-
-
- - - Empty Timebox - ir.actions.act_window - project.timebox.empty - form - form - - {'record_id' : active_id} - new - - - - - Empty Timebox - client_action_multi - - action - project.gtd.timebox - - - -
-
diff --git a/addons/project_gtd/wizard/project_gtd_fill.py b/addons/project_gtd/wizard/project_gtd_fill.py deleted file mode 100644 index 121bd7efdac..00000000000 --- a/addons/project_gtd/wizard/project_gtd_fill.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (). -# -# 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 . -# -############################################################################## - -from openerp.osv import fields, osv - -class project_timebox_fill(osv.osv_memory): - - _name = 'project.timebox.fill.plan' - _description = 'Project Timebox Fill' - _columns = { - 'timebox_id': fields.many2one('project.gtd.timebox', 'Get from Timebox', required=True), - 'timebox_to_id': fields.many2one('project.gtd.timebox', 'Set to Timebox', required=True), - 'task_ids': fields.many2many('project.task', 'project_task_rel', 'task_id', 'fill_id', 'Tasks selection') - } - - def _get_from_tb(self, cr, uid, context=None): - ids = self.pool.get('project.gtd.timebox').search(cr, uid, [], context=context) - return ids and ids[0] or False - - def _get_to_tb(self, cr, uid, context=None): - if context is None: - context = {} - if 'active_id' in context: - return context['active_id'] - return False - - _defaults = { - 'timebox_id': _get_from_tb, - 'timebox_to_id': _get_to_tb, - } - - def process(self, cr, uid, ids, context=None): - if not ids: - return {} - data = self.read(cr, uid, ids, [], context=context) - if not data[0]['task_ids']: - return {} - self.pool.get('project.task').write(cr, uid, data[0]['task_ids'], {'timebox_id':data[0]['timebox_to_id'][0]}) - return {'type': 'ir.actions.act_window_close'} - - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_gtd/wizard/project_gtd_fill_view.xml b/addons/project_gtd/wizard/project_gtd_fill_view.xml deleted file mode 100644 index 626dfb699b8..00000000000 --- a/addons/project_gtd/wizard/project_gtd_fill_view.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - Plannify Timebox - project.timebox.fill.plan - -
- - - - - -
-
- -
-
- - - Plannify Timebox - ir.actions.act_window - project.timebox.fill.plan - form - form - - {'record_id' : active_id} - new - - - - - Plannify Timebox - client_action_multi - - action - project.gtd.timebox - - - -
-
From dfa56e6b5466c82d66f7977cc0b9e477d9edb97e Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Fri, 25 Apr 2014 01:23:48 +0200 Subject: [PATCH 4/6] [REM] move auditrail to extra It's deprecated by _track_fields, mail.message and base_action_rules bzr revid: al@openerp.com-20140424232348-sn1oijj604uz6aen --- addons/audittrail/__init__.py | 25 - addons/audittrail/__openerp__.py | 47 -- addons/audittrail/audittrail.py | 538 ------------------ addons/audittrail/audittrail_demo.xml | 10 - addons/audittrail/audittrail_view.xml | 185 ------ .../audittrail/security/ir.model.access.csv | 5 - addons/audittrail/wizard/__init__.py | 24 - .../audittrail/wizard/audittrail_view_log.py | 65 --- .../wizard/audittrail_view_log_view.xml | 37 -- 9 files changed, 936 deletions(-) delete mode 100644 addons/audittrail/__init__.py delete mode 100644 addons/audittrail/__openerp__.py delete mode 100644 addons/audittrail/audittrail.py delete mode 100644 addons/audittrail/audittrail_demo.xml delete mode 100644 addons/audittrail/audittrail_view.xml delete mode 100644 addons/audittrail/security/ir.model.access.csv delete mode 100644 addons/audittrail/wizard/__init__.py delete mode 100644 addons/audittrail/wizard/audittrail_view_log.py delete mode 100644 addons/audittrail/wizard/audittrail_view_log_view.xml diff --git a/addons/audittrail/__init__.py b/addons/audittrail/__init__.py deleted file mode 100644 index cdaa3fd4181..00000000000 --- a/addons/audittrail/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (). -# -# 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 . -# -############################################################################## - -import audittrail -import wizard -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/addons/audittrail/__openerp__.py b/addons/audittrail/__openerp__.py deleted file mode 100644 index 41958c84f66..00000000000 --- a/addons/audittrail/__openerp__.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (). -# -# 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 . -# -############################################################################## - - -{ - 'name': 'Audit Trail', - 'version': '1.0', - 'category': 'Tools', - 'description': """ -This module lets administrator track every user operation on all the objects of the system. -=========================================================================================== - -The administrator can subscribe to rules for read, write and delete on objects -and can check logs. - """, - 'author': 'OpenERP SA', - 'website': 'http://www.openerp.com', - 'depends': ['base'], - 'data': [ - 'wizard/audittrail_view_log_view.xml', - 'audittrail_view.xml', - 'security/ir.model.access.csv', - ], - 'demo': ['audittrail_demo.xml'], - 'installable': True, - 'auto_install': False, - 'images': ['images/audittrail1.jpeg','images/audittrail2.jpeg','images/audittrail3.jpeg'], -} -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py deleted file mode 100644 index 71008e0855b..00000000000 --- a/addons/audittrail/audittrail.py +++ /dev/null @@ -1,538 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (). -# -# 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 . -# -############################################################################## - -import openerp -from openerp.osv import fields, osv -import openerp.service.model -from openerp.tools.translate import _ -import time -from openerp import tools -from openerp import SUPERUSER_ID - -class audittrail_rule(osv.osv): - """ - For Auddittrail Rule - """ - _name = 'audittrail.rule' - _description = "Audittrail Rule" - _columns = { - "name": fields.char("Rule Name", size=32, required=True), - "object_id": fields.many2one('ir.model', 'Object', required=True, help="Select object for which you want to generate log."), - "user_id": fields.many2many('res.users', 'audittail_rules_users', - 'user_id', 'rule_id', 'Users', help="if User is not added then it will applicable for all users"), - "log_read": fields.boolean("Log Reads", help="Select this if you want to keep track of read/open on any record of the object of this rule"), - "log_write": fields.boolean("Log Writes", help="Select this if you want to keep track of modification on any record of the object of this rule"), - "log_unlink": fields.boolean("Log Deletes", help="Select this if you want to keep track of deletion on any record of the object of this rule"), - "log_create": fields.boolean("Log Creates",help="Select this if you want to keep track of creation on any record of the object of this rule"), - "log_action": fields.boolean("Log Action",help="Select this if you want to keep track of actions on the object of this rule"), - "log_workflow": fields.boolean("Log Workflow",help="Select this if you want to keep track of workflow on any record of the object of this rule"), - "state": fields.selection((("draft", "Draft"), ("subscribed", "Subscribed")), "Status", required=True), - "action_id": fields.many2one('ir.actions.act_window', "Action ID"), - } - _defaults = { - 'state': 'draft', - 'log_create': 1, - 'log_unlink': 1, - 'log_write': 1, - } - _sql_constraints = [ - ('model_uniq', 'unique (object_id)', """There is already a rule defined on this object\n You cannot define another: please edit the existing one.""") - ] - __functions = {} - - def subscribe(self, cr, uid, ids, *args): - """ - Subscribe Rule for auditing changes on object and apply shortcut for logs on that object. - @param cr: the current row, from the database cursor, - @param uid: the current user’s ID for security checks, - @param ids: List of Auddittrail Rule’s IDs. - @return: True - """ - obj_action = self.pool.get('ir.actions.act_window') - obj_model = self.pool.get('ir.model.data') - #start Loop - for thisrule in self.browse(cr, uid, ids): - if thisrule.object_id.model not in self.pool: - raise osv.except_osv( - _('WARNING: audittrail is not part of the pool'), - _('Change audittrail depends -- Setting rule as DRAFT')) - self.write(cr, uid, [thisrule.id], {"state": "draft"}) - val = { - "name": 'View Log', - "res_model": 'audittrail.log', - "src_model": thisrule.object_id.model, - "domain": "[('object_id','=', " + str(thisrule.object_id.id) + "), ('res_id', '=', active_id)]" - - } - action_id = obj_action.create(cr, SUPERUSER_ID, val) - self.write(cr, uid, [thisrule.id], {"state": "subscribed", "action_id": action_id}) - keyword = 'client_action_relate' - value = 'ir.actions.act_window,' + str(action_id) - res = obj_model.ir_set(cr, SUPERUSER_ID, 'action', keyword, 'View_log_' + thisrule.object_id.model, [thisrule.object_id.model], value, replace=True, isobject=True, xml_id=False) - #End Loop - return True - - def unsubscribe(self, cr, uid, ids, *args): - """ - Unsubscribe Auditing Rule on object - @param cr: the current row, from the database cursor, - @param uid: the current user’s ID for security checks, - @param ids: List of Auddittrail Rule’s IDs. - @return: True - """ - obj_action = self.pool.get('ir.actions.act_window') - ir_values_obj = self.pool.get('ir.values') - value='' - #start Loop - for thisrule in self.browse(cr, uid, ids): - if thisrule.id in self.__functions: - for function in self.__functions[thisrule.id]: - setattr(function[0], function[1], function[2]) - w_id = obj_action.search(cr, uid, [('name', '=', 'View Log'), ('res_model', '=', 'audittrail.log'), ('src_model', '=', thisrule.object_id.model)]) - if w_id: - obj_action.unlink(cr, SUPERUSER_ID, w_id) - value = "ir.actions.act_window" + ',' + str(w_id[0]) - val_id = ir_values_obj.search(cr, uid, [('model', '=', thisrule.object_id.model), ('value', '=', value)]) - if val_id: - res = ir_values_obj.unlink(cr, uid, [val_id[0]]) - self.write(cr, uid, [thisrule.id], {"state": "draft"}) - #End Loop - return True - -class audittrail_log(osv.osv): - """ - For Audittrail Log - """ - _name = 'audittrail.log' - _description = "Audittrail Log" - - def _name_get_resname(self, cr, uid, ids, *args): - data = {} - for resname in self.browse(cr, uid, ids,[]): - model_object = resname.object_id - res_id = resname.res_id - if model_object and res_id: - model_pool = self.pool[model_object.model] - res = model_pool.read(cr, uid, res_id, ['name']) - data[resname.id] = res['name'] - else: - data[resname.id] = False - return data - - _columns = { - "name": fields.char("Resource Name",size=64), - "object_id": fields.many2one('ir.model', 'Object'), - "user_id": fields.many2one('res.users', 'User'), - "method": fields.char("Method", size=64), - "timestamp": fields.datetime("Date"), - "res_id": fields.integer('Resource Id'), - "line_ids": fields.one2many('audittrail.log.line', 'log_id', 'Log lines'), - } - - _defaults = { - "timestamp": lambda *a: time.strftime("%Y-%m-%d %H:%M:%S") - } - _order = "timestamp desc" - -class audittrail_log_line(osv.osv): - """ - Audittrail Log Line. - """ - _name = 'audittrail.log.line' - _description = "Log Line" - _columns = { - 'field_id': fields.many2one('ir.model.fields', 'Fields', required=True), - 'log_id': fields.many2one('audittrail.log', 'Log'), - 'log': fields.integer("Log ID"), - 'old_value': fields.text("Old Value"), - 'new_value': fields.text("New Value"), - 'old_value_text': fields.text('Old value Text'), - 'new_value_text': fields.text('New value Text'), - 'field_description': fields.char('Field Description', size=64), - } - -# Monkeypatch the model RPC endpoint for auditing changes. - -def get_value_text(cr, uid, pool, resource_pool, method, field, value): - """ - Gets textual values for the fields. - If the field is a many2one, it returns the name. - If it's a one2many or a many2many, it returns a list of name. - In other cases, it just returns the value. - :param cr: the current row, from the database cursor, - :param uid: the current user’s ID for security checks, - :param pool: current db's pooler object. - :param resource_pool: pooler object of the model which values are being changed. - :param field: for which the text value is to be returned. - :param value: value of the field. - :param recursive: True or False, True will repeat the process recursively - :return: string value or a list of values(for O2M/M2M) - """ - - field_obj = (resource_pool._all_columns.get(field)).column - if field_obj._type in ('one2many','many2many'): - data = pool[field_obj._obj].name_get(cr, uid, value) - #return the modifications on x2many fields as a list of names - res = map(lambda x:x[1], data) - elif field_obj._type == 'many2one': - #return the modifications on a many2one field as its value returned by name_get() - res = value and value[1] or value - else: - res = value - return res - -def create_log_line(cr, uid, log_id, model, lines=None): - """ - Creates lines for changed fields with its old and new values - - @param cr: the current row, from the database cursor, - @param uid: the current user’s ID for security checks, - @param model: Object which values are being changed - @param lines: List of values for line is to be created - """ - if lines is None: - lines = [] - pool = openerp.registry(cr.dbname) - obj_pool = pool[model.model] - model_pool = pool.get('ir.model') - field_pool = pool.get('ir.model.fields') - log_line_pool = pool.get('audittrail.log.line') - for line in lines: - field_obj = obj_pool._all_columns.get(line['name']) - assert field_obj, _("'%s' field does not exist in '%s' model" %(line['name'], model.model)) - field_obj = field_obj.column - old_value = line.get('old_value', '') - new_value = line.get('new_value', '') - search_models = [model.id] - if obj_pool._inherits: - search_models += model_pool.search(cr, uid, [('model', 'in', obj_pool._inherits.keys())]) - field_id = field_pool.search(cr, uid, [('name', '=', line['name']), ('model_id', 'in', search_models)]) - if field_obj._type == 'many2one': - old_value = old_value and old_value[0] or old_value - new_value = new_value and new_value[0] or new_value - vals = { - "log_id": log_id, - "field_id": field_id and field_id[0] or False, - "old_value": old_value, - "new_value": new_value, - "old_value_text": line.get('old_value_text', ''), - "new_value_text": line.get('new_value_text', ''), - "field_description": field_obj.string - } - line_id = log_line_pool.create(cr, uid, vals) - return True - -def log_fct(cr, uid_orig, model, method, fct_src, *args, **kw): - """ - Logging function: This function is performing the logging operation - @param model: Object whose values are being changed - @param method: method to log: create, read, write, unlink, action or workflow action - @param fct_src: execute method of Object proxy - - @return: Returns result as per method of Object proxy - """ - pool = openerp.registry(cr.dbname) - resource_pool = pool[model] - model_pool = pool.get('ir.model') - model_ids = model_pool.search(cr, SUPERUSER_ID, [('model', '=', model)]) - model_id = model_ids and model_ids[0] or False - assert model_id, _("'%s' Model does not exist..." %(model)) - model = model_pool.browse(cr, SUPERUSER_ID, model_id) - - # fields to log. currently only used by log on read() - field_list = [] - old_values = new_values = {} - - if method == 'create': - res = fct_src(cr, uid_orig, model.model, method, *args, **kw) - if res: - res_ids = [res] - new_values = get_data(cr, uid_orig, pool, res_ids, model, method) - elif method == 'read': - res = fct_src(cr, uid_orig, model.model, method, *args, **kw) - if isinstance(res, dict): - records = [res] - else: - records = res - # build the res_ids and the old_values dict. Here we don't use get_data() to - # avoid performing an additional read() - res_ids = [] - for record in records: - res_ids.append(record['id']) - old_values[(model.id, record['id'])] = {'value': record, 'text': record} - # log only the fields read - field_list = args[1] - elif method == 'unlink': - res_ids = args[0] - old_values = get_data(cr, uid_orig, pool, res_ids, model, method) - # process_data first as fct_src will unlink the record - self.process_data(cr, uid_orig, pool, res_ids, model, method, old_values, new_values, field_list) - return fct_src(cr, uid_orig, model.model, method, *args, **kw) - else: # method is write, action or workflow action - res_ids = [] - if args: - res_ids = args[0] - if isinstance(res_ids, (long, int)): - res_ids = [res_ids] - if res_ids: - # store the old values into a dictionary - old_values = get_data(cr, uid_orig, pool, res_ids, model, method) - # process the original function, workflow trigger... - res = fct_src(cr, uid_orig, model.model, method, *args, **kw) - if method == 'copy': - res_ids = [res] - if res_ids: - # check the new values and store them into a dictionary - new_values = get_data(cr, uid_orig, pool, res_ids, model, method) - # compare the old and new values and create audittrail log if needed - process_data(cr, uid_orig, pool, res_ids, model, method, old_values, new_values, field_list) - return res - -def get_data(cr, uid, pool, res_ids, model, method): - """ - This function simply read all the fields of the given res_ids, and also recurisvely on - all records of a x2m fields read that need to be logged. Then it returns the result in - convenient structure that will be used as comparison basis. - - :param cr: the current row, from the database cursor, - :param uid: the current user’s ID. This parameter is currently not used as every - operation to get data is made as super admin. Though, it could be usefull later. - :param pool: current db's pooler object. - :param res_ids: Id's of resource to be logged/compared. - :param model: Object whose values are being changed - :param method: method to log: create, read, unlink, write, actions, workflow actions - :return: dict mapping a tuple (model_id, resource_id) with its value and textual value - { (model_id, resource_id): { 'value': ... - 'textual_value': ... - }, - } - """ - data = {} - resource_pool = pool[model.model] - # read all the fields of the given resources in super admin mode - for resource in resource_pool.read(cr, SUPERUSER_ID, res_ids, resource_pool._all_columns): - values = {} - values_text = {} - resource_id = resource['id'] - # loop on each field on the res_ids we just have read - for field in resource: - if field in ('__last_update', 'id'): - continue - values[field] = resource[field] - # get the textual value of that field for this record - values_text[field] = get_value_text(cr, SUPERUSER_ID, pool, resource_pool, method, field, resource[field]) - - field_obj = resource_pool._all_columns.get(field).column - if field_obj._type in ('one2many','many2many'): - # check if an audittrail rule apply in super admin mode - if check_rules(cr, SUPERUSER_ID, field_obj._obj, method): - # check if the model associated to a *2m field exists, in super admin mode - x2m_model_ids = pool.get('ir.model').search(cr, SUPERUSER_ID, [('model', '=', field_obj._obj)]) - x2m_model_id = x2m_model_ids and x2m_model_ids[0] or False - assert x2m_model_id, _("'%s' Model does not exist..." %(field_obj._obj)) - x2m_model = pool.get('ir.model').browse(cr, SUPERUSER_ID, x2m_model_id) - field_resource_ids = list(set(resource[field])) - if model.model == x2m_model.model: - # we need to remove current resource_id from the many2many to prevent an infinit loop - if resource_id in field_resource_ids: - field_resource_ids.remove(resource_id) - data.update(get_data(cr, SUPERUSER_ID, pool, field_resource_ids, x2m_model, method)) - - data[(model.id, resource_id)] = {'text':values_text, 'value': values} - return data - -def prepare_audittrail_log_line(cr, uid, pool, model, resource_id, method, old_values, new_values, field_list=None): - """ - This function compares the old data (i.e before the method was executed) and the new data - (after the method was executed) and returns a structure with all the needed information to - log those differences. - - :param cr: the current row, from the database cursor, - :param uid: the current user’s ID. This parameter is currently not used as every - operation to get data is made as super admin. Though, it could be usefull later. - :param pool: current db's pooler object. - :param model: model object which values are being changed - :param resource_id: ID of record to which values are being changed - :param method: method to log: create, read, unlink, write, actions, workflow actions - :param old_values: dict of values read before execution of the method - :param new_values: dict of values read after execution of the method - :param field_list: optional argument containing the list of fields to log. Currently only - used when performing a read, it could be usefull later on if we want to log the write - on specific fields only. - - :return: dictionary with - * keys: tuples build as ID of model object to log and ID of resource to log - * values: list of all the changes in field values for this couple (model, resource) - return { - (model.id, resource_id): [] - } - - The reason why the structure returned is build as above is because when modifying an existing - record, we may have to log a change done in a x2many field of that object - """ - if field_list is None: - field_list = [] - key = (model.id, resource_id) - lines = { - key: [] - } - # loop on all the fields - for field_name, field_definition in pool[model.model]._all_columns.items(): - if field_name in ('__last_update', 'id'): - continue - #if the field_list param is given, skip all the fields not in that list - if field_list and field_name not in field_list: - continue - field_obj = field_definition.column - if field_obj._type in ('one2many','many2many'): - # checking if an audittrail rule apply in super admin mode - if check_rules(cr, SUPERUSER_ID, field_obj._obj, method): - # checking if the model associated to a *2m field exists, in super admin mode - x2m_model_ids = pool.get('ir.model').search(cr, SUPERUSER_ID, [('model', '=', field_obj._obj)]) - x2m_model_id = x2m_model_ids and x2m_model_ids[0] or False - assert x2m_model_id, _("'%s' Model does not exist..." %(field_obj._obj)) - x2m_model = pool.get('ir.model').browse(cr, SUPERUSER_ID, x2m_model_id) - # the resource_ids that need to be checked are the sum of both old and previous values (because we - # need to log also creation or deletion in those lists). - x2m_old_values_ids = old_values.get(key, {'value': {}})['value'].get(field_name, []) - x2m_new_values_ids = new_values.get(key, {'value': {}})['value'].get(field_name, []) - # We use list(set(...)) to remove duplicates. - res_ids = list(set(x2m_old_values_ids + x2m_new_values_ids)) - if model.model == x2m_model.model: - # we need to remove current resource_id from the many2many to prevent an infinit loop - if resource_id in res_ids: - res_ids.remove(resource_id) - for res_id in res_ids: - lines.update(prepare_audittrail_log_line(cr, SUPERUSER_ID, pool, x2m_model, res_id, method, old_values, new_values, field_list)) - # if the value value is different than the old value: record the change - if key not in old_values or key not in new_values or old_values[key]['value'][field_name] != new_values[key]['value'][field_name]: - data = { - 'name': field_name, - 'new_value': key in new_values and new_values[key]['value'].get(field_name), - 'old_value': key in old_values and old_values[key]['value'].get(field_name), - 'new_value_text': key in new_values and new_values[key]['text'].get(field_name), - 'old_value_text': key in old_values and old_values[key]['text'].get(field_name) - } - lines[key].append(data) - return lines - -def process_data(cr, uid, pool, res_ids, model, method, old_values=None, new_values=None, field_list=None): - """ - This function processes and iterates recursively to log the difference between the old - data (i.e before the method was executed) and the new data and creates audittrail log - accordingly. - - :param cr: the current row, from the database cursor, - :param uid: the current user’s ID, - :param pool: current db's pooler object. - :param res_ids: Id's of resource to be logged/compared. - :param model: model object which values are being changed - :param method: method to log: create, read, unlink, write, actions, workflow actions - :param old_values: dict of values read before execution of the method - :param new_values: dict of values read after execution of the method - :param field_list: optional argument containing the list of fields to log. Currently only - used when performing a read, it could be usefull later on if we want to log the write - on specific fields only. - :return: True - """ - if field_list is None: - field_list = [] - # loop on all the given ids - for res_id in res_ids: - # compare old and new values and get audittrail log lines accordingly - lines = prepare_audittrail_log_line(cr, uid, pool, model, res_id, method, old_values, new_values, field_list) - - # if at least one modification has been found - for model_id, resource_id in lines: - line_model = pool.get('ir.model').browse(cr, SUPERUSER_ID, model_id).model - - vals = { - 'method': method, - 'object_id': model_id, - 'user_id': uid, - 'res_id': resource_id, - } - if (model_id, resource_id) not in old_values and method not in ('copy', 'read'): - # the resource was not existing so we are forcing the method to 'create' - # (because it could also come with the value 'write' if we are creating - # new record through a one2many field) - vals.update({'method': 'create'}) - if (model_id, resource_id) not in new_values and method not in ('copy', 'read'): - # the resource is not existing anymore so we are forcing the method to 'unlink' - # (because it could also come with the value 'write' if we are deleting the - # record through a one2many field) - name = old_values[(model_id, resource_id)]['value'].get('name',False) - vals.update({'method': 'unlink'}) - else : - name = pool[line_model].name_get(cr, uid, [resource_id])[0][1] - vals.update({'name': name}) - # create the audittrail log in super admin mode, only if a change has been detected - if lines[(model_id, resource_id)]: - log_id = pool.get('audittrail.log').create(cr, SUPERUSER_ID, vals) - model = pool.get('ir.model').browse(cr, uid, model_id) - create_log_line(cr, SUPERUSER_ID, log_id, model, lines[(model_id, resource_id)]) - return True - -def check_rules(cr, uid, model, method): - """ - Checks if auditrails is installed for that db and then if one rule match - @param cr: the current row, from the database cursor, - @param uid: the current user’s ID, - @param model: value of _name of the object which values are being changed - @param method: method to log: create, read, unlink,write,actions,workflow actions - @return: True or False - """ - pool = openerp.registry(cr.dbname) - if 'audittrail.rule' in pool.models: - model_ids = pool.get('ir.model').search(cr, SUPERUSER_ID, [('model', '=', model)]) - model_id = model_ids and model_ids[0] or False - if model_id: - rule_ids = pool.get('audittrail.rule').search(cr, SUPERUSER_ID, [('object_id', '=', model_id), ('state', '=', 'subscribed')]) - for rule in pool.get('audittrail.rule').read(cr, SUPERUSER_ID, rule_ids, ['user_id','log_read','log_write','log_create','log_unlink','log_action','log_workflow']): - if len(rule['user_id']) == 0 or uid in rule['user_id']: - if rule.get('log_'+method,0): - return True - elif method not in ('default_get','read','fields_view_get','fields_get','search','search_count','name_search','name_get','get','request_get', 'get_sc', 'unlink', 'write', 'create', 'read_group', 'import_data'): - if rule['log_action']: - return True - -# Replace the openerp.service.model functions. - -original_execute_cr = openerp.service.model.execute_cr -original_exec_workflow_cr = openerp.service.model.exec_workflow_cr - -def execute_cr(cr, uid, model, method, *args, **kw): - fct_src = original_execute_cr - if check_rules(cr,uid,model,method): - return log_fct(cr, uid, model, method, fct_src, *args, **kw) - return fct_src(cr, uid, model, method, *args, **kw) - -def exec_workflow_cr(cr, uid, model, method, *args, **kw): - fct_src = original_exec_workflow_cr - if check_rules(cr,uid,model,'workflow'): - return log_fct(cr, uid, model, method, fct_src, *args, **kw) - return fct_src(cr, uid, model, method, *args, **kw) - -openerp.service.model.execute_cr = execute_cr -openerp.service.model.exec_workflow_cr = exec_workflow_cr - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/addons/audittrail/audittrail_demo.xml b/addons/audittrail/audittrail_demo.xml deleted file mode 100644 index fbf925fb239..00000000000 --- a/addons/audittrail/audittrail_demo.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - Audit on Partners - - - - - diff --git a/addons/audittrail/audittrail_view.xml b/addons/audittrail/audittrail_view.xml deleted file mode 100644 index 5ea15ab557b..00000000000 --- a/addons/audittrail/audittrail_view.xml +++ /dev/null @@ -1,185 +0,0 @@ - - - - - - - - - - audittrail.rule.form - audittrail.rule - -
-
-
- - - - - - - - - - - - - - - -
-
-
- - - audittrail.rule.tree - audittrail.rule - - - - - - - - - - - - - - - - - audittrail.rule.search - audittrail.rule - - - - - - - - - - - - - - - Audit Rules - audittrail.rule - ir.actions.act_window - form - tree,form - {'search_default_draft': 1} - - - - - - - - - audittrail.log.form - audittrail.log - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
-
- - - audittrail.log.tree - audittrail.log - - - - - - - - - - - - - audittrail.log.search - audittrail.log - - - - - - - - - - - - - - - - Audit Logs - audittrail.log - form - - - - - -
-
diff --git a/addons/audittrail/security/ir.model.access.csv b/addons/audittrail/security/ir.model.access.csv deleted file mode 100644 index 1d2198fd661..00000000000 --- a/addons/audittrail/security/ir.model.access.csv +++ /dev/null @@ -1,5 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_audittrail_rule_all_users,audittrail rule all,model_audittrail_rule,base.group_system,1,1,1,0 -access_audittrail_rule_all_access,audittrail rule all,model_audittrail_rule,base.group_erp_manager,1,1,1,0 -access_audittrail_log_all_users,audittrail log all,model_audittrail_log,base.group_user,1,0,1,0 -access_audittrail_log_line_all_users,audittrail log line all,model_audittrail_log_line,base.group_user,1,0,1,0 diff --git a/addons/audittrail/wizard/__init__.py b/addons/audittrail/wizard/__init__.py deleted file mode 100644 index 9b2af466a01..00000000000 --- a/addons/audittrail/wizard/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (). -# -# 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 . -# -############################################################################## - -import audittrail_view_log -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/addons/audittrail/wizard/audittrail_view_log.py b/addons/audittrail/wizard/audittrail_view_log.py deleted file mode 100644 index 4385970f8d9..00000000000 --- a/addons/audittrail/wizard/audittrail_view_log.py +++ /dev/null @@ -1,65 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (). -# -# 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 . -# -############################################################################## - -from openerp.osv import fields, osv -import time - -class audittrail_view_log(osv.osv_memory): - - _name = "audittrail.view.log" - _description = "View Log" - _columns = { - 'from':fields.datetime('Log From'), - 'to':fields.datetime('Log To', required = True) - } - _defaults = { - 'to': lambda *a: time.strftime("%Y-%m-%d %H:%M:%S"), - } - - def log_open_window(self, cr, uid, ids, context=None): - """ - Open Log form from given date range.. - @param cr: the current row, from the database cursor, - @param uid: the current user’s ID for security checks, - @param ids: List of audittrail view log’s IDs. - @return: Dictionary of audittrail log form on given date range. - """ - - mod_obj = self.pool.get('ir.model.data') - act_obj = self.pool.get('ir.actions.act_window') - result = mod_obj._get_id(cr, uid, 'audittrail', 'action_audittrail_log_tree') - id = mod_obj.read(cr, uid, [result], ['res_id'], context=context)[0]['res_id'] - result = act_obj.read(cr, uid, [id], context=context)[0] - - #start Loop - for datas in self.read(cr, uid, ids, context=context): - if not datas.get('from', None): - if datas.get('to') <> time.strftime("%Y-%m-%d %H:%M:%S"): - result['domain'] = str([('timestamp', '<', datas.get('to'))]) - else: - pass - else: - result['domain'] = str([('timestamp', '>', datas.get('from', None)), ('timestamp', '<', datas.get('to'))]) - #End Loop - return result - - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/audittrail/wizard/audittrail_view_log_view.xml b/addons/audittrail/wizard/audittrail_view_log_view.xml deleted file mode 100644 index 414527bdbb0..00000000000 --- a/addons/audittrail/wizard/audittrail_view_log_view.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - audittrail.view.log.form - audittrail.view.log - -
- - - - -
-
-
-
-
- - - - - View log - audittrail.view.log - form - tree,form - - new - - -
-
From 95a9bccb380a0eed8f7904dab61e99721457c4b6 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Fri, 25 Apr 2014 01:52:54 +0200 Subject: [PATCH 5/6] [REM] move project_long_term to extra bzr revid: al@openerp.com-20140424235254-u2um2dsth6igvb7r --- addons/project_long_term/__init__.py | 25 -- addons/project_long_term/__openerp__.py | 63 --- addons/project_long_term/project_long_term.py | 296 -------------- .../project_long_term_data.xml | 5 - .../project_long_term_demo.xml | 111 ----- .../project_long_term_report.xml | 9 - .../project_long_term_view.xml | 387 ------------------ .../project_long_term_workflow.xml | 110 ----- .../security/ir.model.access.csv | 9 - .../project_long_term/test/phase_process.yml | 79 ---- .../project_long_term/test/task_process.yml | 19 - addons/project_long_term/wizard/__init__.py | 25 -- .../wizard/project_compute_phases.py | 76 ---- .../wizard/project_compute_phases_view.xml | 39 -- .../wizard/project_compute_tasks.py | 63 --- .../wizard/project_compute_tasks_view.xml | 36 -- 16 files changed, 1352 deletions(-) delete mode 100644 addons/project_long_term/__init__.py delete mode 100644 addons/project_long_term/__openerp__.py delete mode 100644 addons/project_long_term/project_long_term.py delete mode 100644 addons/project_long_term/project_long_term_data.xml delete mode 100644 addons/project_long_term/project_long_term_demo.xml delete mode 100644 addons/project_long_term/project_long_term_report.xml delete mode 100644 addons/project_long_term/project_long_term_view.xml delete mode 100644 addons/project_long_term/project_long_term_workflow.xml delete mode 100644 addons/project_long_term/security/ir.model.access.csv delete mode 100644 addons/project_long_term/test/phase_process.yml delete mode 100644 addons/project_long_term/test/task_process.yml delete mode 100644 addons/project_long_term/wizard/__init__.py delete mode 100644 addons/project_long_term/wizard/project_compute_phases.py delete mode 100644 addons/project_long_term/wizard/project_compute_phases_view.xml delete mode 100644 addons/project_long_term/wizard/project_compute_tasks.py delete mode 100644 addons/project_long_term/wizard/project_compute_tasks_view.xml diff --git a/addons/project_long_term/__init__.py b/addons/project_long_term/__init__.py deleted file mode 100644 index 6b9b2613f3f..00000000000 --- a/addons/project_long_term/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (). -# -# 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 . -# -############################################################################## - -import project_long_term -import wizard - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_long_term/__openerp__.py b/addons/project_long_term/__openerp__.py deleted file mode 100644 index 3a3307d2898..00000000000 --- a/addons/project_long_term/__openerp__.py +++ /dev/null @@ -1,63 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (). -# -# 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 . -# -############################################################################## - -{ - 'name': 'Long Term Projects', - 'version': '1.1', - 'author': 'OpenERP SA', - 'website': 'http://www.openerp.com', - 'category': 'Project Management', - 'images': ['images/project_phase_form.jpeg','images/project_phases.jpeg', 'images/resources_allocation.jpeg'], - 'depends': ['project'], - 'description': """ -Long Term Project management module that tracks planning, scheduling, resources allocation. -=========================================================================================== - -Features: ---------- - * Manage Big project - * Define various Phases of Project - * Compute Phase Scheduling: Compute start date and end date of the phases - which are in draft, open and pending state of the project given. If no - project given then all the draft, open and pending state phases will be taken. - * Compute Task Scheduling: This works same as the scheduler button on - project.phase. It takes the project as argument and computes all the open, - draft and pending tasks. - * Schedule Tasks: All the tasks which are in draft, pending and open state - are scheduled with taking the phase's start date. - """, - 'demo': ['project_long_term_demo.xml'], - 'test': [ - 'test/phase_process.yml', - 'test/task_process.yml', - ], - 'data': [ - 'security/ir.model.access.csv', - 'project_long_term_view.xml', - 'project_long_term_workflow.xml', - 'wizard/project_compute_phases_view.xml', - 'wizard/project_compute_tasks_view.xml', - ], - 'installable': True, - 'auto_install': False, -} - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py deleted file mode 100644 index 29e94591094..00000000000 --- a/addons/project_long_term/project_long_term.py +++ /dev/null @@ -1,296 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (). -# -# 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 . -# -############################################################################## - -from datetime import datetime -from openerp.tools.translate import _ -from openerp.osv import fields, osv -from openerp.addons.resource.faces import task as Task - -class project_phase(osv.osv): - _name = "project.phase" - _description = "Project Phase" - - def _check_recursion(self, cr, uid, ids, context=None): - if context is None: - context = {} - - data_phase = self.browse(cr, uid, ids[0], context=context) - prev_ids = data_phase.previous_phase_ids - next_ids = data_phase.next_phase_ids - # it should neither be in prev_ids nor in next_ids - if (data_phase in prev_ids) or (data_phase in next_ids): - return False - ids = [id for id in prev_ids if id in next_ids] - # both prev_ids and next_ids must be unique - if ids: - return False - # unrelated project - prev_ids = [rec.id for rec in prev_ids] - next_ids = [rec.id for rec in next_ids] - # iter prev_ids - while prev_ids: - cr.execute('SELECT distinct prv_phase_id FROM project_phase_rel WHERE next_phase_id IN %s', (tuple(prev_ids),)) - prv_phase_ids = filter(None, map(lambda x: x[0], cr.fetchall())) - if data_phase.id in prv_phase_ids: - return False - ids = [id for id in prv_phase_ids if id in next_ids] - if ids: - return False - prev_ids = prv_phase_ids - # iter next_ids - while next_ids: - cr.execute('SELECT distinct next_phase_id FROM project_phase_rel WHERE prv_phase_id IN %s', (tuple(next_ids),)) - next_phase_ids = filter(None, map(lambda x: x[0], cr.fetchall())) - if data_phase.id in next_phase_ids: - return False - ids = [id for id in next_phase_ids if id in prev_ids] - if ids: - return False - next_ids = next_phase_ids - return True - - def _check_dates(self, cr, uid, ids, context=None): - for phase in self.read(cr, uid, ids, ['date_start', 'date_end'], context=context): - if phase['date_start'] and phase['date_end'] and phase['date_start'] > phase['date_end']: - return False - return True - - def _compute_progress(self, cr, uid, ids, field_name, arg, context=None): - res = {} - if not ids: - return res - for phase in self.browse(cr, uid, ids, context=context): - if phase.state=='done': - res[phase.id] = 100.0 - continue - elif phase.state=="cancelled": - res[phase.id] = 0.0 - continue - elif not phase.task_ids: - res[phase.id] = 0.0 - continue - - tot = done = 0.0 - for task in phase.task_ids: - tot += task.total_hours - done += min(task.effective_hours, task.total_hours) - - if not tot: - res[phase.id] = 0.0 - else: - res[phase.id] = round(100.0 * done / tot, 2) - return res - - _columns = { - 'name': fields.char("Name", size=64, required=True), - 'date_start': fields.datetime('Start Date', select=True, help="It's computed by the scheduler according the project date or the end date of the previous phase.", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), - 'date_end': fields.datetime('End Date', help=" It's computed by the scheduler according to the start date and the duration.", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), - 'constraint_date_start': fields.datetime('Minimum Start Date', help='force the phase to start after this date', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), - 'constraint_date_end': fields.datetime('Deadline', help='force the phase to finish before this date', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), - 'project_id': fields.many2one('project.project', 'Project', required=True, select=True), - 'next_phase_ids': fields.many2many('project.phase', 'project_phase_rel', 'prv_phase_id', 'next_phase_id', 'Next Phases', states={'cancelled':[('readonly',True)]}), - 'previous_phase_ids': fields.many2many('project.phase', 'project_phase_rel', 'next_phase_id', 'prv_phase_id', 'Previous Phases', states={'cancelled':[('readonly',True)]}), - 'sequence': fields.integer('Sequence', select=True, help="Gives the sequence order when displaying a list of phases."), - 'duration': fields.float('Duration', required=True, help="By default in days", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), - 'product_uom': fields.many2one('product.uom', 'Duration Unit of Measure', required=True, help="Unit of Measure (Unit of Measure) is the unit of measurement for Duration", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), - 'task_ids': fields.one2many('project.task', 'phase_id', "Project Tasks", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), - 'user_force_ids': fields.many2many('res.users', string='Force Assigned Users'), - 'user_ids': fields.one2many('project.user.allocation', 'phase_id', "Assigned Users",states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}, - help="The resources on the project can be computed automatically by the scheduler."), - 'state': fields.selection([('draft', 'New'), ('cancelled', 'Cancelled'),('open', 'In Progress'), ('pending', 'Pending'), ('done', 'Done')], 'Status', readonly=True, required=True, - help='If the phase is created the status \'Draft\'.\n If the phase is started, the status becomes \'In Progress\'.\n If review is needed the phase is in \'Pending\' status.\ - \n If the phase is over, the status is set to \'Done\'.'), - 'progress': fields.function(_compute_progress, string='Progress', help="Computed based on related tasks"), - } - _defaults = { - 'state': 'draft', - 'sequence': 10, - } - _order = "project_id, date_start, sequence" - _constraints = [ - (_check_recursion,'Loops in phases not allowed',['next_phase_ids', 'previous_phase_ids']), - (_check_dates, 'Phase start-date must be lower than phase end-date.', ['date_start', 'date_end']), - ] - - def onchange_project(self, cr, uid, ids, project, context=None): - return {} - - def copy(self, cr, uid, id, default=None, context=None): - if default is None: - default = {} - if not default.get('name', False): - default.update(name=_('%s (copy)') % (self.browse(cr, uid, id, context=context).name)) - return super(project_phase, self).copy(cr, uid, id, default, context) - - def set_draft(self, cr, uid, ids, *args): - self.write(cr, uid, ids, {'state': 'draft'}) - return True - - def set_open(self, cr, uid, ids, *args): - self.write(cr, uid, ids, {'state': 'open'}) - return True - - def set_pending(self, cr, uid, ids, *args): - self.write(cr, uid, ids, {'state': 'pending'}) - return True - - def set_cancel(self, cr, uid, ids, *args): - self.write(cr, uid, ids, {'state': 'cancelled'}) - return True - - def set_done(self, cr, uid, ids, *args): - self.write(cr, uid, ids, {'state': 'done'}) - return True - - def generate_phase(self, cr, uid, phases, context=None): - context = context or {} - result = "" - - task_pool = self.pool.get('project.task') - for phase in phases: - if phase.state in ('done','cancelled'): - continue - # FIXME: brittle and not working if context['lang'] != 'en_US' - duration_uom = { - 'day(s)': 'd', 'days': 'd', 'day': 'd', 'd':'d', - 'month(s)': 'm', 'months': 'm', 'month':'month', 'm':'m', - 'week(s)': 'w', 'weeks': 'w', 'week': 'w', 'w':'w', - 'hour(s)': 'H', 'hours': 'H', 'hour': 'H', 'h':'H', - }.get(phase.product_uom.name.lower(), "H") - duration = str(phase.duration) + duration_uom - result += ''' - def Phase_%s(): - effort = \"%s\"''' % (phase.id, duration) - start = [] - if phase.constraint_date_start: - start.append('datetime.datetime.strptime("'+str(phase.constraint_date_start)+'", "%Y-%m-%d %H:%M:%S")') - for previous_phase in phase.previous_phase_ids: - start.append("up.Phase_%s.end" % (previous_phase.id,)) - if start: - result += ''' - start = max(%s) -''' % (','.join(start)) - - if phase.user_force_ids: - result += ''' - resource = %s -''' % '|'.join(map(lambda x: 'User_'+str(x.id), phase.user_force_ids)) - - result += task_pool._generate_task(cr, uid, phase.task_ids, ident=8, context=context) - result += "\n" - - return result - -class project_user_allocation(osv.osv): - _name = 'project.user.allocation' - _description = 'Phase User Allocation' - _rec_name = 'user_id' - _columns = { - 'user_id': fields.many2one('res.users', 'User', required=True), - 'phase_id': fields.many2one('project.phase', 'Project Phase', ondelete='cascade', required=True), - 'project_id': fields.related('phase_id', 'project_id', type='many2one', relation="project.project", string='Project', store=True), - 'date_start': fields.datetime('Start Date', help="Starting Date"), - 'date_end': fields.datetime('End Date', help="Ending Date"), - } - -class project(osv.osv): - _inherit = "project.project" - - def _phase_count(self, cr, uid, ids, field_name, arg, context=None): - res = dict.fromkeys(ids, 0) - phase_ids = self.pool.get('project.phase').search(cr, uid, [('project_id', 'in', ids)]) - for phase in self.pool.get('project.phase').browse(cr, uid, phase_ids, context): - res[phase.project_id.id] += 1 - return res - - _columns = { - 'phase_ids': fields.one2many('project.phase', 'project_id', "Project Phases"), - 'phase_count': fields.function(_phase_count, type='integer', string="Open Phases"), - } - - def schedule_phases(self, cr, uid, ids, context=None): - context = context or {} - if type(ids) in (long, int,): - ids = [ids] - projects = self.browse(cr, uid, ids, context=context) - result = self._schedule_header(cr, uid, ids, context=context) - for project in projects: - result += self._schedule_project(cr, uid, project, context=context) - result += self.pool.get('project.phase').generate_phase(cr, uid, project.phase_ids, context=context) - - local_dict = {} - exec result in local_dict - projects_gantt = Task.BalancedProject(local_dict['Project']) - - for project in projects: - project_gantt = getattr(projects_gantt, 'Project_%d' % (project.id,)) - for phase in project.phase_ids: - if phase.state in ('done','cancelled'): - continue - # Maybe it's better to update than unlink/create if it already exists ? - p = getattr(project_gantt, 'Phase_%d' % (phase.id,)) - - self.pool.get('project.user.allocation').unlink(cr, uid, - [x.id for x in phase.user_ids], - context=context - ) - - for r in p.booked_resource: - self.pool.get('project.user.allocation').create(cr, uid, { - 'user_id': int(r.name[5:]), - 'phase_id': phase.id, - 'date_start': p.start.strftime('%Y-%m-%d %H:%M:%S'), - 'date_end': p.end.strftime('%Y-%m-%d %H:%M:%S') - }, context=context) - self.pool.get('project.phase').write(cr, uid, [phase.id], { - 'date_start': p.start.strftime('%Y-%m-%d %H:%M:%S'), - 'date_end': p.end.strftime('%Y-%m-%d %H:%M:%S') - }, context=context) - return True - -class account_analytic_account(osv.osv): - _inherit = 'account.analytic.account' - _description = 'Analytic Account' - _columns = { - 'use_phases': fields.boolean('Phases', help="Check this field if you plan to use phase-based scheduling"), - } - - def on_change_template(self, cr, uid, ids, template_id, date_start=False, context=None): - res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, date_start=date_start, context=context) - if template_id and 'value' in res: - template = self.browse(cr, uid, template_id, context=context) - res['value']['use_phases'] = template.use_phases - return res - - - def _trigger_project_creation(self, cr, uid, vals, context=None): - if context is None: context = {} - res = super(account_analytic_account, self)._trigger_project_creation(cr, uid, vals, context=context) - return res or (vals.get('use_phases') and not 'project_creation_in_progress' in context) - - -class project_task(osv.osv): - _inherit = "project.task" - _columns = { - 'phase_id': fields.many2one('project.phase', 'Project Phase', domain="[('project_id', '=', project_id)]"), - } - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_long_term/project_long_term_data.xml b/addons/project_long_term/project_long_term_data.xml deleted file mode 100644 index ebc084668b7..00000000000 --- a/addons/project_long_term/project_long_term_data.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/addons/project_long_term/project_long_term_demo.xml b/addons/project_long_term/project_long_term_demo.xml deleted file mode 100644 index fda481d5a11..00000000000 --- a/addons/project_long_term/project_long_term_demo.xml +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - - - - - - - Collect Requirement and Make SRS - - - 30 - - - - - - - - - Design Model - - - 20 - - - - - - - Planning and compute Risk analysis, Time chart - - - 20 - - - - - - - Development and Integration - - - 90 - - - - - - Review and Testing - - - 30 - - - - - - Deployement and Training - - - 10 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/addons/project_long_term/project_long_term_report.xml b/addons/project_long_term/project_long_term_report.xml deleted file mode 100644 index d8fe2a4fa6e..00000000000 --- a/addons/project_long_term/project_long_term_report.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/addons/project_long_term/project_long_term_view.xml b/addons/project_long_term/project_long_term_view.xml deleted file mode 100644 index 36fb83000ce..00000000000 --- a/addons/project_long_term/project_long_term_view.xml +++ /dev/null @@ -1,387 +0,0 @@ - - - - - - - - - project.user.allocation.gantt - project.user.allocation - - - - - - - - project.user.allocation.calendar - project.user.allocation - - - - - - - - - - - - project.user.allocation.form - project.user.allocation - -
- - - - - - - -
-
-
- - - project.user.allocation.list - project.user.allocation - - - - - - - - - - - - project.user.allocation.search - project.user.allocation - - - - - - - - - - - - - - - Team Planning - project.user.allocation - form - gantt,tree,form,calendar - {} - - - - - - - - project.phase - form - Phases - tree,form - {'search_default_project_id': [active_id], 'default_project_id': active_id} - - - - Inherit project form : Phase - project.project - - - - - - -