diff --git a/.gitignore b/.gitignore
index 4c3277c5215..2f01ce29ff4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,9 @@ _build/
status
# odoo filestore
openerp/filestore
+# maintenance migration scripts
+openerp/addons/base/maintenance
+
# generated for windows installer?
install/win32/*.bat
install/win32/meta.py
diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py
index f7d372e2750..31015ebd41c 100644
--- a/addons/account/account_invoice.py
+++ b/addons/account/account_invoice.py
@@ -720,7 +720,7 @@ class account_invoice(models.Model):
for tax in self.tax_line:
if tax.manual:
continue
- key = (tax.tax_code_id.id, tax.base_code_id.id, tax.account_id.id, tax.account_analytic_id.id)
+ key = (tax.tax_code_id.id, tax.base_code_id.id, tax.account_id.id)
tax_key.append(key)
if key not in compute_taxes:
raise except_orm(_('Warning!'), _('Global taxes defined, but they are not in invoice lines !'))
@@ -1560,7 +1560,15 @@ class account_invoice_tax(models.Model):
val['account_id'] = tax['account_paid_id'] or line.account_id.id
val['account_analytic_id'] = tax['account_analytic_paid_id']
- key = (val['tax_code_id'], val['base_code_id'], val['account_id'], val['account_analytic_id'])
+ # If the taxes generate moves on the same financial account as the invoice line
+ # and no default analytic account is defined at the tax level, propagate the
+ # analytic account from the invoice line to the tax line. This is necessary
+ # in situations were (part of) the taxes cannot be reclaimed,
+ # to ensure the tax move is allocated to the proper analytic account.
+ if not val.get('account_analytic_id') and line.account_analytic_id and val['account_id'] == line.account_id.id:
+ val['account_analytic_id'] = line.account_analytic_id.id
+
+ key = (val['tax_code_id'], val['base_code_id'], val['account_id'])
if not key in tax_grouped:
tax_grouped[key] = val
else:
diff --git a/addons/base_action_rule/base_action_rule.py b/addons/base_action_rule/base_action_rule.py
index 864d283d89f..ac95da93534 100644
--- a/addons/base_action_rule/base_action_rule.py
+++ b/addons/base_action_rule/base_action_rule.py
@@ -230,8 +230,8 @@ class base_action_rule(osv.osv):
ids = self.search(cr, SUPERUSER_ID, [])
for action_rule in self.browse(cr, SUPERUSER_ID, ids):
model = action_rule.model_id.model
- model_obj = self.pool[model]
- if not hasattr(model_obj, 'base_action_ruled'):
+ model_obj = self.pool.get(model)
+ if model_obj and not hasattr(model_obj, 'base_action_ruled'):
# monkey-patch methods create and write
model_obj._patch_method('create', make_create())
model_obj._patch_method('write', make_write())
diff --git a/addons/gamification/wizard/grant_badge.py b/addons/gamification/wizard/grant_badge.py
index 44f739fff4e..513a1526c8b 100644
--- a/addons/gamification/wizard/grant_badge.py
+++ b/addons/gamification/wizard/grant_badge.py
@@ -36,7 +36,6 @@ class grant_badge_wizard(osv.TransientModel):
def action_grant_badge(self, cr, uid, ids, context=None):
"""Wizard action for sending a badge to a chosen user"""
- badge_obj = self.pool.get('gamification.badge')
badge_user_obj = self.pool.get('gamification.badge.user')
for wiz in self.browse(cr, uid, ids, context=context):
@@ -51,6 +50,6 @@ class grant_badge_wizard(osv.TransientModel):
'comment': wiz.comment,
}
badge_user = badge_user_obj.create(cr, uid, values, context=context)
- result = badge_obj._send_badge(cr, uid, badge_user, context=context)
+ result = badge_user_obj._send_badge(cr, uid, badge_user, context=context)
return result
diff --git a/addons/marketing_campaign/marketing_campaign_view.xml b/addons/marketing_campaign/marketing_campaign_view.xml
index 1ba5621ff0a..7d4b3d36618 100644
--- a/addons/marketing_campaign/marketing_campaign_view.xml
+++ b/addons/marketing_campaign/marketing_campaign_view.xml
@@ -315,14 +315,14 @@
-
+