[MERGE] merge from master
This commit is contained in:
commit
fe209f9e7a
|
@ -1,3 +1,5 @@
|
|||
<a href="http://runbot.odoo.com/runbot"><img src="http://runbot.odoo.com/runbot/badge/1/master.svg"/></a>
|
||||
|
||||
Odoo
|
||||
----
|
||||
|
||||
|
|
|
@ -1546,7 +1546,7 @@ class account_invoice_line(osv.osv):
|
|||
context = dict(context)
|
||||
context.update({'company_id': company_id})
|
||||
warning = {}
|
||||
res = self.product_id_change(cr, uid, ids, product, uom, qty, name, type, partner_id, fposition_id, price_unit, currency_id, context=context)
|
||||
res = self.product_id_change(cr, uid, ids, product, uom, qty, name, type, partner_id, fposition_id, price_unit, currency_id, context=context, company_id=company_id)
|
||||
if not uom:
|
||||
res['value']['price_unit'] = 0.0
|
||||
if product and uom:
|
||||
|
|
|
@ -39,7 +39,7 @@ class account_analytic_default(osv.osv):
|
|||
'date_stop': fields.date('End Date', help="Default end date for this Analytic Account."),
|
||||
}
|
||||
|
||||
def account_get(self, cr, uid, product_id=None, partner_id=None, user_id=None, date=None, context=None):
|
||||
def account_get(self, cr, uid, product_id=None, partner_id=None, user_id=None, date=None, company_id=None, context=None):
|
||||
domain = []
|
||||
if product_id:
|
||||
domain += ['|', ('product_id', '=', product_id)]
|
||||
|
@ -47,6 +47,9 @@ class account_analytic_default(osv.osv):
|
|||
if partner_id:
|
||||
domain += ['|', ('partner_id', '=', partner_id)]
|
||||
domain += [('partner_id', '=', False)]
|
||||
if company_id:
|
||||
domain += ['|', ('company_id', '=', company_id)]
|
||||
domain += [('company_id', '=', False)]
|
||||
if user_id:
|
||||
domain += ['|',('user_id', '=', user_id)]
|
||||
domain += [('user_id','=', False)]
|
||||
|
@ -59,6 +62,7 @@ class account_analytic_default(osv.osv):
|
|||
index = 0
|
||||
if rec.product_id: index += 1
|
||||
if rec.partner_id: index += 1
|
||||
if rec.company_id: index += 1
|
||||
if rec.user_id: index += 1
|
||||
if rec.date_start: index += 1
|
||||
if rec.date_stop: index += 1
|
||||
|
@ -74,7 +78,7 @@ class account_invoice_line(osv.osv):
|
|||
|
||||
def product_id_change(self, cr, uid, ids, product, uom_id, qty=0, name='', type='out_invoice', partner_id=False, fposition_id=False, price_unit=False, currency_id=False, context=None, company_id=None):
|
||||
res_prod = super(account_invoice_line, self).product_id_change(cr, uid, ids, product, uom_id, qty, name, type, partner_id, fposition_id, price_unit, currency_id=currency_id, context=context, company_id=company_id)
|
||||
rec = self.pool.get('account.analytic.default').account_get(cr, uid, product, partner_id, uid, time.strftime('%Y-%m-%d'), context=context)
|
||||
rec = self.pool.get('account.analytic.default').account_get(cr, uid, product, partner_id, uid, time.strftime('%Y-%m-%d'), company_id=company_id, context=context)
|
||||
if rec:
|
||||
res_prod['value'].update({'account_analytic_id': rec.analytic_id.id})
|
||||
else:
|
||||
|
@ -88,7 +92,7 @@ class stock_picking(osv.osv):
|
|||
|
||||
def _get_account_analytic_invoice(self, cursor, user, picking, move_line):
|
||||
partner_id = picking.partner_id and picking.partner_id.id or False
|
||||
rec = self.pool.get('account.analytic.default').account_get(cursor, user, move_line.product_id.id, partner_id , user, time.strftime('%Y-%m-%d'), context={})
|
||||
rec = self.pool.get('account.analytic.default').account_get(cursor, user, move_line.product_id.id, partner_id, user, time.strftime('%Y-%m-%d'))
|
||||
|
||||
if rec:
|
||||
return rec.analytic_id.id
|
||||
|
|
|
@ -81,7 +81,7 @@ class account_analytic_plan_line(osv.osv):
|
|||
_order = "sequence, id"
|
||||
_columns = {
|
||||
'plan_id': fields.many2one('account.analytic.plan','Analytic Plan',required=True),
|
||||
'name': fields.char('Plan Name', size=64, required=True, select=True),
|
||||
'name': fields.char('Axis Name', size=64, required=True, select=True),
|
||||
'sequence': fields.integer('Sequence'),
|
||||
'root_analytic_id': fields.many2one('account.analytic.account', 'Root Account', help="Root account of this plan.", required=False),
|
||||
'min_required': fields.float('Minimum Allowed (%)'),
|
||||
|
|
|
@ -349,10 +349,12 @@ class hr_employee(osv.osv):
|
|||
else:
|
||||
return super(hr_employee, self).get_suggested_thread(cr, uid, removed_suggested_threads, context)
|
||||
|
||||
def _message_get_auto_subscribe_fields(self, cr, uid, updated_fields, auto_follow_fields=['user_id'], context=None):
|
||||
def _message_get_auto_subscribe_fields(self, cr, uid, updated_fields, auto_follow_fields=None, context=None):
|
||||
""" Overwrite of the original method to always follow user_id field,
|
||||
even when not track_visibility so that a user will follow it's employee
|
||||
"""
|
||||
if auto_follow_fields is None:
|
||||
auto_follow_fields = ['user_id']
|
||||
user_field_lst = []
|
||||
for name, column_info in self._all_columns.items():
|
||||
if name in auto_follow_fields and name in updated_fields and column_info.column._obj == 'res.users':
|
||||
|
|
|
@ -1699,7 +1699,7 @@ class mail_thread(osv.AbstractModel):
|
|||
], context=context)
|
||||
return fol_obj.unlink(cr, SUPERUSER_ID, fol_ids, context=context)
|
||||
|
||||
def _message_get_auto_subscribe_fields(self, cr, uid, updated_fields, auto_follow_fields=['user_id'], context=None):
|
||||
def _message_get_auto_subscribe_fields(self, cr, uid, updated_fields, auto_follow_fields=None, context=None):
|
||||
""" Returns the list of relational fields linking to res.users that should
|
||||
trigger an auto subscribe. The default list checks for the fields
|
||||
- called 'user_id'
|
||||
|
@ -1710,6 +1710,8 @@ class mail_thread(osv.AbstractModel):
|
|||
Override this method if a custom behavior is needed about fields
|
||||
that automatically subscribe users.
|
||||
"""
|
||||
if auto_follow_fields is None:
|
||||
auto_follow_fields = ['user_id']
|
||||
user_field_lst = []
|
||||
for name, column_info in self._all_columns.items():
|
||||
if name in auto_follow_fields and name in updated_fields and getattr(column_info.column, 'track_visibility', False) and column_info.column._obj == 'res.users':
|
||||
|
|
|
@ -782,6 +782,7 @@ class task(osv.osv):
|
|||
'project.task': (lambda self, cr, uid, ids, c={}: ids, ['work_ids', 'remaining_hours', 'planned_hours'], 10),
|
||||
'project.task.work': (_get_task, ['hours'], 10),
|
||||
}),
|
||||
'reviewer_id': fields.many2one('res.users', 'Reviewer', select=True, track_visibility='onchange'),
|
||||
'user_id': fields.many2one('res.users', 'Assigned to', select=True, track_visibility='onchange'),
|
||||
'delegated_user_id': fields.related('child_ids', 'user_id', type='many2one', relation='res.users', string='Delegated To'),
|
||||
'partner_id': fields.many2one('res.partner', 'Customer'),
|
||||
|
@ -801,6 +802,7 @@ class task(osv.osv):
|
|||
'progress': 0,
|
||||
'sequence': 10,
|
||||
'active': True,
|
||||
'reviewer_id': lambda obj, cr, uid, ctx=None: uid,
|
||||
'user_id': lambda obj, cr, uid, ctx=None: uid,
|
||||
'company_id': lambda self, cr, uid, ctx=None: self.pool.get('res.company')._company_default_get(cr, uid, 'project.task', context=ctx),
|
||||
'partner_id': lambda self, cr, uid, ctx=None: self._get_default_partner(cr, uid, context=ctx),
|
||||
|
@ -1090,6 +1092,11 @@ class task(osv.osv):
|
|||
# Mail gateway
|
||||
# ---------------------------------------------------
|
||||
|
||||
def _message_get_auto_subscribe_fields(self, cr, uid, updated_fields, auto_follow_fields=None, context=None):
|
||||
if auto_follow_fields is None:
|
||||
auto_follow_fields = ['user_id', 'reviewer_id']
|
||||
return super(task, self)._message_get_auto_subscribe_fields(cr, uid, updated_fields, auto_follow_fields, context=context)
|
||||
|
||||
def message_get_reply_to(self, cr, uid, ids, context=None):
|
||||
""" Override to get the reply_to of the parent project. """
|
||||
return [task.project_id.message_get_reply_to()[0] if task.project_id else False
|
||||
|
|
|
@ -29,9 +29,11 @@
|
|||
help="Show only tasks having a deadline"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="project_id"/>
|
||||
<field name="reviewer_id"/>
|
||||
<field name="user_id"/>
|
||||
<field name="stage_id" domain="[]"/>
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="Reviewers" name="group_reviewer_id" domain="[]" context="{'group_by':'reviewer_id'}"/>
|
||||
<filter string="Users" name="group_user_id" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
|
||||
<filter string="Project" name="group_project_id" icon="terp-folder-violet" domain="[]" context="{'group_by':'project_id'}"/>
|
||||
<filter string="Stage" name="group_stage_id" icon="terp-stage" domain="[]" context="{'group_by':'stage_id'}"/>
|
||||
|
@ -389,6 +391,9 @@
|
|||
<field name="user_id"
|
||||
options='{"no_open": True}'
|
||||
context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'project.group_project_user']}"/>
|
||||
<field name="reviewer_id"
|
||||
options='{"no_open": True}'
|
||||
context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'project.group_project_user']}"/>
|
||||
<field name="planned_hours" widget="float_time"
|
||||
groups="project.group_time_work_estimation_tasks"
|
||||
on_change="onchange_planned(planned_hours, effective_hours)"/>
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
}
|
||||
}).then(function (val, field, $dialog) {
|
||||
if (val) {
|
||||
var url = '/website/add/' + encodeURI(val);
|
||||
var url = '/website/add/' + encodeURIComponent(val);
|
||||
if ($dialog.find('input[type="checkbox"]').is(':checked')) url +="?add_menu=1";
|
||||
document.location = url;
|
||||
}
|
||||
|
|
|
@ -214,6 +214,13 @@
|
|||
string="Readonly"
|
||||
domain="[('readonly', '=', True)]"/>
|
||||
<separator/>
|
||||
<filter
|
||||
string="Custom"
|
||||
domain="[('state', '=', 'manual')]"/>
|
||||
<filter
|
||||
string="Base"
|
||||
domain="[('state', '=', 'base')]"/>
|
||||
<separator/>
|
||||
<filter icon="terp-translate"
|
||||
string="Translate"
|
||||
domain="[('translate', '=', True)]"/>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
|
||||
# Copyright (C) 2010-2011 OpenERP s.a. (<http://openerp.com>).
|
||||
# Copyright (C) 2010-2014 OpenERP s.a. (<http://openerp.com>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
|
@ -149,7 +149,14 @@ class Graph(dict):
|
|||
level += 1
|
||||
|
||||
|
||||
class Singleton(object):
|
||||
class Node(object):
|
||||
""" One module in the modules dependency graph.
|
||||
|
||||
Node acts as a per-module singleton. A node is constructed via
|
||||
Graph.add_module() or Graph.add_modules(). Some of its fields are from
|
||||
ir_module_module (setted by Graph.update_from_db()).
|
||||
|
||||
"""
|
||||
def __new__(cls, name, graph, info):
|
||||
if name in graph:
|
||||
inst = graph[name]
|
||||
|
@ -160,22 +167,13 @@ class Singleton(object):
|
|||
graph[name] = inst
|
||||
return inst
|
||||
|
||||
|
||||
class Node(Singleton):
|
||||
""" One module in the modules dependency graph.
|
||||
|
||||
Node acts as a per-module singleton. A node is constructed via
|
||||
Graph.add_module() or Graph.add_modules(). Some of its fields are from
|
||||
ir_module_module (setted by Graph.update_from_db()).
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, name, graph, info):
|
||||
self.graph = graph
|
||||
if not hasattr(self, 'children'):
|
||||
self.children = []
|
||||
if not hasattr(self, 'depth'):
|
||||
self.depth = 0
|
||||
self.info = info or {}
|
||||
|
||||
def add_child(self, name, info):
|
||||
node = Node(name, self.graph, info)
|
||||
|
@ -189,7 +187,7 @@ class Node(Singleton):
|
|||
return node
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
super(Singleton, self).__setattr__(name, value)
|
||||
super(Node, self).__setattr__(name, value)
|
||||
if name in ('init', 'update', 'demo'):
|
||||
tools.config[name][self.name] = 1
|
||||
for child in self.children:
|
||||
|
|
|
@ -148,6 +148,13 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
|
|||
migrations.migrate_module(package, 'pre')
|
||||
load_openerp_module(package.name)
|
||||
|
||||
new_install = package.installed_version is None
|
||||
if new_install:
|
||||
py_module = sys.modules['openerp.addons.%s' % (module_name,)]
|
||||
pre_init = package.info.get('pre_init_hook')
|
||||
if pre_init:
|
||||
getattr(py_module, pre_init)(cr)
|
||||
|
||||
models = registry.load(cr, package)
|
||||
|
||||
loaded_modules.append(package.name)
|
||||
|
@ -181,6 +188,11 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
|
|||
|
||||
migrations.migrate_module(package, 'post')
|
||||
|
||||
if new_install:
|
||||
post_init = package.info.get('post_init_hook')
|
||||
if post_init:
|
||||
getattr(py_module, post_init)(cr, registry)
|
||||
|
||||
registry._init_modules.add(package.name)
|
||||
# validate all the views at a whole
|
||||
registry['ir.ui.view']._validate_module_views(cr, SUPERUSER_ID, module_name)
|
||||
|
@ -401,10 +413,17 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
|
|||
if update_module:
|
||||
# Remove records referenced from ir_model_data for modules to be
|
||||
# removed (and removed the references from ir_model_data).
|
||||
cr.execute("SELECT id FROM ir_module_module WHERE state=%s", ('to remove',))
|
||||
mod_ids_to_remove = [x[0] for x in cr.fetchall()]
|
||||
if mod_ids_to_remove:
|
||||
registry['ir.module.module'].module_uninstall(cr, SUPERUSER_ID, mod_ids_to_remove)
|
||||
cr.execute("SELECT name, id FROM ir_module_module WHERE state=%s", ('to remove',))
|
||||
modules_to_remove = dict(cr.fetchall())
|
||||
if modules_to_remove:
|
||||
pkgs = reversed([p for p in graph if p.name in modules_to_remove])
|
||||
for pkg in pkgs:
|
||||
uninstall_hook = pkg.info.get('uninstall_hook')
|
||||
if uninstall_hook:
|
||||
py_module = sys.modules['openerp.addons.%s' % (pkg.name,)]
|
||||
getattr(py_module, uninstall_hook)(cr, registry)
|
||||
|
||||
registry['ir.module.module'].module_uninstall(cr, SUPERUSER_ID, modules_to_remove.values())
|
||||
# Recursive reload, should only happen once, because there should be no
|
||||
# modules to remove next time
|
||||
cr.commit()
|
||||
|
|
Loading…
Reference in New Issue