From 919869907de3945f02ac2dfb33190eb82c8edca5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Pigeon?= Date: Tue, 2 Sep 2014 16:11:37 +0200 Subject: [PATCH 001/274] [ADD] add new test for onchange on one2many field --- openerp/addons/test_new_api/models.py | 5 +++++ .../test_new_api/tests/test_onchange.py | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/openerp/addons/test_new_api/models.py b/openerp/addons/test_new_api/models.py index 263868c835b..84c897e051d 100644 --- a/openerp/addons/test_new_api/models.py +++ b/openerp/addons/test_new_api/models.py @@ -85,11 +85,16 @@ class Discussion(models.Model): 'test_new_api_discussion_category', 'discussion', 'category') participants = fields.Many2many('res.users') messages = fields.One2many('test_new_api.message', 'discussion') + message_changes = fields.Integer('Message changes') @api.onchange('moderator') def _onchange_moderator(self): self.participants |= self.moderator + @api.onchange('messages') + def _onchange_messages(self): + self.message_changes = len(self.messages) + class Message(models.Model): _name = 'test_new_api.message' diff --git a/openerp/addons/test_new_api/tests/test_onchange.py b/openerp/addons/test_new_api/tests/test_onchange.py index c69becf9263..cbd24f4daac 100644 --- a/openerp/addons/test_new_api/tests/test_onchange.py +++ b/openerp/addons/test_new_api/tests/test_onchange.py @@ -163,3 +163,24 @@ class TestOnChange(common.TransactionCase): self.assertLessEqual(set(['participants']), set(result['value'])) self.assertItemsEqual(result['value']['participants'], participants + [(4, demo.id)]) + + def test_onchange_one2many(self): + discussion = self.env.ref('test_new_api.discussion_0') + demo = self.env.ref('base.user_demo') + + field_onchange = self.Discussion._onchange_spec() + self.assertEqual(field_onchange.get('messages'), '1') + + self.assertEqual(len(discussion.messages), 3) + messages = [(4, msg.id) for msg in discussion.messages] + messages[0] = (1, messages[0][1], {'body': 'test onchange'}) + values = { + 'name': discussion.name, + 'moderator': demo.id, + 'categories': [(4, cat.id) for cat in discussion.categories], + 'messages': messages, + 'participants': [(4, usr.id) for usr in discussion.participants], + 'message_changes': len(discussion.messages) + } + result = discussion.onchange(values, 'messages', field_onchange) + self.assertEqual(result['value'].get('message_changes', 0), len(discussion.messages)) From 242fbc2a20750a3debb13c6f8cec683c88d7c640 Mon Sep 17 00:00:00 2001 From: Arthur Maniet Date: Wed, 10 Sep 2014 11:41:00 +0200 Subject: [PATCH 002/274] [FIX] account: bank statement reconciliation widget: create move line + partial reconcile now possible --- addons/account/static/src/js/account_widgets.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js index e8f364127a1..593211832db 100644 --- a/addons/account/static/src/js/account_widgets.js +++ b/addons/account/static/src/js/account_widgets.js @@ -1029,10 +1029,12 @@ openerp.account = function (instance) { partnerNameClickHandler: function() { var self = this; // Delete statement line's partner - return self.changePartner('', function() { - self.$(".partner_name").hide(); - self.$(".change_partner_container").show(); - }); + if (window.confirm(_t("Reset the statement line's partner ?"))) { + return self.changePartner('', function() { + self.$(".partner_name").hide(); + self.$(".change_partner_container").show(); + }); + } }, @@ -1374,10 +1376,9 @@ openerp.account = function (instance) { var self = this; var mv_lines_selected = self.get("mv_lines_selected"); var lines_selected_num = mv_lines_selected.length; - var lines_created_num = self.getCreatedLines().length; // Undo partial reconciliation if necessary - if (lines_selected_num !== 1 || lines_created_num !== 0) { + if (lines_selected_num !== 1) { _.each(mv_lines_selected, function(line) { if (line.partial_reconcile === true) self.unpartialReconcileLine(line); if (line.propose_partial_reconcile === true) line.propose_partial_reconcile = false; @@ -1394,12 +1395,12 @@ openerp.account = function (instance) { _.each(self.getCreatedLines(), function(o) { balance += o.amount; }); - // Should work as long as currency's rounding factor is > 0.001 (ie: don't use gold kilos as a currency) + // Dealing with floating-point balance = Math.round(balance*1000)/1000; self.set("balance", balance); // Propose partial reconciliation if necessary - if (lines_selected_num === 1 && lines_created_num === 0 && self.st_line.amount * balance > 0) { + if (lines_selected_num === 1 && self.st_line.amount * balance > 0 && ! mv_lines_selected[0].partial_reconcile) { mv_lines_selected[0].propose_partial_reconcile = true; self.updateAccountingViewMatchedLines(); } From 9277cc920318fd716fe711120adbb159acf4e67a Mon Sep 17 00:00:00 2001 From: Arthur Maniet Date: Wed, 10 Sep 2014 14:07:27 +0200 Subject: [PATCH 003/274] [IMP]: account: bank statement reconciliation widget: statement name can be changed from widget --- .../account_bank_statement_reconciliation.css | 13 ++++- ...account_bank_statement_reconciliation.scss | 16 ++++++ .../account/static/src/js/account_widgets.js | 50 ++++++++++++++++--- .../account_bank_statement_reconciliation.xml | 13 ++++- 4 files changed, 83 insertions(+), 9 deletions(-) diff --git a/addons/account/static/src/css/account_bank_statement_reconciliation.css b/addons/account/static/src/css/account_bank_statement_reconciliation.css index 040e55eb45f..63b71ade4a5 100644 --- a/addons/account/static/src/css/account_bank_statement_reconciliation.css +++ b/addons/account/static/src/css/account_bank_statement_reconciliation.css @@ -18,12 +18,21 @@ border-top: 0; border-bottom: 0; height: 100%; } + .openerp .oe_bank_statement_reconciliation h1 input, .openerp .oe_bank_statement_reconciliation h2 input { + height: auto !important; } .openerp .oe_bank_statement_reconciliation h1 { width: 48%; padding: 0 0 0 15px; margin: 0 0 25px 0; float: left; font-size: 2em; } + .openerp .oe_bank_statement_reconciliation .change_statement_name_container { + display: none; } + .openerp .oe_bank_statement_reconciliation .change_statement_name_container td:first-child, .openerp .oe_bank_statement_reconciliation .change_statement_name_container td:first-child > input { + width: 99%; } + .openerp .oe_bank_statement_reconciliation .change_statement_name_container td:last-child { + width: 1%; + padding-left: 5px; } .openerp .oe_bank_statement_reconciliation h2 { font-size: 1.8em; } .openerp .oe_bank_statement_reconciliation .progress { @@ -182,7 +191,7 @@ color: #555; padding-right: 5px; } .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view .initial_line > td { - border-top: 1px solid #bbbbbb; + border-top: 1px solid #bbb; padding-top: 4px; padding-bottom: 5px; background-color: #f0f0f0; @@ -217,7 +226,7 @@ font-weight: bold; cursor: pointer; } .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view td.cell_credit { - border-left: 1px solid black; } + border-left: 1px solid #000; } .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match .match_controls { padding: 0 0 5px 18px; } .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match .match_controls .filter { diff --git a/addons/account/static/src/css/account_bank_statement_reconciliation.scss b/addons/account/static/src/css/account_bank_statement_reconciliation.scss index 92788e3bb51..b35d416addc 100644 --- a/addons/account/static/src/css/account_bank_statement_reconciliation.scss +++ b/addons/account/static/src/css/account_bank_statement_reconciliation.scss @@ -31,6 +31,10 @@ $aestetic_animation_speed: 300ms; } } + h1 input, h2 input { + height: auto !important; + } + h1 { width: 48%; padding: 0 0 0 $actionColWidth; @@ -39,6 +43,18 @@ $aestetic_animation_speed: 300ms; font-size: 2em; } + .change_statement_name_container { + display: none; + + td:first-child, td:first-child > input { + width: 99%; + } + td:last-child { + width: 1%; + padding-left: 5px; + } + } + h2 { font-size: 1.8em; } diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js index 593211832db..d92b46c3ef8 100644 --- a/addons/account/static/src/js/account_widgets.js +++ b/addons/account/static/src/js/account_widgets.js @@ -9,12 +9,19 @@ openerp.account = function (instance) { instance.web.client_actions.add('bank_statement_reconciliation_view', 'instance.web.account.bankStatementReconciliation'); instance.web.account.bankStatementReconciliation = instance.web.Widget.extend({ className: 'oe_bank_statement_reconciliation', + + events: { + "click .statement_name span": "statementNameClickHandler", + "keyup .change_statement_name_field": "changeStatementNameFieldHandler", + "click .change_statement_name_button": "changeStatementButtonClickHandler", + }, init: function(parent, context) { this._super(parent); this.max_reconciliations_displayed = 10; if (context.context.statement_id) this.statement_ids = [context.context.statement_id]; if (context.context.statement_ids) this.statement_ids = context.context.statement_ids; + this.is_single_statement = this.statement_ids !== undefined && this.statement_ids.length === 1; this.title = context.context.title || _t("Reconciliation"); this.st_lines = []; this.last_displayed_reconciliation_index = undefined; // Flow control @@ -127,8 +134,8 @@ openerp.account = function (instance) { if (self.statement_ids && self.statement_ids.length > 0) { lines_filter.push(['statement_id', 'in', self.statement_ids]); - // If only one statement, retreive its name - if (self.statement_ids.length === 1) { + // If only one statement, display its name as title and allow to modify it + if (self.is_single_statement) { deferred_promises.push(self.model_bank_statement .query(["name"]) .filter([['id', '=', self.statement_ids[0]]]) @@ -211,7 +218,11 @@ openerp.account = function (instance) { }); // Render and display - self.$el.prepend(QWeb.render("bank_statement_reconciliation", {title: self.title, total_lines: self.already_reconciled_lines+self.st_lines.length})); + self.$el.prepend(QWeb.render("bank_statement_reconciliation", { + title: self.title, + is_single_statement: self.is_single_statement, + total_lines: self.already_reconciled_lines+self.st_lines.length + })); self.updateProgressbar(); var reconciliations_to_show = self.st_lines.slice(0, self.max_reconciliations_displayed); self.last_displayed_reconciliation_index = reconciliations_to_show.length; @@ -233,6 +244,34 @@ openerp.account = function (instance) { }); }); }, + + statementNameClickHandler: function() { + if (! this.is_single_statement) return; + this.$(".statement_name span").hide(); + this.$(".change_statement_name_field").attr("value", this.title); + this.$(".change_statement_name_container").show(); + }, + + changeStatementNameFieldHandler: function(e) { + var name = this.$(".change_statement_name_field").val(); + if (name === "") this.$(".change_statement_name_button").attr("disabled", "disabled"); + else this.$(".change_statement_name_button").removeAttr("disabled"); + if (name !== "" && e.which === 13) this.$(".change_statement_name_button").trigger("click"); + }, + + changeStatementButtonClickHandler: function() { + var self = this; + if (! self.is_single_statement) return; + var name = self.$(".change_statement_name_field").val(); + if (name === "") return; + return self.model_bank_statement + .call("write", [[self.statement_ids[0]], {'name': name}]) + .then(function () { + self.title = name; + self.$(".statement_name span").text(name).show(); + self.$(".change_statement_name_container").hide(); + }); + }, keyboardShortcutsHandler: function(e) { var self = this; @@ -345,7 +384,6 @@ openerp.account = function (instance) { displayDoneMessage: function() { var self = this; - var is_single_statement = self.statement_ids !== undefined && self.statement_ids.length === 1; var sec_taken = Math.round((Date.now()-self.time_widget_loaded)/1000); var sec_per_item = Math.round(sec_taken/self.reconciled_lines); var achievements = []; @@ -381,7 +419,7 @@ openerp.account = function (instance) { transactions_done: self.reconciled_lines, done_with_ctrl_enter: self.lines_reconciled_with_ctrl_enter, achievements: achievements, - has_statement_id: is_single_statement, + has_statement_id: self.is_single_statement, })); // Animate it @@ -400,7 +438,7 @@ openerp.account = function (instance) { }); }); - if (is_single_statement && self.$(".button_close_statement").length !== 0) { + if (self.is_single_statement && self.$(".button_close_statement").length !== 0) { self.$(".button_close_statement").hide(); self.model_bank_statement .query(["balance_end_real", "balance_end"]) diff --git a/addons/account/static/src/xml/account_bank_statement_reconciliation.xml b/addons/account/static/src/xml/account_bank_statement_reconciliation.xml index 4e32d97eceb..c86414a99ba 100644 --- a/addons/account/static/src/xml/account_bank_statement_reconciliation.xml +++ b/addons/account/static/src/xml/account_bank_statement_reconciliation.xml @@ -13,7 +13,18 @@
-

+ +

+ + + + +
+

+
+ +

+
0 /
From 24cf401f63dbd96056671475767df89f4242345a Mon Sep 17 00:00:00 2001 From: Arthur Maniet Date: Wed, 10 Sep 2014 15:01:13 +0200 Subject: [PATCH 004/274] [IMP] account: bank reconciliation widget: making it harder to remove a statement line's partner ; improved change statement name usability --- .../account_bank_statement_reconciliation.css | 23 +++++++++++----- ...account_bank_statement_reconciliation.scss | 26 ++++++++++++++++--- .../account/static/src/js/account_widgets.js | 23 +++++++++------- .../account_bank_statement_reconciliation.xml | 5 +++- 4 files changed, 58 insertions(+), 19 deletions(-) diff --git a/addons/account/static/src/css/account_bank_statement_reconciliation.css b/addons/account/static/src/css/account_bank_statement_reconciliation.css index 63b71ade4a5..2c8502c4272 100644 --- a/addons/account/static/src/css/account_bank_statement_reconciliation.css +++ b/addons/account/static/src/css/account_bank_statement_reconciliation.css @@ -25,19 +25,24 @@ padding: 0 0 0 15px; margin: 0 0 25px 0; float: left; - font-size: 2em; } + font-size: 2em; + height: 1.5em; } + .openerp .oe_bank_statement_reconciliation .statement_name span { + line-height: 1.5em; + cursor: pointer; } .openerp .oe_bank_statement_reconciliation .change_statement_name_container { - display: none; } + display: none; + width: 95%; } .openerp .oe_bank_statement_reconciliation .change_statement_name_container td:first-child, .openerp .oe_bank_statement_reconciliation .change_statement_name_container td:first-child > input { width: 99%; } .openerp .oe_bank_statement_reconciliation .change_statement_name_container td:last-child { width: 1%; - padding-left: 5px; } + padding-left: 3px; } .openerp .oe_bank_statement_reconciliation h2 { font-size: 1.8em; } .openerp .oe_bank_statement_reconciliation .progress { width: 49%; - margin: 4px 15px 0 0; + margin: 10px 15px 0 0; float: right; position: relative; display: inline-block; } @@ -130,6 +135,13 @@ -ms-transform: rotate(90deg); -o-transform: rotate(90deg); transform: rotate(90deg); } + .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .partner_name .remove_partner { + display: none; + cursor: pointer; } + .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .partner_name .remove_partner .glyphicon { + margin: 0 5px; } + .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .partner_name:hover .remove_partner { + display: inline; } .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .change_partner_container { width: 200px; display: none; @@ -223,8 +235,7 @@ position: relative; top: 7px; /* meh */ - font-weight: bold; - cursor: pointer; } + font-weight: bold; } .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view td.cell_credit { border-left: 1px solid #000; } .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match .match_controls { diff --git a/addons/account/static/src/css/account_bank_statement_reconciliation.scss b/addons/account/static/src/css/account_bank_statement_reconciliation.scss index b35d416addc..e0ed85311a1 100644 --- a/addons/account/static/src/css/account_bank_statement_reconciliation.scss +++ b/addons/account/static/src/css/account_bank_statement_reconciliation.scss @@ -41,17 +41,24 @@ $aestetic_animation_speed: 300ms; margin: 0 0 25px 0; float: left; font-size: 2em; + height: 1.5em; + } + + .statement_name span { + line-height: 1.5em; + cursor: pointer; } .change_statement_name_container { display: none; + width: 95%; td:first-child, td:first-child > input { width: 99%; } td:last-child { width: 1%; - padding-left: 5px; + padding-left: 3px; } } @@ -61,7 +68,7 @@ $aestetic_animation_speed: 300ms; .progress { width: 49%; - margin: 4px $actionColWidth 0 0; + margin: 10px $actionColWidth 0 0; float: right; position: relative; display: inline-block; @@ -189,6 +196,20 @@ $aestetic_animation_speed: 300ms; transform: rotate(90deg); } + .partner_name { + .remove_partner { + display: none; + cursor: pointer; + + .glyphicon { + margin: 0 5px; + } + } + &:hover .remove_partner { + display: inline; + } + } + .change_partner_container { width: 200px; display: none; @@ -367,7 +388,6 @@ $aestetic_animation_speed: 300ms; > span, > input { position: relative; top: 7px; /* meh */ font-weight: bold; - cursor: pointer; } } diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js index d92b46c3ef8..411ed3f314a 100644 --- a/addons/account/static/src/js/account_widgets.js +++ b/addons/account/static/src/js/account_widgets.js @@ -250,13 +250,20 @@ openerp.account = function (instance) { this.$(".statement_name span").hide(); this.$(".change_statement_name_field").attr("value", this.title); this.$(".change_statement_name_container").show(); + this.$(".change_statement_name_field").focus(); }, changeStatementNameFieldHandler: function(e) { var name = this.$(".change_statement_name_field").val(); if (name === "") this.$(".change_statement_name_button").attr("disabled", "disabled"); else this.$(".change_statement_name_button").removeAttr("disabled"); - if (name !== "" && e.which === 13) this.$(".change_statement_name_button").trigger("click"); + + if (name !== "" && e.which === 13) // Enter + this.$(".change_statement_name_button").trigger("click"); + if (e.which === 27) { // Escape + this.$(".statement_name span").show(); + this.$(".change_statement_name_container").hide(); + } }, changeStatementButtonClickHandler: function() { @@ -493,7 +500,7 @@ openerp.account = function (instance) { className: 'oe_bank_statement_reconciliation_line', events: { - "click .partner_name": "partnerNameClickHandler", + "click .remove_partner": "removePartnerClickHandler", "click .button_ok": "persistAndDestroy", "click .mv_line": "moveLineClickHandler", "click .initial_line": "initialLineClickHandler", @@ -1064,15 +1071,13 @@ openerp.account = function (instance) { } }, - partnerNameClickHandler: function() { + removePartnerClickHandler: function() { var self = this; // Delete statement line's partner - if (window.confirm(_t("Reset the statement line's partner ?"))) { - return self.changePartner('', function() { - self.$(".partner_name").hide(); - self.$(".change_partner_container").show(); - }); - } + return self.changePartner('', function() { + self.$(".partner_name").hide(); + self.$(".change_partner_container").show(); + }); }, diff --git a/addons/account/static/src/xml/account_bank_statement_reconciliation.xml b/addons/account/static/src/xml/account_bank_statement_reconciliation.xml index c86414a99ba..869acdf08c6 100644 --- a/addons/account/static/src/xml/account_bank_statement_reconciliation.xml +++ b/addons/account/static/src/xml/account_bank_statement_reconciliation.xml @@ -64,7 +64,10 @@ From b281b83cd012925d849738f66230113f9ac3d988 Mon Sep 17 00:00:00 2001 From: Arthur Maniet Date: Wed, 10 Sep 2014 15:02:33 +0200 Subject: [PATCH 005/274] [FIX] account: reconciliation: using move_line.name instead of move_line.move_id.name when is defined --- 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 0f3e1322aaf..99c40f3626b 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -777,7 +777,7 @@ class account_move_line(osv.osv): ret_line = { 'id': line.id, - 'name': line.move_id.name, + 'name': line.name if line.name != '/' else line.move_id.name, 'ref': line.move_id.ref, 'account_code': line.account_id.code, 'account_name': line.account_id.name, From 90cc05f8c3dc4160069a2ceab0a9a1208b5eeab3 Mon Sep 17 00:00:00 2001 From: Arthur Maniet Date: Wed, 10 Sep 2014 15:45:28 +0200 Subject: [PATCH 006/274] [FIX] account: bank statement reconciliation widget: firefox compatibility --- .../account_bank_statement_reconciliation.css | 80 ++++++++++--------- ...account_bank_statement_reconciliation.scss | 5 +- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/addons/account/static/src/css/account_bank_statement_reconciliation.css b/addons/account/static/src/css/account_bank_statement_reconciliation.css index 2c8502c4272..2306496ec2c 100644 --- a/addons/account/static/src/css/account_bank_statement_reconciliation.css +++ b/addons/account/static/src/css/account_bank_statement_reconciliation.css @@ -202,42 +202,44 @@ .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr .undo_partial_reconcile_button, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match table tr .undo_partial_reconcile_button { color: #555; padding-right: 5px; } - .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view .initial_line > td { - border-top: 1px solid #bbb; - padding-top: 4px; - padding-bottom: 5px; - background-color: #f0f0f0; - -webkit-transition-property: background-color; - -moz-transition-property: background-color; - -ms-transition-property: background-color; - transition-property: background-color; - -webkit-transition-duration: 300ms; - -moz-transition-duration: 300ms; - -ms-transition-duration: 300ms; - -o-transition-duration: 300ms; - transition-duration: 300ms; } - .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view .initial_line > td.cell_action, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view .initial_line > td.cell_info_popover { - border-top: none; - background: white !important; - padding-top: 6px; - padding-bottom: 3px; } - .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption { - text-align: left; - font-size: 1.1em; - font-weight: bold; - height: 26px; - margin: 0 15px 4px 15px; } - .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption button { - float: right; } - .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption button:disabled { - opacity: 0.5; } - .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption > span, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption > input { - position: relative; - top: 7px; - /* meh */ - font-weight: bold; } - .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view td.cell_credit { - border-left: 1px solid #000; } + .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view { + border-collapse: separate; } + .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view .initial_line > td { + border-top: 1px solid #bbb; + padding-top: 4px; + padding-bottom: 5px; + background-color: #f0f0f0; + -webkit-transition-property: background-color; + -moz-transition-property: background-color; + -ms-transition-property: background-color; + transition-property: background-color; + -webkit-transition-duration: 300ms; + -moz-transition-duration: 300ms; + -ms-transition-duration: 300ms; + -o-transition-duration: 300ms; + transition-duration: 300ms; } + .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view .initial_line > td.cell_action, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view .initial_line > td.cell_info_popover { + border-top: none; + background: white !important; + padding-top: 6px; + padding-bottom: 3px; } + .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption { + text-align: left; + font-size: 1.1em; + font-weight: bold; + height: 26px; + margin: 0 15px 4px 15px; } + .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption button { + float: right; } + .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption button:disabled { + opacity: 0.5; } + .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption > span, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption > input { + position: relative; + top: 7px; + /* meh */ + font-weight: bold; } + .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view td.cell_credit { + border-left: 1px solid #000; } .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match .match_controls { padding: 0 0 5px 18px; } .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match .match_controls .filter { @@ -270,9 +272,11 @@ width: 49%; height: 26px; } .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .create .oe_form > table:nth-child(2n+1) { - float: left; } + float: left; + clear: left; } .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .create .oe_form > table:nth-child(2n) { - float: right; } + float: right; + clear: right; } .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .create .oe_form > table th { font-weight: bold; line-height: 26px; diff --git a/addons/account/static/src/css/account_bank_statement_reconciliation.scss b/addons/account/static/src/css/account_bank_statement_reconciliation.scss index e0ed85311a1..ea9bf86384a 100644 --- a/addons/account/static/src/css/account_bank_statement_reconciliation.scss +++ b/addons/account/static/src/css/account_bank_statement_reconciliation.scss @@ -345,6 +345,7 @@ $aestetic_animation_speed: 300ms; /* Partie infos */ .accounting_view { + border-collapse: separate; .initial_line > td { border-top: $lightBorder; @@ -452,8 +453,8 @@ $aestetic_animation_speed: 300ms; width: 49%; height: 26px; - &:nth-child(2n+1) { float: left; } - &:nth-child(2n) { float: right; } + &:nth-child(2n+1) { float: left; clear: left; } + &:nth-child(2n) { float: right; clear: right; } th { font-weight: bold; From e49eeded3949fe22261ebb53a5e8500f8b0a2908 Mon Sep 17 00:00:00 2001 From: Arthur Maniet Date: Wed, 10 Sep 2014 16:58:31 +0200 Subject: [PATCH 007/274] [FIX] account: reconciliation widget: when updating matches (move lines), exclude those which are reconciled with a selected move line as well --- addons/account/account_move_line.py | 3 ++ .../account/static/src/js/account_widgets.js | 38 ++++++++++++------- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index 99c40f3626b..c404b930996 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -772,8 +772,10 @@ class account_move_line(osv.osv): for line in lines: if line.reconcile_partial_id and line.reconcile_partial_id.id in reconcile_partial_ids: continue + partial_reconciliation_siblings_ids = [] if line.reconcile_partial_id: reconcile_partial_ids.append(line.reconcile_partial_id.id) + partial_reconciliation_siblings_ids = self.search(cr, uid, [('reconcile_partial_id', '=', line.reconcile_partial_id.id)], context=context) ret_line = { 'id': line.id, @@ -788,6 +790,7 @@ class account_move_line(osv.osv): 'journal_name': line.journal_id.name, 'partner_id': line.partner_id.id, 'partner_name': line.partner_id.name, + 'partial_reconciliation_siblings_ids': partial_reconciliation_siblings_ids, } # Get right debit / credit: diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js index 411ed3f314a..e69165bb167 100644 --- a/addons/account/static/src/js/account_widgets.js +++ b/addons/account/static/src/js/account_widgets.js @@ -293,8 +293,13 @@ openerp.account = function (instance) { // Adds move line ids to the list of move lines not to fetch for a given partner // This is required because the same move line cannot be selected for multiple reconciliation - excludeMoveLines: function(source_child, partner_id, line_ids) { + excludeMoveLines: function(source_child, partner_id, lines) { var self = this; + var line_ids = []; + _.each(lines, function(o) { + line_ids.push(o.id); + line_ids = line_ids.concat(o.partial_reconciliation_siblings_ids) + }); var excluded_ids = this.excluded_move_lines_ids[partner_id]; var excluded_move_lines_changed = false; @@ -331,9 +336,14 @@ openerp.account = function (instance) { }); }, - unexcludeMoveLines: function(source_child, partner_id, line_ids) { + unexcludeMoveLines: function(source_child, partner_id, lines) { var self = this; - + var line_ids = []; + _.each(lines, function(o) { + line_ids.push(o.id); + line_ids = line_ids.concat(o.partial_reconciliation_siblings_ids) + }); + var initial_excluded_lines_num = this.excluded_move_lines_ids[partner_id].length; this.excluded_move_lines_ids[partner_id] = _.difference(this.excluded_move_lines_ids[partner_id], line_ids); if (this.excluded_move_lines_ids[partner_id].length === initial_excluded_lines_num) @@ -530,10 +540,9 @@ openerp.account = function (instance) { this.decorateStatementLine(this.st_line); // Exclude selected move lines - var selected_line_ids = _(context.reconciliation_proposition).map(function(o){ return o.id }); if (this.getParent().excluded_move_lines_ids[this.partner_id] === undefined) this.getParent().excluded_move_lines_ids[this.partner_id] = []; - this.getParent().excludeMoveLines(this, this.partner_id, selected_line_ids); + this.getParent().excludeMoveLines(this, this.partner_id, context.reconciliation_proposition); } else { this.set("mv_lines_selected", []); this.st_line = undefined; @@ -684,7 +693,7 @@ openerp.account = function (instance) { _.each(self.getChildren(), function(o){ o.destroy() }); self.is_consistent = false; return $.when(self.$el.animate({opacity: 0}, self.animation_speed)).then(function() { - self.getParent().unexcludeMoveLines(self, self.partner_id, _.map(self.get("mv_lines_selected"), function(o){ return o.id })); + self.getParent().unexcludeMoveLines(self, self.partner_id, self.get("mv_lines_selected")); $.each(self.$(".bootstrap_popover"), function(){ $(this).popover('destroy') }); self.$el.empty(); self.$el.removeClass("no_partner"); @@ -1277,11 +1286,11 @@ openerp.account = function (instance) { mvLinesSelectedChanged: function(elt, val) { var self = this; - var added_lines_ids = _.map(_.difference(val.newValue, val.oldValue), function(o){ return o.id }); - var removed_lines_ids = _.map(_.difference(val.oldValue, val.newValue), function(o){ return o.id }); + var added_lines = _.difference(val.newValue, val.oldValue); + var removed_lines = _.difference(val.oldValue, val.newValue); - self.getParent().excludeMoveLines(self, self.partner_id, added_lines_ids); - self.getParent().unexcludeMoveLines(self, self.partner_id, removed_lines_ids); + self.getParent().excludeMoveLines(self, self.partner_id, added_lines); + self.getParent().unexcludeMoveLines(self, self.partner_id, removed_lines); $.when(self.updateMatches()).then(function(){ self.updateAccountingViewMatchedLines(); @@ -1459,8 +1468,11 @@ openerp.account = function (instance) { if (offset < 0) offset = 0; var limit = (self.get("pager_index")+1) * self.max_move_lines_displayed - deselected_lines_num; if (limit > self.max_move_lines_displayed) limit = self.max_move_lines_displayed; - var excluded_ids = _.collect(self.get("mv_lines_selected").concat(self.mv_lines_deselected), function(o){ return o.id }); - excluded_ids = excluded_ids.concat(self.getParent().excluded_move_lines_ids[self.partner_id]); + var excluded_ids = self.getParent().excluded_move_lines_ids[self.partner_id]; + _.each(self.get("mv_lines_selected").concat(self.mv_lines_deselected), function(o){ + excluded_ids.push(o.id); + excluded_ids = excluded_ids.concat(o.partial_reconciliation_siblings_ids); + }); var deferred_move_lines; var move_lines = []; @@ -1552,7 +1564,7 @@ openerp.account = function (instance) { speed = (isNaN(speed) ? self.animation_speed : speed); if (! self.is_consistent) return; - self.getParent().unexcludeMoveLines(self, self.partner_id, _.map(self.get("mv_lines_selected"), function(o){ return o.id })); + self.getParent().unexcludeMoveLines(self, self.partner_id, self.get("mv_lines_selected")); // Sliding animation var height = self.$el.outerHeight(); From 1cd330f7efdc79c91f2af55cea686ed9d64058ce Mon Sep 17 00:00:00 2001 From: Arthur Maniet Date: Wed, 10 Sep 2014 17:07:07 +0200 Subject: [PATCH 008/274] [FIX] account: reconciliation: taking into account that amount_residual can (very infrequently) be < 0 --- addons/account/account_move_line.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index c404b930996..f359289e8d8 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -816,6 +816,12 @@ class account_move_line(osv.osv): credit = currency_obj.compute(cr, uid, target_currency.id, company_currency.id, credit, context=ctx) amount_str = rml_parser.formatLang(debit or credit, currency_obj=target_currency) + # Amount residual can be negative + if debit < 0: + debit, credit = credit, -debit + if credit < 0: + debit, credit = -credit, debit + ret_line['credit'] = credit ret_line['debit'] = debit ret_line['amount_str'] = amount_str From f87954834041cff5cb17c8605ec679adaf5aadff Mon Sep 17 00:00:00 2001 From: Arthur Maniet Date: Wed, 10 Sep 2014 17:17:35 +0200 Subject: [PATCH 009/274] [FIX] account: bank statement reconciliation widget: cleaning (ID has nothing to do in the tooltip showing more infos about a move line) --- addons/account/static/src/js/account_widgets.js | 4 ++-- .../static/src/xml/account_bank_statement_reconciliation.xml | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js index e69165bb167..86f5b250fe7 100644 --- a/addons/account/static/src/js/account_widgets.js +++ b/addons/account/static/src/js/account_widgets.js @@ -298,7 +298,7 @@ openerp.account = function (instance) { var line_ids = []; _.each(lines, function(o) { line_ids.push(o.id); - line_ids = line_ids.concat(o.partial_reconciliation_siblings_ids) + line_ids = line_ids.concat(o.partial_reconciliation_siblings_ids); }); var excluded_ids = this.excluded_move_lines_ids[partner_id]; @@ -341,7 +341,7 @@ openerp.account = function (instance) { var line_ids = []; _.each(lines, function(o) { line_ids.push(o.id); - line_ids = line_ids.concat(o.partial_reconciliation_siblings_ids) + line_ids = line_ids.concat(o.partial_reconciliation_siblings_ids); }); var initial_excluded_lines_num = this.excluded_move_lines_ids[partner_id].length; diff --git a/addons/account/static/src/xml/account_bank_statement_reconciliation.xml b/addons/account/static/src/xml/account_bank_statement_reconciliation.xml index 869acdf08c6..7b9b1f00fa8 100644 --- a/addons/account/static/src/xml/account_bank_statement_reconciliation.xml +++ b/addons/account/static/src/xml/account_bank_statement_reconciliation.xml @@ -154,7 +154,6 @@
- + + + +
- From 6af1d35ba6a858d90e407c249b8643297f52de05 Mon Sep 17 00:00:00 2001 From: Arthur Maniet Date: Thu, 11 Sep 2014 09:27:10 +0200 Subject: [PATCH 010/274] [FIX] account: bank statement reconciliation widget: correctly refresh partial reconciliation sign --- addons/account/static/src/js/account_widgets.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js index 86f5b250fe7..eb07489f954 100644 --- a/addons/account/static/src/js/account_widgets.js +++ b/addons/account/static/src/js/account_widgets.js @@ -1452,9 +1452,16 @@ openerp.account = function (instance) { self.set("balance", balance); // Propose partial reconciliation if necessary - if (lines_selected_num === 1 && self.st_line.amount * balance > 0 && ! mv_lines_selected[0].partial_reconcile) { + if (lines_selected_num === 1 && + self.st_line.amount * balance > 0 && + self.st_line.amount * (mv_lines_selected[0].debit - mv_lines_selected[0].credit) < 0 && + ! mv_lines_selected[0].partial_reconcile) { + mv_lines_selected[0].propose_partial_reconcile = true; self.updateAccountingViewMatchedLines(); + } else if (lines_selected_num === 1) { + mv_lines_selected[0].propose_partial_reconcile = false; + self.updateAccountingViewMatchedLines(); } }, From 80c62b395ff67190142cfa50a01c3cf3c3893c78 Mon Sep 17 00:00:00 2001 From: Arthur Maniet Date: Thu, 11 Sep 2014 12:46:56 +0200 Subject: [PATCH 011/274] [IMP] account: bank statement reconciliation widget: it is now possible, when reconciliation is done, to close all the statements reconciled and to go back to statements list view --- .../account/static/src/js/account_widgets.js | 68 +++++++++++++------ .../account_bank_statement_reconciliation.xml | 6 +- 2 files changed, 49 insertions(+), 25 deletions(-) diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js index eb07489f954..0547e365549 100644 --- a/addons/account/static/src/js/account_widgets.js +++ b/addons/account/static/src/js/account_widgets.js @@ -21,7 +21,8 @@ openerp.account = function (instance) { this.max_reconciliations_displayed = 10; if (context.context.statement_id) this.statement_ids = [context.context.statement_id]; if (context.context.statement_ids) this.statement_ids = context.context.statement_ids; - this.is_single_statement = this.statement_ids !== undefined && this.statement_ids.length === 1; + this.single_statement = this.statement_ids !== undefined && this.statement_ids.length === 1; + this.multiple_statements = this.statement_ids !== undefined && this.statement_ids.length > 1; this.title = context.context.title || _t("Reconciliation"); this.st_lines = []; this.last_displayed_reconciliation_index = undefined; // Flow control @@ -135,7 +136,7 @@ openerp.account = function (instance) { lines_filter.push(['statement_id', 'in', self.statement_ids]); // If only one statement, display its name as title and allow to modify it - if (self.is_single_statement) { + if (self.single_statement) { deferred_promises.push(self.model_bank_statement .query(["name"]) .filter([['id', '=', self.statement_ids[0]]]) @@ -220,7 +221,7 @@ openerp.account = function (instance) { // Render and display self.$el.prepend(QWeb.render("bank_statement_reconciliation", { title: self.title, - is_single_statement: self.is_single_statement, + single_statement: self.single_statement, total_lines: self.already_reconciled_lines+self.st_lines.length })); self.updateProgressbar(); @@ -246,7 +247,7 @@ openerp.account = function (instance) { }, statementNameClickHandler: function() { - if (! this.is_single_statement) return; + if (! this.single_statement) return; this.$(".statement_name span").hide(); this.$(".change_statement_name_field").attr("value", this.title); this.$(".change_statement_name_container").show(); @@ -268,7 +269,7 @@ openerp.account = function (instance) { changeStatementButtonClickHandler: function() { var self = this; - if (! self.is_single_statement) return; + if (! self.single_statement) return; var name = self.$(".change_statement_name_field").val(); if (name === "") return; return self.model_bank_statement @@ -397,6 +398,32 @@ openerp.account = function (instance) { } } }, + + goBackToStatementsTreeView: function() { + var self = this; + new instance.web.Model("ir.model.data") + .call("get_object_reference", ['account', 'action_bank_statement_tree']) + .then(function (result) { + var action_id = result[1]; + // Warning : altough I don't see why this widget wouldn't be directly instanciated by the + // action manager, if it wasn't, this code wouldn't work. You'd have to do something like : + // var action_manager = self; + // while (! action_manager instanceof ActionManager) + // action_manager = action_manager.getParent(); + var action_manager = self.getParent(); + var breadcrumbs = action_manager.breadcrumbs; + var found = false; + for (var i=breadcrumbs.length-1; i>=0; i--) { + if (breadcrumbs[i].action && breadcrumbs[i].action.id === action_id) { + var title = breadcrumbs[i].get_title(); + action_manager.select_breadcrumb(i, _.isArray(title) ? i : undefined); + found = true; + } + } + if (!found) + instance.web.Home(self); + }); + }, displayDoneMessage: function() { var self = this; @@ -436,7 +463,8 @@ openerp.account = function (instance) { transactions_done: self.reconciled_lines, done_with_ctrl_enter: self.lines_reconciled_with_ctrl_enter, achievements: achievements, - has_statement_id: self.is_single_statement, + single_statement: self.single_statement, + multiple_statements: self.multiple_statements, })); // Animate it @@ -447,32 +475,28 @@ openerp.account = function (instance) { // Make it interactive self.$(".achievement").popover({'placement': 'top', 'container': self.el, 'trigger': 'hover'}); - - self.$(".button_back_to_statement").click(function() { - self.do_action({ - type: 'ir.actions.client', - tag: 'history_back', - }); - }); - if (self.is_single_statement && self.$(".button_close_statement").length !== 0) { + if (self.$(".button_back_to_statement").length !== 0) { + self.$(".button_back_to_statement").click(function() { + self.goBackToStatementsTreeView(); + }); + } + + if (self.$(".button_close_statement").length !== 0) { self.$(".button_close_statement").hide(); self.model_bank_statement .query(["balance_end_real", "balance_end"]) - .filter([['id', '=', self.statement_ids[0]]]) - .first() + .filter([['id', 'in', self.statement_ids]]) + .all() .then(function(data){ - if (data.balance_end_real === data.balance_end) { + if (_.all(data, function(o) { return o.balance_end_real === o.balance_end })) { self.$(".button_close_statement").show(); self.$(".button_close_statement").click(function() { self.$(".button_close_statement").attr("disabled", "disabled"); self.model_bank_statement - .call("button_confirm_bank", [[self.statement_ids[0]]]) + .call("button_confirm_bank", [self.statement_ids]) .then(function () { - self.do_action({ - type: 'ir.actions.client', - tag: 'history_back', - }); + self.goBackToStatementsTreeView(); }, function() { self.$(".button_close_statement").removeAttr("disabled"); }); diff --git a/addons/account/static/src/xml/account_bank_statement_reconciliation.xml b/addons/account/static/src/xml/account_bank_statement_reconciliation.xml index 7b9b1f00fa8..7dcdf19d827 100644 --- a/addons/account/static/src/xml/account_bank_statement_reconciliation.xml +++ b/addons/account/static/src/xml/account_bank_statement_reconciliation.xml @@ -49,9 +49,9 @@

- - - + + +

From b146263a77bb82768ba22ec40d0272e333327905 Mon Sep 17 00:00:00 2001 From: Arthur Maniet Date: Thu, 11 Sep 2014 13:08:59 +0200 Subject: [PATCH 012/274] [IMP] account: bank statement reconciliation widget: better animations --- .../account/static/src/js/account_widgets.js | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js index 0547e365549..a13477c4029 100644 --- a/addons/account/static/src/js/account_widgets.js +++ b/addons/account/static/src/js/account_widgets.js @@ -234,12 +234,11 @@ openerp.account = function (instance) { .call("get_data_for_reconciliations", [reconciliations_to_show]) .then(function (data) { var child_promises = []; - _.each(reconciliations_to_show, function(st_line_id){ - var datum = data.shift(); - child_promises.push(self.displayReconciliation(st_line_id, 'inactive', false, true, datum.st_line, datum.reconciliation_proposition)); - }); + var datum = data.shift(); + child_promises.push(self.displayReconciliation(datum.st_line.id, 'match', false, true, datum.st_line, datum.reconciliation_proposition)); + while ((datum = data.shift()) !== undefined) + child_promises.push(self.displayReconciliation(datum.st_line.id, 'inactive', false, true, datum.st_line, datum.reconciliation_proposition)); $.when.apply($, child_promises).then(function(){ - self.getChildren()[0].set("mode", "match"); self.$(".reconciliation_lines_container").animate({opacity: 1}, self.aestetic_animation_speed); }); }); @@ -712,6 +711,7 @@ openerp.account = function (instance) { restart: function(mode) { var self = this; mode = (mode === undefined ? 'inactive' : mode); + self.context.animate_entrance = false; self.$el.css("height", self.$el.outerHeight()); // Destroy everything _.each(self.getChildren(), function(o){ o.destroy() }); @@ -1264,14 +1264,20 @@ openerp.account = function (instance) { self.el.dataset.mode = "inactive"; } else if (self.get("mode") === "match") { + // TODO : remove this old_animation_speed / new_animation_speed hack + // when .on handler's returned deferred's no longer lost + var old_animation_speed = self.animation_speed; return $.when(self.updateMatches()).then(function() { - if (self.$el.hasClass("no_match")) { - self.set("mode", "inactive"); + var new_animation_speed = self.animation_speed; + self.animation_speed = old_animation_speed; + if (self.$el.hasClass("no_match")) { // TODO : not for manual reconciliation + self.set("mode", "create"); return; } self.$(".match").slideDown(self.animation_speed); self.$(".create").slideUp(self.animation_speed); self.el.dataset.mode = "match"; + self.animation_speed = new_animation_speed; }); } else if (self.get("mode") === "create") { From 0171d949394b8f38bf209f303daff0ef920dc65c Mon Sep 17 00:00:00 2001 From: Arthur Maniet Date: Thu, 11 Sep 2014 16:34:05 +0200 Subject: [PATCH 013/274] [FIX] account: bank statement reconciliation widget: refactor fix : is_single_statement -> single_statement --- .../static/src/xml/account_bank_statement_reconciliation.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/account/static/src/xml/account_bank_statement_reconciliation.xml b/addons/account/static/src/xml/account_bank_statement_reconciliation.xml index 7dcdf19d827..9d6d10add24 100644 --- a/addons/account/static/src/xml/account_bank_statement_reconciliation.xml +++ b/addons/account/static/src/xml/account_bank_statement_reconciliation.xml @@ -13,7 +13,7 @@
- +

id
Account
Journal
Period
@@ -22,7 +22,7 @@
- +

From b7361b04eed428d1065837721484c9bde223bc9e Mon Sep 17 00:00:00 2001 From: Arthur Maniet Date: Thu, 11 Sep 2014 17:02:47 +0200 Subject: [PATCH 014/274] [FIX] account: reconciliation: allow to reconcile when no_partner --- .../account/static/src/js/account_widgets.js | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js index a13477c4029..c42be9b6027 100644 --- a/addons/account/static/src/js/account_widgets.js +++ b/addons/account/static/src/js/account_widgets.js @@ -1241,23 +1241,6 @@ openerp.account = function (instance) { self.$(".action_pane.active").removeClass("active"); - // Special case hack : if no_partner, either inactive or create - if (self.st_line.has_no_partner) { - if (self.get("mode") === "inactive") { - self.$(".match").slideUp(self.animation_speed); - self.$(".create").slideUp(self.animation_speed); - self.$(".toggle_match").removeClass("visible_toggle"); - self.el.dataset.mode = "inactive"; - } else { - self.initializeCreateForm(); - self.$(".match").slideUp(self.animation_speed); - self.$(".create").slideDown(self.animation_speed); - self.$(".toggle_match").addClass("visible_toggle"); - self.el.dataset.mode = "create"; - } - return; - } - if (self.get("mode") === "inactive") { self.$(".match").slideUp(self.animation_speed); self.$(".create").slideUp(self.animation_speed); @@ -1497,7 +1480,6 @@ openerp.account = function (instance) { // Loads move lines according to the widget's state updateMatches: function() { - if (this.st_line.has_no_partner) return; var self = this; var deselected_lines_num = self.mv_lines_deselected.length; var move_lines_num = 0; @@ -1505,7 +1487,8 @@ openerp.account = function (instance) { if (offset < 0) offset = 0; var limit = (self.get("pager_index")+1) * self.max_move_lines_displayed - deselected_lines_num; if (limit > self.max_move_lines_displayed) limit = self.max_move_lines_displayed; - var excluded_ids = self.getParent().excluded_move_lines_ids[self.partner_id]; + if (self.st_line.has_no_partner) + var excluded_ids = self.getParent().excluded_move_lines_ids[self.partner_id]; _.each(self.get("mv_lines_selected").concat(self.mv_lines_deselected), function(o){ excluded_ids.push(o.id); excluded_ids = excluded_ids.concat(o.partial_reconciliation_siblings_ids); From f393171bc3b9931ec4bd9236d8d4f77004f49080 Mon Sep 17 00:00:00 2001 From: Arthur Maniet Date: Fri, 12 Sep 2014 15:28:50 +0200 Subject: [PATCH 015/274] [FIX] account: bank statement reconciliation widget: display only one line for a partial reconciliation --- addons/account/account_move_line.py | 1 + .../account/static/src/js/account_widgets.js | 35 ++++++++++--------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index f359289e8d8..a3e224cd80d 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -776,6 +776,7 @@ class account_move_line(osv.osv): if line.reconcile_partial_id: reconcile_partial_ids.append(line.reconcile_partial_id.id) partial_reconciliation_siblings_ids = self.search(cr, uid, [('reconcile_partial_id', '=', line.reconcile_partial_id.id)], context=context) + partial_reconciliation_siblings_ids.remove(line.id) ret_line = { 'id': line.id, diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js index c42be9b6027..da6d489bcfe 100644 --- a/addons/account/static/src/js/account_widgets.js +++ b/addons/account/static/src/js/account_widgets.js @@ -293,13 +293,10 @@ openerp.account = function (instance) { // Adds move line ids to the list of move lines not to fetch for a given partner // This is required because the same move line cannot be selected for multiple reconciliation + // and because for a partial reconciliation only one line can be fetched) excludeMoveLines: function(source_child, partner_id, lines) { var self = this; - var line_ids = []; - _.each(lines, function(o) { - line_ids.push(o.id); - line_ids = line_ids.concat(o.partial_reconciliation_siblings_ids); - }); + var line_ids = _.collect(lines, function(o) { return o.id }); var excluded_ids = this.excluded_move_lines_ids[partner_id]; var excluded_move_lines_changed = false; @@ -338,11 +335,7 @@ openerp.account = function (instance) { unexcludeMoveLines: function(source_child, partner_id, lines) { var self = this; - var line_ids = []; - _.each(lines, function(o) { - line_ids.push(o.id); - line_ids = line_ids.concat(o.partial_reconciliation_siblings_ids); - }); + var line_ids = _.collect(lines, function(o) { return o.id }); var initial_excluded_lines_num = this.excluded_move_lines_ids[partner_id].length; this.excluded_move_lines_ids[partner_id] = _.difference(this.excluded_move_lines_ids[partner_id], line_ids); @@ -1291,7 +1284,14 @@ openerp.account = function (instance) { } else { self.$el.removeClass("no_match"); } - + + _.each(self.get("mv_lines"), function(line) { + if (line.partial_reconciliation_siblings_ids.length > 0) { + var correct_format = _.collect(line.partial_reconciliation_siblings_ids, function(o) { return {'id': o} }); + self.getParent().excludeMoveLines(self, self.partner_id, correct_format); + } + }); + self.updateMatchView(); self.updatePagerControls(); }, @@ -1487,12 +1487,13 @@ openerp.account = function (instance) { if (offset < 0) offset = 0; var limit = (self.get("pager_index")+1) * self.max_move_lines_displayed - deselected_lines_num; if (limit > self.max_move_lines_displayed) limit = self.max_move_lines_displayed; - if (self.st_line.has_no_partner) - var excluded_ids = self.getParent().excluded_move_lines_ids[self.partner_id]; - _.each(self.get("mv_lines_selected").concat(self.mv_lines_deselected), function(o){ - excluded_ids.push(o.id); - excluded_ids = excluded_ids.concat(o.partial_reconciliation_siblings_ids); - }); + var excluded_ids = self.getParent().excluded_move_lines_ids[self.partner_id]; + var excluded_ids = _.collect(self.get("mv_lines_selected").concat(self.mv_lines_deselected), function(o) { return o.id; }); + var globally_excluded_ids = self.getParent().excluded_move_lines_ids[self.partner_id]; + if (globally_excluded_ids !== undefined) + for (var i=0; i Date: Fri, 12 Sep 2014 12:01:25 +0200 Subject: [PATCH 016/274] [FIX]: account: reconciliation: handling negative amount_residual --- addons/account/account_move_line.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index a3e224cd80d..1918b5401d7 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -794,19 +794,29 @@ class account_move_line(osv.osv): 'partial_reconciliation_siblings_ids': partial_reconciliation_siblings_ids, } + # Amount residual can be negative + debit = line.debit + credit = line.credit + amount_residual = line.amount_residual + amount_residual_currency = line.amount_residual_currency + if line.amount_residual < 0: + debit, credit = credit, debit + amount_residual = -amount_residual + amount_residual_currency = -amount_residual_currency + # Get right debit / credit: line_currency = line.currency_id or company_currency amount_currency_str = "" if line.currency_id and line.amount_currency: amount_currency_str = rml_parser.formatLang(line.amount_currency, currency_obj=line.currency_id) if target_currency and line_currency == target_currency and target_currency != company_currency: - debit = line.debit > 0 and line.amount_residual_currency or 0.0 - credit = line.credit > 0 and line.amount_residual_currency or 0.0 - amount_currency_str = rml_parser.formatLang(line.amount_residual, currency_obj=company_currency) + debit = debit > 0 and amount_residual_currency or 0.0 + credit = credit > 0 and amount_residual_currency or 0.0 + amount_currency_str = amount_residual_currency(amount_residual, currency_obj=company_currency) amount_str = rml_parser.formatLang(debit or credit, currency_obj=target_currency) else: - debit = line.debit > 0 and line.amount_residual or 0.0 - credit = line.credit > 0 and line.amount_residual or 0.0 + debit = debit > 0 and amount_residual or 0.0 + credit = credit > 0 and amount_residual or 0.0 amount_str = rml_parser.formatLang(debit or credit, currency_obj=company_currency) if target_currency and target_currency != company_currency: amount_currency_str = rml_parser.formatLang(debit or credit, currency_obj=line_currency) @@ -817,12 +827,6 @@ class account_move_line(osv.osv): credit = currency_obj.compute(cr, uid, target_currency.id, company_currency.id, credit, context=ctx) amount_str = rml_parser.formatLang(debit or credit, currency_obj=target_currency) - # Amount residual can be negative - if debit < 0: - debit, credit = credit, -debit - if credit < 0: - debit, credit = -credit, debit - ret_line['credit'] = credit ret_line['debit'] = debit ret_line['amount_str'] = amount_str From ddc78626e16025bbe40e9bfac412f61f781176e2 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Fri, 12 Sep 2014 17:51:56 +0200 Subject: [PATCH 017/274] [IMP] ir.model:.fields allow setting ondelete=restrict foncustom fields --- openerp/addons/base/ir/ir_model.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openerp/addons/base/ir/ir_model.py b/openerp/addons/base/ir/ir_model.py index c8c7b77c441..25529d648d1 100644 --- a/openerp/addons/base/ir/ir_model.py +++ b/openerp/addons/base/ir/ir_model.py @@ -244,7 +244,8 @@ class ir_model_fields(osv.osv): 'translate': fields.boolean('Translatable', help="Whether values for this field can be translated (enables the translation mechanism for that field)"), 'size': fields.integer('Size'), 'state': fields.selection([('manual','Custom Field'),('base','Base Field')],'Type', required=True, readonly=True, select=1), - 'on_delete': fields.selection([('cascade','Cascade'),('set null','Set NULL')], 'On Delete', help='On delete property for many2one fields'), + 'on_delete': fields.selection([('cascade', 'Cascade'), ('set null', 'Set NULL'), ('restrict', 'Restrict')], + 'On Delete', help='On delete property for many2one fields'), 'domain': fields.char('Domain', help="The optional domain to restrict possible values for relationship fields, " "specified as a Python expression defining a list of triplets. " "For example: [('color','=','red')]"), From b601015800ba2ec28fdd064eb560349b51149936 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Mon, 15 Sep 2014 11:55:53 +0200 Subject: [PATCH 018/274] [FIX] tools: restrict available attributes --- openerp/tools/safe_eval.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openerp/tools/safe_eval.py b/openerp/tools/safe_eval.py index 0b9b2e7a8a3..c317c9bea88 100644 --- a/openerp/tools/safe_eval.py +++ b/openerp/tools/safe_eval.py @@ -42,6 +42,9 @@ __all__ = ['test_expr', 'safe_eval', 'const_eval'] # lp:703841), does import time. _ALLOWED_MODULES = ['_strptime', 'time'] +_UNSAFE_ATTRIBUTES = ['f_builtins', 'f_globals', 'f_locals', 'gi_frame', + 'co_code', 'func_globals'] + _CONST_OPCODES = set(opmap[x] for x in [ 'POP_TOP', 'ROT_TWO', 'ROT_THREE', 'ROT_FOUR', 'DUP_TOP', 'DUP_TOPX', 'POP_BLOCK','SETUP_LOOP', 'BUILD_LIST', 'BUILD_MAP', 'BUILD_TUPLE', @@ -113,7 +116,7 @@ def assert_no_dunder_name(code_obj, expr): .. note:: actually forbids every name containing 2 underscores """ for name in code_obj.co_names: - if "__" in name: + if "__" in name or name in _UNSAFE_ATTRIBUTES: raise NameError('Access to forbidden name %r (%r)' % (name, expr)) def assert_valid_codeobj(allowed_codes, code_obj, expr): From 42680c9906125a034c2df2d1dd106b00212a27fc Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Mon, 7 Apr 2014 10:24:45 +0200 Subject: [PATCH 019/274] [FIX] web: backport of ebb826a and 2372d30 Fixing breadcrumb not being displayed after some action button (e.g. validate invoice, opw 612763) --- addons/web/controllers/main.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 6bfc249cc9a..6206d1fa4d4 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -1109,11 +1109,14 @@ class DataSet(openerpweb.Controller): def _call_kw(self, req, model, method, args, kwargs): # Temporary implements future display_name special field for model#read() - if method == 'read' and kwargs.get('context', {}).get('future_display_name'): + if method in ('read', 'search_read') and kwargs.get('context', {}).get('future_display_name'): if 'display_name' in args[1]: - names = dict(req.session.model(model).name_get(args[0], **kwargs)) + if method == 'read': + names = dict(req.session.model(model).name_get(args[0], **kwargs)) + else: + names = dict(req.session.model(model).name_search('', args[0], **kwargs)) args[1].remove('display_name') - records = req.session.model(model).read(*args, **kwargs) + records = getattr(req.session.model(model), method)(*args, **kwargs) for record in records: record['display_name'] = \ names.get(record['id']) or "%s#%d" % (model, (record['id'])) From 176e14d2bc973c8ac97455c570e3e933361e2888 Mon Sep 17 00:00:00 2001 From: Samus CTO Date: Thu, 4 Sep 2014 09:30:43 +0200 Subject: [PATCH 020/274] [IMP] api: compute methods cannot depend on field 'id' This feature hasn't been implemented because of complexity problems. Therefore, we should not allow the developer to use it. --- openerp/api.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openerp/api.py b/openerp/api.py index 83190f82e87..d576f9fa001 100644 --- a/openerp/api.py +++ b/openerp/api.py @@ -191,6 +191,8 @@ def depends(*args): """ if args and callable(args[0]): args = args[0] + elif any('id' in arg.split('.') for arg in args): + raise NotImplementedError("Compute method cannot depend on field 'id'.") return lambda method: decorate(method, '_depends', args) From 685fa26e83e6358fcaa786b6e0358bd8b1e155f3 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Mon, 15 Sep 2014 15:22:04 +0200 Subject: [PATCH 021/274] [FIX] web: do not check if db in session match filter if no db --- addons/web/controllers/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 35be5189c0e..b59e01b6c39 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -153,7 +153,7 @@ def ensure_db(redirect='/web/database/selector'): return # if db not provided, use the session one - if not db and http.db_filter([request.session.db]): + if not db and request.session.db and http.db_filter([request.session.db]): db = request.session.db # if no database provided and no database in session, use monodb From 32f51689742cdec79ad2bc41ac37bb53fbb6f199 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Mon, 15 Sep 2014 15:24:43 +0200 Subject: [PATCH 022/274] [FIX] orm: do not drop foreign keys of transient models During the update of a module, the existing foreign keys are dropped if they have a different ondelete_rule than the one specified on the field. The foreign keys for many2one transiant -> non-transiant are created with cascade rule by default (see `m2o_add_foreign_key_checked` method) so the check needs to be realised in the same conditions. --- openerp/osv/orm.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 9bf10df39d6..07ed496000c 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -3016,6 +3016,9 @@ class BaseModel(object): if len(constraints) == 1: # Is it the right constraint? cons, = constraints + if self.is_transient() and not dest_model.is_transient(): + # transient foreign keys are added as cascade by default + ondelete = ondelete or 'cascade' if cons['ondelete_rule'] != POSTGRES_CONFDELTYPES.get((ondelete or 'set null').upper(), 'a')\ or cons['foreign_table'] != dest_model._table: # Wrong FK: drop it and recreate From cfac9464a466a27bf3cf2c315d785093cba4ed34 Mon Sep 17 00:00:00 2001 From: Jeremy Kersten Date: Mon, 15 Sep 2014 15:27:48 +0200 Subject: [PATCH 023/274] [FIX] website_hr_recruitment: add param to force all countries else it use GeoIP, check that country returned by GeoIP have jobs availables else fallback on all countries --- addons/crm/ir_http.py | 2 +- addons/website_hr_recruitment/controllers/main.py | 6 ++++-- addons/website_hr_recruitment/views/templates.xml | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/addons/crm/ir_http.py b/addons/crm/ir_http.py index aeebe6427b1..c3e1f445e9a 100644 --- a/addons/crm/ir_http.py +++ b/addons/crm/ir_http.py @@ -6,7 +6,7 @@ from openerp.osv import orm class ir_http(orm.AbstractModel): _inherit = 'ir.http' - def get_utm_domain_cookies(slef): + def get_utm_domain_cookies(self): return request.httprequest.host def _dispatch(self): diff --git a/addons/website_hr_recruitment/controllers/main.py b/addons/website_hr_recruitment/controllers/main.py index 2ca6e3aa3e6..6da86976511 100644 --- a/addons/website_hr_recruitment/controllers/main.py +++ b/addons/website_hr_recruitment/controllers/main.py @@ -19,7 +19,7 @@ class website_hr_recruitment(http.Controller): '/jobs/department//office/', '/jobs/country//department//office/', ], type='http', auth="public", website=True) - def jobs(self, country=None, department=None, office_id=None): + def jobs(self, country=None, department=None, office_id=None, **kwargs): env = request.env(context=dict(request.env.context, show_address=True, no_tag_br=True)) Country = env['res.country'] @@ -41,9 +41,11 @@ class website_hr_recruitment(http.Controller): if country_code: countries_ = Country.search([('code', '=', country_code)]) country = countries_[0] if countries_ else None + if not any(j for j in jobs if j.address_id and j.address_id.country_id == country): + country = False # Filter the matching one - if country: + if country and not kwargs.get('all_countries'): jobs = (j for j in jobs if j.address_id is None or j.address_id.country_id and j.address_id.country_id.id == country.id) if department: jobs = (j for j in jobs if j.department_id and j.department_id.id == department.id) diff --git a/addons/website_hr_recruitment/views/templates.xml b/addons/website_hr_recruitment/views/templates.xml index 0d1397cb6df..47280892cab 100644 --- a/addons/website_hr_recruitment/views/templates.xml +++ b/addons/website_hr_recruitment/views/templates.xml @@ -227,7 +227,7 @@