[ADD] handling of binary fields in list views
authorXavier Morel <xmo@openerp.com>
Tue, 10 Jan 2012 15:51:06 +0000 (16:51 +0100)
committerXavier Morel <xmo@openerp.com>
Tue, 10 Jan 2012 15:51:06 +0000 (16:51 +0100)
lp bug: https://launchpad.net/bugs/914267 fixed

bzr revid: xmo@openerp.com-20120110155106-p3g85wbh5g4wlbdi

addons/account/account_invoice.py
addons/account_voucher/wizard/account_statement_from_invoice.py
addons/project/project_demo.xml
addons/report_webkit/webkit_report.py
addons/web/static/src/js/data.js
addons/web/static/src/js/view_form.js
addons/web_dashboard/static/src/js/dashboard.js
addons/web_diagram/static/src/js/diagram.js

index 9772984..166d146 100644 (file)
@@ -259,7 +259,7 @@ class account_invoice(osv.osv):
                 'account.move.reconcile': (_get_invoice_from_reconcile, None, 50),
             }, help="It indicates that the invoice has been paid and the journal entry of the invoice has been reconciled with one or several journal entries of payment."),
         'partner_bank_id': fields.many2one('res.partner.bank', 'Bank Account',
-            help='Bank Account Number, Company bank account if Invoice is customer or supplier refund, otherwise Partner bank account number.', readonly=True, states={'draft':[('readonly',False)]}),
+            help='Bank Account Number to which the invoice will be paid. A Company bank account if this is a Customer Invoice or Supplier Refund, otherwise a Partner bank account number.', readonly=True, states={'draft':[('readonly',False)]}),
         'move_lines':fields.function(_get_lines, type='many2many', relation='account.move.line', string='Entry Lines'),
         'residual': fields.function(_amount_residual, digits_compute=dp.get_precision('Account'), string='Balance',
             store={
index 5fb3fc2..1b921e0 100644 (file)
@@ -89,11 +89,10 @@ class account_statement_from_invoice_lines(osv.osv_memory):
             voucher_id = voucher_obj.create(cr, uid, voucher_res, context=context)
 
             voucher_line_dict =  {}
-            if result['value']['line_ids']:
-                for line_dict in result['value']['line_ids']:
-                    move_line = line_obj.browse(cr, uid, line_dict['move_line_id'], context)
-                    if line.move_id.id == move_line.move_id.id:
-                        voucher_line_dict = line_dict
+            for line_dict in result['value']['line_cr_ids'] + result['value']['line_dr_ids']:
+                move_line = line_obj.browse(cr, uid, line_dict['move_line_id'], context)
+                if line.move_id.id == move_line.move_id.id:
+                    voucher_line_dict = line_dict
 
             if voucher_line_dict:
                 voucher_line_dict.update({'voucher_id': voucher_id})
@@ -190,4 +189,4 @@ class account_statement_from_invoice(osv.osv_memory):
         }
 
 account_statement_from_invoice()
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
index dab7e23..28d451b 100644 (file)
@@ -72,6 +72,7 @@
 
         <record id="project_task_1" model="project.task">
             <field eval="100.0" name="planned_hours"/>
+            <field eval="100.0" name="remaining_hours"/>
             <field name="user_id" ref="base.user_niv"/>
             <field name="priority">2</field>
             <field name="project_id" ref="project.project_integrate_openerp"/>
@@ -82,6 +83,7 @@
 
         <record id="project_task_2" model="project.task">
             <field eval="80.0" name="planned_hours"/>
+            <field eval="80.0" name="remaining_hours"/>
             <field name="user_id" ref="base.user_niv"/>
             <field name="priority">2</field>
             <field name="project_id" ref="project.project_integrate_openerp"/>
@@ -91,6 +93,7 @@
 
         <record id="project_task_3" model="project.task">
             <field eval="40.0" name="planned_hours"/>
+            <field eval="40.0" name="remaining_hours"/>
             <field name="user_id" ref="base.user_al"/>
             <field name="priority">2</field>
             <field name="project_id" ref="project.project_integrate_openerp"/>
 
         <record id="project_task_4" model="project.task">
             <field eval="25.0" name="planned_hours"/>
+            <field eval="25.0" name="remaining_hours"/>
             <field name="user_id" ref="base.user_al"/>
             <field name="priority">2</field>
             <field name="project_id" ref="project.project_integrate_openerp"/>
 
         <record id="project_task_5" model="project.task">
             <field eval="25.0" name="planned_hours"/>
+            <field eval="25.0" name="remaining_hours"/>
             <field name="user_id" ref="base.user_al"/>
             <field name="priority">2</field>
             <field name="project_id" ref="project.project_integrate_openerp"/>
 
         <record id="project_task_6" model="project.task">
             <field eval="20.0" name="planned_hours"/>
+            <field eval="20.0" name="remaining_hours"/>
             <field name="user_id" ref="base.user_al"/>
             <field name="priority">2</field>
             <field name="project_id" ref="project.project_integrate_openerp"/>
 
         <record id="project_task_7" model="project.task">
             <field eval="30.0" name="planned_hours"/>
+            <field eval="30.0" name="remaining_hours"/>
             <field name="user_id" ref="base.user_al"/>
             <field name="priority">2</field>
             <field name="project_id" ref="project.project_integrate_openerp"/>
 
         <record id="project_task_8" model="project.task">
             <field eval="10.0" name="planned_hours"/>
+            <field eval="10.0" name="remaining_hours"/>
             <field name="user_id" ref="base.user_al"/>
             <field name="priority">2</field>
             <field name="project_id" ref="project.project_integrate_openerp"/>
 
         <record id="project_task_9" model="project.task">
             <field eval="50.0" name="planned_hours"/>
+            <field eval="50.0" name="remaining_hours"/>
             <field name="user_id" ref="base.user_al"/>
             <field name="priority">2</field>
             <field name="project_id" ref="project.project_integrate_openerp"/>
 
         <record id="project_task_10" model="project.task">
             <field eval="40.0" name="planned_hours"/>
+            <field eval="40.0" name="remaining_hours"/>
             <field name="user_id" ref="base.user_fpi"/>
             <field name="priority">2</field>
             <field name="project_id" ref="project.project_integrate_openerp"/>
 
         <record id="project_task_11" model="project.task">
             <field eval="90.0" name="planned_hours"/>
+            <field eval="90.0" name="remaining_hours"/>
             <field name="user_id" ref="base.user_fpi"/>
             <field name="priority">2</field>
             <field name="project_id" ref="project.project_integrate_openerp"/>
         
         <record id="project_task_12" model="project.task">
             <field eval="20.0" name="planned_hours"/>
+            <field eval="20.0" name="remaining_hours"/>
             <field name="user_id" ref="base.user_fpi"/>
             <field name="priority">2</field>
             <field name="project_id" ref="project.project_integrate_openerp"/>
         
         <record id="project_task_13" model="project.task">
             <field eval="50.0" name="planned_hours"/>
+            <field eval="50.0" name="remaining_hours"/>
             <field name="user_id" ref="base.user_mit"/>
             <field name="priority">2</field>
             <field name="project_id" ref="project.project_integrate_openerp"/>
 
         <record id="project_task_14" model="project.task">
             <field eval="30.0" name="planned_hours"/>
+            <field eval="30.0" name="remaining_hours"/>
             <field name="user_id" ref="base.user_mit"/>
             <field name="priority">2</field>
             <field name="project_id" ref="project.project_integrate_openerp"/>
 
         <record id="project_task_15" model="project.task">
             <field eval="15.0" name="planned_hours"/>
+            <field eval="15.0" name="remaining_hours"/>
             <field name="user_id" ref="base.user_fpi"/>
             <field name="priority">2</field>
             <field name="project_id" ref="project.project_integrate_openerp"/>
         <record id="project_task_16" model="project.task">
             <field eval="10" name="sequence"/>
             <field eval="40.0" name="planned_hours"/>
+            <field eval="40.0" name="remaining_hours"/>
             <field name="user_id" ref="base.user_mit"/>
             <field name="priority">2</field>
             <field name="project_id" ref="project.project_integrate_openerp"/>
 
         <record id="project_task_17" model="project.task">
             <field eval="5.0" name="planned_hours"/>
+            <field eval="5.0" name="remaining_hours"/>
             <field name="user_id" ref="base.user_niv"/>
             <field name="priority">2</field>
             <field name="project_id" ref="project.project_integrate_openerp"/>
 
         <record id="project_task_18" model="project.task">
             <field eval="10.0" name="planned_hours"/>
+            <field eval="10.0" name="remaining_hours"/>
             <field name="user_id" ref="base.user_niv"/>
             <field name="priority">2</field>
             <field name="project_id" ref="project.project_integrate_openerp"/>
index 7e82840..c3753f5 100644 (file)
@@ -38,6 +38,7 @@ import time
 import logging
 
 from mako.template import Template
+from mako.lookup import TemplateLookup
 from mako import exceptions
 
 import netsvc
@@ -56,8 +57,8 @@ def mako_template(text):
 
     This template uses UTF-8 encoding
     """
-    # default_filters=['unicode', 'h'] can be used to set global filters
-    return Template(text, input_encoding='utf-8', output_encoding='utf-8')
+    tmp_lookup  = TemplateLookup() #we need it in order to allow inclusion and inheritance
+    return Template(text, input_encoding='utf-8', output_encoding='utf-8', lookup=tmp_lookup)
 
 
 class WebKitParser(report_sxw):
index c24325a..3b444df 100644 (file)
@@ -322,16 +322,17 @@ openerp.web.DataSet =  openerp.web.Widget.extend( /** @lends openerp.web.DataSet
      * Reads the current dataset record (from its index)
      *
      * @params {Array} [fields] fields to read and return, by default all fields are returned
+     * @param {Object} [options.context] context data to add to the request payload, on top of the DataSet's own context
      * @params {Function} callback function called with read_index result
      * @returns {$.Deferred}
      */
-    read_index: function (fields, callback) {
+    read_index: function (fields, options, callback) {
         var def = $.Deferred().then(callback);
         if (_.isEmpty(this.ids)) {
             def.reject();
         } else {
             fields = fields || false;
-            this.read_ids([this.ids[this.index]], fields).then(function(records) {
+            this.read_ids([this.ids[this.index]], fields, options).then(function(records) {
                 def.resolve(records[0]);
             }, function() {
                 def.reject.apply(def, arguments);
index 159fedb..89b3a97 100644 (file)
@@ -50,10 +50,10 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
         _.defaults(this.options, {
             "not_interactible_on_create": false
         });
-        this.mutating_lock = $.Deferred();
-        this.initial_mutating_lock = this.mutating_lock;
-        this.on_change_lock = $.Deferred().resolve();
-        this.reload_lock = $.Deferred().resolve();
+        this.is_initialized = $.Deferred();
+        this.mutating_mutex = new $.Mutex();
+        this.on_change_mutex = new $.Mutex();
+        this.reload_mutex = new $.Mutex();
     },
     start: function() {
         this._super();
@@ -189,7 +189,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
                 });
             }
             self.on_form_changed();
-            self.initial_mutating_lock.resolve();
+            self.is_initialized.resolve();
             self.show_invalid = true;
             self.do_update_pager(record.id == null);
             if (self.sidebar) {
@@ -306,7 +306,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
     },
     do_onchange: function(widget, processed) {
         var self = this;
-        var act = function() {
+        return this.on_change_mutex.exec(function() {
             try {
                 processed = processed || [];
                 var on_change = widget.node.attrs.on_change;
@@ -333,9 +333,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
                 console.error(e);
                 return $.Deferred().reject();
             }
-        };
-        this.on_change_lock = this.on_change_lock.pipe(act, act);
-        return this.on_change_lock;
+        });
     },
     on_processed_onchange: function(response, processed) {
         try {
@@ -417,10 +415,8 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
      */
     do_save: function(success, prepend_on_create) {
         var self = this;
-        var action = function() {
+        return this.mutating_mutex.exec(function() { return self.is_initialized.pipe(function() {
             try {
-            if (!self.initial_mutating_lock.isResolved() && !self.initial_mutating_lock.isRejected())
-                return;
             var form_invalid = false,
                 values = {},
                 first_invalid_field = null;
@@ -465,9 +461,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
                 console.error(e);
                 return $.Deferred().reject();
             }
-        };
-        this.mutating_lock = this.mutating_lock.pipe(action, action);
-        return this.mutating_lock;
+        });});
     },
     on_invalid: function() {
         var msg = "<ul>";
@@ -528,15 +522,13 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
     },
     reload: function() {
         var self = this;
-        var act = function() {
+        return this.reload_mutex.exec(function() {
             if (self.dataset.index == null || self.dataset.index < 0) {
                 return $.when(self.on_button_new());
             } else {
                 return self.dataset.read_index(_.keys(self.fields_view.fields)).pipe(self.on_record_loaded);
             }
-        };
-        this.reload_lock = this.reload_lock.pipe(act, act);
-        return this.reload_lock;
+        });
     },
     get_fields_values: function(blacklist) {
        blacklist = blacklist || [];
@@ -834,23 +826,17 @@ openerp.web.form.Widget = openerp.web.Widget.extend(/** @lends openerp.web.form.
      * the fields'context with the action's context.
      */
     build_context: function(blacklist) {
-        var f_context = (this.field || {}).context || {};
-        if (!!f_context.__ref || true) { //TODO: remove true
-            var fields_values = this._build_eval_context(blacklist);
-            f_context = new openerp.web.CompoundContext(f_context).set_eval_context(fields_values);
-        }
-        // maybe the default_get should only be used when we do a default_get?
-        var v_contexts = _.compact([this.node.attrs.default_get || null,
-            this.node.attrs.context || null]);
-        var v_context = new openerp.web.CompoundContext();
-        _.each(v_contexts, function(x) {v_context.add(x);});
-        if (_.detect(v_contexts, function(x) {return !!x.__ref;}) || true) { //TODO: remove true
+        // only use the model's context if there is not context on the node
+        var v_context = this.node.attrs.context;
+        if (! v_context) {
+            v_context = (this.field || {}).context || {};
+        }
+        
+        if (v_context.__ref || true) { //TODO: remove true
             var fields_values = this._build_eval_context(blacklist);
-            v_context.set_eval_context(fields_values);
+            v_context = new openerp.web.CompoundContext(v_context).set_eval_context(fields_values);
         }
-        // if there is a context on the node, overrides the model's context
-        var ctx = v_contexts.length > 0 ? v_context : f_context;
-        return ctx;
+        return v_context;
     },
     build_domain: function() {
         var f_domain = this.field.domain || [];
@@ -1708,16 +1694,13 @@ openerp.web.form.FieldSelection = openerp.web.form.Field.extend({
 
 openerp.web.form.dialog = function(content, options) {
     options = _.extend({
-        autoOpen: true,
         width: '90%',
-        height: '90%',
-        min_width: '800px',
-        min_height: '600px'
+        height: 'auto',
+        min_width: '800px'
     }, options || {});
     options.autoOpen = true;
-    var dialog = new openerp.web.Dialog(null, options);
-    dialog.$element = $(content).dialog(dialog.dialog_options);
-    return dialog.$element;
+    var dialog = new openerp.web.Dialog(null, options).open();
+    return dialog.$element.html(content);
 };
 
 openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
@@ -2306,6 +2289,9 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
                    this.viewmanager.views[this.viewmanager.active_view].controller) {
                    var view = this.viewmanager.views[this.viewmanager.active_view].controller;
                    if (this.viewmanager.active_view === "form") {
+                       if (!view.is_initialized.isResolved()) {
+                           return false;
+                       }
                        var res = $.when(view.do_save());
                        if (!res.isResolved() && !res.isRejected()) {
                            console.warn("Asynchronous get_value() is not supported in form view.");
index 28ea127..2ac6c68 100644 (file)
@@ -290,7 +290,7 @@ openerp.web_dashboard.ConfigOverview = openerp.web.View.extend({
     start: function () {
         this._super();
         var self = this;
-        return this.user.read_index(['groups_id']).pipe(function (record) {
+        return this.user.read_index(['groups_id']).pipe(function(record) {
             var todos_filter = [
                 ['type', '!=', 'automatic'],
                 '|', ['groups_id', '=', false],
index f88a7fd..ddc88d9 100644 (file)
@@ -219,7 +219,7 @@ openerp.web.DiagramView = openerp.web.View.extend({
                 this.context || this.dataset.context
             );
             pop.on_select_elements.add_last(function(element_ids) {
-                self.dataset.read_index(_.keys(self.fields_view.fields), self.on_diagram_loaded);
+                self.dataset.read_index(_.keys(self.fields_view.fields)).pipe(self.on_diagram_loaded);
             });
         } else {
             pop = new openerp.web.form.FormOpenPopup(this);
@@ -232,7 +232,7 @@ openerp.web.DiagramView = openerp.web.View.extend({
                 }
             );
             pop.on_write.add(function() {
-                self.dataset.read_index(_.keys(self.fields_view.fields), self.on_diagram_loaded);
+                self.dataset.read_index(_.keys(self.fields_view.fields)).pipe(self.on_diagram_loaded);
             });
         }
 
@@ -292,7 +292,7 @@ openerp.web.DiagramView = openerp.web.View.extend({
                 this.dataset.index = this.dataset.ids.length - 1;
                 break;
         }
-        this.dataset.read_index(_.keys(this.fields_view.fields), this.on_diagram_loaded);
+        this.dataset.read_index(_.keys(this.fields_view.fields)).pipe(this.on_diagram_loaded);
         this.do_update_pager();
     },