[MERGE] forward port of branch 7.0 up to 5035c76
authorDenis Ledoux <dle@odoo.com>
Tue, 4 Nov 2014 11:19:58 +0000 (12:19 +0100)
committerDenis Ledoux <dle@odoo.com>
Tue, 4 Nov 2014 11:19:58 +0000 (12:19 +0100)
.gitignore
addons/account/account_invoice.py
addons/base_action_rule/base_action_rule.py
addons/product/product.py
addons/project_issue/project_issue.py
addons/stock/stock.py
addons/web/static/lib/cleditor/jquery.cleditor.js
addons/web/static/src/js/view_form.js

index 7828a60..68382f2 100644 (file)
@@ -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
index 79fa7a4..70d644d 100644 (file)
@@ -857,7 +857,7 @@ class account_invoice(osv.osv):
             for tax in inv.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 not key in compute_taxes:
                     raise osv.except_osv(_('Warning!'), _('Global taxes defined, but they are not in invoice lines !'))
@@ -1770,7 +1770,15 @@ class account_invoice_tax(osv.osv):
                     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:
index e74e719..91433b2 100644 (file)
@@ -219,8 +219,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'):
                 model_obj.create = self._wrap_create(model_obj.create, model)
                 model_obj.write = self._wrap_write(model_obj.write, model)
                 model_obj.base_action_ruled = True
index 0c08dbb..2110f24 100644 (file)
@@ -821,6 +821,7 @@ class product_product(osv.osv):
             price_type_currency_id = pricetype_obj.browse(cr,uid,price_type_id).currency_id.id
 
         res = {}
+        company_id = self.pool['res.users'].read(cr, uid, uid, ['company_id'], context=context)['company_id'][0]
         # standard_price field can only be seen by users in base.group_user
         # Thus, in order to compute the sale price from the cost price for users not in this group
         # We fetch the standard price as the superuser
@@ -828,7 +829,7 @@ class product_product(osv.osv):
             if ptype != 'standard_price':
                 res[product.id] = product[ptype] or 0.0
             else: 
-                res[product.id] = self.read(cr, SUPERUSER_ID, product.id, [ptype], context=context)[ptype] or 0.0
+                res[product.id] = self.read(cr, SUPERUSER_ID, product.id, [ptype], context=dict(context, force_company=company_id))[ptype] or 0.0
 
         product_uom_obj = self.pool.get('product.uom')
         for product in products:
index c3fa1eb..691a9fd 100644 (file)
@@ -287,7 +287,7 @@ class project_issue(osv.Model):
         'progress': fields.function(_hours_get, string='Progress (%)', multi='hours', group_operator="avg", help="Computed as: Time Spent / Total Time.",
             store = {
                 'project.issue': (lambda self, cr, uid, ids, c={}: ids, ['task_id'], 10),
-                'project.task': (_get_issue_task, ['progress'], 10),
+                'project.task': (_get_issue_task, ['work_ids', 'remaining_hours', 'planned_hours', 'state', 'stage_id'], 10),
                 'project.task.work': (_get_issue_work, ['hours'], 10),
             }),
     }
index ee9437a..e075c17 100644 (file)
@@ -721,8 +721,8 @@ class stock_picking(osv.osv):
         if ('name' not in default) or (picking_obj.name == '/'):
             seq_obj_name = 'stock.picking.' + picking_obj.type
             default['name'] = self.pool.get('ir.sequence').get(cr, uid, seq_obj_name)
-            default['origin'] = ''
-            default['backorder_id'] = False
+            default.setdefault('origin', False)
+            default.setdefault('backorder_id', False)
         if 'invoice_state' not in default and picking_obj.invoice_state == 'invoiced':
             default['invoice_state'] = '2binvoiced'
         res = super(stock_picking, self).copy(cr, uid, id, default, context)
@@ -1241,7 +1241,7 @@ class stock_picking(osv.osv):
                 partial_data = partial_datas.get('move%s'%(move.id), {})
                 product_qty = partial_data.get('product_qty',0.0)
                 move_product_qty[move.id] = product_qty
-                product_uom = partial_data.get('product_uom',False)
+                product_uom = partial_data.get('product_uom', move.product_uom.id)
                 product_price = partial_data.get('product_price',0.0)
                 product_currency = partial_data.get('product_currency',False)
                 prodlot_id = partial_data.get('prodlot_id')
index cf98288..5a30d29 100644 (file)
 \r
   // change - shortcut for .bind("change", handler) or .trigger("change")\r
   fn.change = function change(handler) {\r
-    console.log('change test');\r
     var $this = $(this);\r
     return handler ? $this.bind(CHANGE, handler) : $this.trigger(CHANGE);\r
   };\r
index 96c821a..db75e1e 100644 (file)
@@ -4105,28 +4105,23 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({
         this.o2m.trigger_on_change();
     },
     is_valid: function () {
-        var editor = this.editor;
-        var form = editor.form;
-        // If no edition is pending, the listview can not be invalid (?)
-        if (!editor.record) {
-            return true;
-        }
-        // If the form has not been modified, the view can only be valid
-        // NB: is_dirty will also be set on defaults/onchanges/whatever?
-        // oe_form_dirty seems to only be set on actual user actions
-        if (!form.$el.is('.oe_form_dirty')) {
+        var self = this;
+        if (!this.editable()){
             return true;
         }
         this.o2m._dirty_flag = true;
-
-        // Otherwise validate internal form
-        return _(form.fields).chain()
-            .invoke(function () {
-                this._check_css_flags();
-                return this.is_valid();
-            })
-            .all(_.identity)
-            .value();
+        var r;
+        return _.every(this.records.records, function(record){
+            r = record;
+            _.each(self.editor.form.fields, function(field){
+                field.set_value(r.attributes[field.name]);
+            });
+            return _.every(self.editor.form.fields, function(field){
+                field.process_modifiers();
+                field._check_css_flags();
+                return field.is_valid();
+            });
+        });
     },
     do_add_record: function () {
         if (this.editable()) {