From 8d538fc33a97a7795386270ef55103887c9a49fe Mon Sep 17 00:00:00 2001 From: Sandy Date: Fri, 13 Jun 2014 10:39:57 -0400 Subject: [PATCH 01/13] Spawn gevent using same python executable Solves issues of spawning wrong version of python or popping out of virtualenv --- openerp/service/server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/service/server.py b/openerp/service/server.py index 72e130edf8b..b64febb5c33 100644 --- a/openerp/service/server.py +++ b/openerp/service/server.py @@ -463,7 +463,7 @@ class PreforkServer(CommonServer): cmd = nargs[0] cmd = os.path.join(os.path.dirname(cmd), "openerp-gevent") nargs[0] = cmd - popen = subprocess.Popen(nargs) + popen = subprocess.Popen([sys.executable] + nargs) self.long_polling_pid = popen.pid def worker_pop(self, pid): From b8124f5ceca5f0308e53d4f33e73c7a778de2302 Mon Sep 17 00:00:00 2001 From: Gaurav Panchal Date: Mon, 23 Jun 2014 11:48:05 +0530 Subject: [PATCH 02/13] [IMP]document: Remove document menu and submenu from knowledge, hr_applicnt_document: add kanban view in hr resume and letter, mail: change the kanban view of attachment --- addons/document/document_view.xml | 8 ------- .../views/hr_applicant.xml | 5 +++-- addons/mail/mail_message_view.xml | 22 +++++++++++++------ 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/addons/document/document_view.xml b/addons/document/document_view.xml index 87da74c5658..4e19478e205 100644 --- a/addons/document/document_view.xml +++ b/addons/document/document_view.xml @@ -253,14 +253,6 @@

- - ir.actions.act_window diff --git a/addons/hr_applicant_document/views/hr_applicant.xml b/addons/hr_applicant_document/views/hr_applicant.xml index 706a1b4c754..71607014c85 100644 --- a/addons/hr_applicant_document/views/hr_applicant.xml +++ b/addons/hr_applicant_document/views/hr_applicant.xml @@ -16,8 +16,9 @@ Resumes and Letters ir.attachment - tree,form - + form + kanban,tree,form + [('res_model','=','hr.applicant')]

diff --git a/addons/mail/mail_message_view.xml b/addons/mail/mail_message_view.xml index dde087de597..0ab7b269cca 100644 --- a/addons/mail/mail_message_view.xml +++ b/addons/mail/mail_message_view.xml @@ -100,13 +100,21 @@

-
- -
bb
-
-
- -
aa
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
From 7e4443547ef1f6201b505449eaaea5dff8b73176 Mon Sep 17 00:00:00 2001 From: Cedric Snauwaert Date: Thu, 19 Jun 2014 11:35:45 +0200 Subject: [PATCH 03/13] [WIP]remove some unneeded argument in computing reconciliation line --- addons/account/account_bank_statement.py | 27 +++++++------------ .../account/static/src/js/account_widgets.js | 17 +++++++++--- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py index 1ddab4bece9..7a45cf85041 100644 --- a/addons/account/account_bank_statement.py +++ b/addons/account/account_bank_statement.py @@ -532,20 +532,20 @@ class account_bank_statement_line(osv.osv): # look for structured communication exact_match_id = self.search_structured_com(cr, uid, st_line, context=context) if exact_match_id: - return self.make_counter_part_lines(cr, uid, st_line, [exact_match_id], count=False, context=context) + return self.make_counter_part_lines(cr, uid, st_line, [exact_match_id], context=context) #we don't propose anything if there is no partner detected if not st_line.partner_id.id: return [] # look for exact match - exact_match_id = self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=excluded_ids, limit=1, additional_domain=[(amount_field, '=', (sign * st_line.amount))]) + exact_match_id = self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=excluded_ids, additional_domain=[(amount_field, '=', (sign * st_line.amount))]) if exact_match_id: - return exact_match_id + return exact_match_id[0] # select oldest move lines if sign == -1: - mv_lines = self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=excluded_ids, limit=50, additional_domain=[(amount_field, '<', 0)]) + mv_lines = self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=excluded_ids, additional_domain=[(amount_field, '<', 0)]) else: - mv_lines = self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=excluded_ids, limit=50, additional_domain=[(amount_field, '>', 0)]) + mv_lines = self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=excluded_ids, additional_domain=[(amount_field, '>', 0)]) ret = [] total = 0 # get_move_lines_counterparts inverts debit and credit @@ -558,11 +558,11 @@ class account_bank_statement_line(osv.osv): break return ret - def get_move_lines_counterparts_id(self, cr, uid, st_line_id, excluded_ids=[], filter_str="", offset=0, limit=None, count=False, additional_domain=[], context=None): + def get_move_lines_counterparts_id(self, cr, uid, st_line_id, excluded_ids=[], additional_domain=[], count=False, context=None): st_line = self.browse(cr, uid, st_line_id, context=context) - return self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids, filter_str, offset, limit, count, additional_domain, context=context) + return self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids, additional_domain, count, context=context) - def get_move_lines_counterparts(self, cr, uid, st_line, excluded_ids=[], filter_str="", offset=0, limit=None, count=False, additional_domain=[], context=None): + def get_move_lines_counterparts(self, cr, uid, st_line, excluded_ids=[], additional_domain=[], count=False, context=None): """ Find the move lines that could be used to reconcile a statement line and returns the counterpart that could be created to reconcile them If count is true, only returns the count. @@ -576,10 +576,7 @@ class account_bank_statement_line(osv.osv): """ mv_line_pool = self.pool.get('account.move.line') - domain = additional_domain + [ - ('reconcile_id', '=', False), - ('state', '=', 'valid'), - ] + domain = additional_domain + [('reconcile_id', '=', False),('state', '=', 'valid')] if st_line.partner_id.id: domain += [('partner_id', '=', st_line.partner_id.id), '|', ('account_id.type', '=', 'receivable'), @@ -589,11 +586,7 @@ class account_bank_statement_line(osv.osv): #domain += [('account_id.reconcile', '=', True), ('account_id.type', '=', 'other')] if excluded_ids: domain.append(('id', 'not in', excluded_ids)) - if filter_str: - if not st_line.partner_id: - domain += [ '|', ('partner_id.name', 'ilike', filter_str)] - domain += ['|', ('move_id.name', 'ilike', filter_str), ('move_id.ref', 'ilike', filter_str)] - line_ids = mv_line_pool.search(cr, uid, domain, offset=offset, limit=limit, order="date_maturity asc, id asc", context=context) + line_ids = mv_line_pool.search(cr, uid, domain, order="date_maturity asc, id asc", context=context) return self.make_counter_part_lines(cr, uid, st_line, line_ids, count=count, context=context) def make_counter_part_lines(self, cr, uid, st_line, line_ids, count=False, context=None): diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js index 8f5786e978f..29ab9c0200d 100644 --- a/addons/account/static/src/js/account_widgets.js +++ b/addons/account/static/src/js/account_widgets.js @@ -531,6 +531,9 @@ openerp.account = function (instance) { this.set("line_created_being_edited", [{'id': 0}]); this.on("change:lines_created", this, this.createdLinesChanged); this.on("change:line_created_being_edited", this, this.createdLinesChanged); + + //all lines associated to current reconciliation + this.lines = undefined; }, start: function() { @@ -566,6 +569,14 @@ openerp.account = function (instance) { // Display the widget return $.when(deferred_fetch_data).then(function(){ + //load all lines that can be usefull for counterparts + var deferred_total_move_lines_num = self.model_bank_statement_line + .call("get_move_lines_counterparts_id", [self.st_line.id, []]) + .then(function(lines){ + self.lines = lines; + }); + return deferred_total_move_lines_num; + }).then(function(){ // Render template var presets_array = []; for (var id in self.presets) @@ -580,7 +591,7 @@ openerp.account = function (instance) { if (self.context.mode !== "match") self.updateMatches(); self.bindPopoverTo(self.$(".line_info_button")); self.createFormWidgets(); - + debugger; // Special case hack : no identified partner if (self.st_line.has_no_partner) { self.$el.css("opacity", "0"); @@ -1363,7 +1374,7 @@ openerp.account = function (instance) { if (limit > 0) { // Load move lines deferred_move_lines = self.model_bank_statement_line - .call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids, self.filter, offset, limit]) + .call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids]) .then(function (lines) { _(lines).each(self.decorateMoveLine.bind(self)); move_lines = lines; @@ -1371,7 +1382,7 @@ openerp.account = function (instance) { } // Fetch the number of move lines corresponding to this statement line and this filter var deferred_total_move_lines_num = self.model_bank_statement_line - .call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids, self.filter, 0, undefined, true]) + .call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids, [], true]) .then(function(num){ move_lines_num = num; }); From 29a0e7b354613cf6d4cc6d56be67cd95e77080d9 Mon Sep 17 00:00:00 2001 From: Cedric Snauwaert Date: Fri, 20 Jun 2014 15:35:46 +0200 Subject: [PATCH 04/13] [REF]refactor account widget to reduce rpc call --- .../account/static/src/js/account_widgets.js | 222 +++++------------- .../account_bank_statement_reconciliation.xml | 2 +- 2 files changed, 65 insertions(+), 159 deletions(-) diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js index 29ab9c0200d..b78c8514cb8 100644 --- a/addons/account/static/src/js/account_widgets.js +++ b/addons/account/static/src/js/account_widgets.js @@ -29,7 +29,7 @@ openerp.account = function (instance) { this.time_widget_loaded = Date.now(); // Stuff used by the children bankStatementReconciliationLine - this.max_move_lines_displayed = 5; + this.max_move_lines_displayed = 2; this.animation_speed = 100; // "Blocking" animations this.aestetic_animation_speed = 300; // eye candy this.map_tax_id_amount = {}; @@ -37,7 +37,7 @@ openerp.account = function (instance) { // We'll need to get the code of an account selected in a many2one (whose value is the id) this.map_account_id_code = {}; // The same move line cannot be selected for multiple resolutions - this.excluded_move_lines_ids = {}; + this.excluded_move_lines_ids = []; // Description of the fields to initialize in the "create new line" form // NB : for presets to work correctly, a field id must be the same string as a preset field this.create_form_fields = { @@ -253,59 +253,34 @@ 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(line_ids) { var self = this; - - var excluded_ids = this.excluded_move_lines_ids[partner_id]; - var excluded_move_lines_changed = false; _.each(line_ids, function(line_id){ - if (excluded_ids.indexOf(line_id) === -1) { - excluded_ids.push(line_id); - excluded_move_lines_changed = true; + line_id = parseInt(line_id); + if (self.excluded_move_lines_ids.indexOf(line_id) === -1) { + self.excluded_move_lines_ids.push(line_id); } }); - if (! excluded_move_lines_changed) - return; - - // Function that finds if an array of line objects contains at least a line identified by its id - var contains_lines = function(lines_array, line_ids) { - for (var i = 0; i < lines_array.length; i++) - for (var j = 0; j < line_ids.length; j++) - if (lines_array[i].id === line_ids[j]) - return true; - return false; - }; - - // Update children if needed + //update all children view _.each(self.getChildren(), function(child){ - if (child.partner_id === partner_id && child !== source_child) { - if (contains_lines(child.get("mv_lines_selected"), line_ids)) { - child.set("mv_lines_selected", _.filter(child.get("mv_lines_selected"), function(o){ return line_ids.indexOf(o.id) === -1 })); - } else if (contains_lines(child.mv_lines_deselected, line_ids)) { - child.mv_lines_deselected = _.filter(child.mv_lines_deselected, function(o){ return line_ids.indexOf(o.id) === -1 }); - child.updateMatches(); - } else if (contains_lines(child.get("mv_lines"), line_ids)) { - child.updateMatches(); - } - } + child.render(); }); }, - - unexcludeMoveLines: function(source_child, partner_id, line_ids) { + + unexcludeMoveLines: function(line_ids) { var self = this; - - 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) - return; - - // Update children if needed + var index = -1; + _.each(line_ids, function(line_id){ + line_id = parseInt(line_id); + index = self.excluded_move_lines_ids.indexOf(line_id); + if (index > -1) { + self.excluded_move_lines_ids.splice(index,1); + } + }); + //update all children view _.each(self.getChildren(), function(child){ - if (child.partner_id === partner_id && child !== source_child && (child.get("mode") === "match" || child.$el.hasClass("no_match"))) - child.updateMatches(); + child.render(); }); }, @@ -490,9 +465,7 @@ openerp.account = function (instance) { // 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(selected_line_ids); } else { this.set("mv_lines_selected", []); this.st_line = undefined; @@ -525,7 +498,6 @@ openerp.account = function (instance) { // NB : mv_lines represent the counterpart that will be created to reconcile existing move lines, so debit and credit are inverted this.set("mv_lines", []); this.on("change:mv_lines", this, this.mvLinesChanged); - this.mv_lines_deselected = []; // deselected lines are displayed on top of the match table this.on("change:mv_lines_selected", this, this.mvLinesSelectedChanged); this.set("lines_created", []); this.set("line_created_being_edited", [{'id': 0}]); @@ -533,7 +505,7 @@ openerp.account = function (instance) { this.on("change:line_created_being_edited", this, this.createdLinesChanged); //all lines associated to current reconciliation - this.lines = undefined; + this.propositions_lines = undefined; }, start: function() { @@ -556,9 +528,6 @@ openerp.account = function (instance) { self.st_line = data; self.decorateStatementLine(self.st_line); self.partner_id = data.partner_id; - if (self.getParent().excluded_move_lines_ids[self.partner_id] === undefined) - self.getParent().excluded_move_lines_ids[self.partner_id] = []; - // load and display move lines $.when(self.loadReconciliationProposition()).then(function(){ deferred_fetch_data.resolve(); }); @@ -573,7 +542,8 @@ openerp.account = function (instance) { var deferred_total_move_lines_num = self.model_bank_statement_line .call("get_move_lines_counterparts_id", [self.st_line.id, []]) .then(function(lines){ - self.lines = lines; + _(lines).each(self.decorateMoveLine.bind(self)); + self.propositions_lines = lines; }); return deferred_total_move_lines_num; }).then(function(){ @@ -588,10 +558,9 @@ openerp.account = function (instance) { self.$(".match").slideUp(0); self.$(".create").slideUp(0); if (self.st_line.no_match) self.$el.addClass("no_match"); - if (self.context.mode !== "match") self.updateMatches(); + if (self.context.mode !== "match") self.render(); self.bindPopoverTo(self.$(".line_info_button")); self.createFormWidgets(); - debugger; // Special case hack : no identified partner if (self.st_line.has_no_partner) { self.$el.css("opacity", "0"); @@ -634,7 +603,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(_.map(self.get("mv_lines_selected"), function(o){ return o.id })); $.each(self.$(".bootstrap_popover"), function(){ $(this).popover('destroy') }); self.$el.empty(); self.$el.removeClass("no_partner"); @@ -648,7 +617,6 @@ openerp.account = function (instance) { self.set("pager_index", 0, {silent: true}); self.set("mv_lines", [], {silent: true}); self.set("mv_lines_selected", [], {silent: true}); - self.mv_lines_deselected = []; self.set("lines_created", [], {silent: true}); self.set("line_created_being_edited", [{'id': 0}], {silent: true}); // Rebirth @@ -847,54 +815,25 @@ openerp.account = function (instance) { if (e.currentTarget.dataset.selected === "true") self.deselectMoveLine(e.currentTarget); else self.selectMoveLine(e.currentTarget); }, - - // Takes a move line from the match view and adds it to the mv_lines_selected array + selectMoveLine: function(mv_line) { var self = this; var line_id = mv_line.dataset.lineid; - - // find the line in mv_lines or mv_lines_deselected - var line = _.find(self.get("mv_lines"), function(o){ return o.id == line_id }); - if (! line) { - line = _.find(self.mv_lines_deselected, function(o){ return o.id == line_id }); - self.mv_lines_deselected = _.filter(self.mv_lines_deselected, function(o) { return o.id != line_id }); - } - // If no line found, the view is probably not up to date to the model (asynchronous fun) - if (! line) return; - - // Warn the user if he's selecting lines from both a payable and a receivable account - var last_selected_line = _.last(self.get("mv_lines_selected")); - if (last_selected_line && last_selected_line.account_type != line.account_type) { - // TODO : web client API - alert(_.str.sprintf(_t("You are selecting transactions from both a payable and a receivable account.\n\nIn order to proceed, you first need to deselect the %s transactions."), last_selected_line.account_type)); - return; - } - + var line = _.find(self.propositions_lines, function(o){ return o.id == line_id}); + $(mv_line).attr('data-selected','true'); + self.getParent().excludeMoveLines([line_id]); self.set("mv_lines_selected", self.get("mv_lines_selected").concat(line)); }, - - // Removes a move line from the mv_lines_selected array + deselectMoveLine: function(mv_line) { var self = this; var line_id = mv_line.dataset.lineid; - var line = _.find(self.get("mv_lines_selected"), function(o) { return o.id == line_id }); - // If no line found, the view is probably not up to date to the model (asynchronous fun) - if (! line) return; - - // add the line to mv_lines_deselected and remove it from mv_lines_selected - self.mv_lines_deselected.unshift(line); - var mv_lines_selected = _.filter(self.get("mv_lines_selected"), function(o) { return o.id != line_id }); - - // remove partial reconciliation stuff if necessary - if (line.partial_reconcile === true) self.unpartialReconcileLine(line); - if (line.propose_partial_reconcile === true) line.propose_partial_reconcile = false; - - self.$el.removeClass("no_match"); - self.set("mode", "match"); - self.set("mv_lines_selected", mv_lines_selected); + var line = _.find(self.propositions_lines, function(o){ return o.id == line_id}); + $(mv_line).attr('data-selected','false'); + self.getParent().unexcludeMoveLines([line_id]); + self.set("mv_lines_selected",_.filter(self.get("mv_lines_selected"), function(o) { return o.id != line_id })); }, - /** Matches pagination */ pagerControlLeftHandler: function() { @@ -916,11 +855,9 @@ openerp.account = function (instance) { var self = this; self.set("pager_index", 0); self.filter = self.$(".filter").val(); - window.clearTimeout(self.apply_filter_timeout); - self.apply_filter_timeout = window.setTimeout(self.proxy('updateMatches'), 200); + self.render(); }, - /** Creating */ initializeCreateForm: function() { @@ -1052,20 +989,16 @@ openerp.account = function (instance) { table.empty(); var slice_start = self.get("pager_index") * self.max_move_lines_displayed; var slice_end = (self.get("pager_index")+1) * self.max_move_lines_displayed; - _( _.filter(self.mv_lines_deselected, function(o){ - return o.q_label.indexOf(self.filter) !== -1 || (o.ref && o.ref.indexOf(self.filter) !== -1) - }) - .slice(slice_start, slice_end)).each(function(line){ - var $line = $(QWeb.render("bank_statement_reconciliation_move_line", {line: line, selected: false})); - self.bindPopoverTo($line.find(".line_info_button")); - table.append($line); - nothing_displayed = false; - }); + + var visible = 0 _(self.get("mv_lines")).each(function(line){ - var $line = $(QWeb.render("bank_statement_reconciliation_move_line", {line: line, selected: false})); - self.bindPopoverTo($line.find(".line_info_button")); - table.append($line); - nothing_displayed = false; + if (visible >= slice_start && visible < slice_end) { + var $line = $(QWeb.render("bank_statement_reconciliation_move_line", {line: line, selected: false})); + self.bindPopoverTo($line.find(".line_info_button")); + table.append($line); + nothing_displayed = false; + } + visible = visible + 1; }); if (nothing_displayed) table.append(QWeb.render("filter_no_match", {filter_str: self.filter})); @@ -1077,7 +1010,7 @@ openerp.account = function (instance) { self.$(".pager_control_left").addClass("disabled"); else self.$(".pager_control_left").removeClass("disabled"); - if (self.total_move_lines_num <= ((self.get("pager_index")+1) * self.max_move_lines_displayed)) + if (self.get('mv_lines').length <= ((self.get("pager_index")+1) * self.max_move_lines_displayed)) self.$(".pager_control_right").addClass("disabled"); else self.$(".pager_control_right").removeClass("disabled"); @@ -1147,7 +1080,7 @@ openerp.account = function (instance) { self.el.dataset.mode = "inactive"; } else if (self.get("mode") === "match") { - return $.when(self.updateMatches()).then(function() { + return $.when(self.render()).then(function() { if (self.$el.hasClass("no_match")) { self.set("mode", "inactive"); return; @@ -1167,7 +1100,7 @@ openerp.account = function (instance) { pagerChanged: function() { var self = this; - self.updateMatches(); + self.render(); }, mvLinesChanged: function() { @@ -1178,7 +1111,7 @@ openerp.account = function (instance) { } // If there is no match to display, disable match view and pass in mode inactive - if (self.total_move_lines_num + self.mv_lines_deselected.length === 0 && self.filter === "") { + if (self.get("mv_lines").length === 0 && self.filter === "") { self.$el.addClass("no_match"); if (self.get("mode") === "match") { self.set("mode", "inactive"); @@ -1197,13 +1130,11 @@ openerp.account = function (instance) { 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 }); - self.getParent().excludeMoveLines(self, self.partner_id, added_lines_ids); - self.getParent().unexcludeMoveLines(self, self.partner_id, removed_lines_ids); + self.getParent().excludeMoveLines(added_lines_ids); + self.getParent().unexcludeMoveLines(removed_lines_ids); - $.when(self.updateMatches()).then(function(){ - self.updateAccountingViewMatchedLines(); - self.updateBalance(); - }); + self.updateAccountingViewMatchedLines(); + self.updateBalance(); }, // Generic function for updating the line_created_being_edited @@ -1350,47 +1281,22 @@ openerp.account = function (instance) { loadReconciliationProposition: function() { var self = this; return self.model_bank_statement_line - .call("get_reconciliation_proposition", [self.st_line.id, self.getParent().excluded_move_lines_ids[self.partner_id]]) + .call("get_reconciliation_proposition", [self.st_line.id, self.getParent().excluded_move_lines_ids]) .then(function (lines) { _(lines).each(self.decorateMoveLine.bind(self)); self.set("mv_lines_selected", self.get("mv_lines_selected").concat(lines)); }); }, - - // Loads move lines according to the widget's state - updateMatches: function() { + + render: function() { var self = this; - var deselected_lines_num = self.mv_lines_deselected.length; - var move_lines = {}; - var move_lines_num = 0; - var offset = self.get("pager_index") * self.max_move_lines_displayed - deselected_lines_num; - 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 deferred_move_lines; - if (limit > 0) { - // Load move lines - deferred_move_lines = self.model_bank_statement_line - .call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids]) - .then(function (lines) { - _(lines).each(self.decorateMoveLine.bind(self)); - move_lines = lines; - }); - } - // Fetch the number of move lines corresponding to this statement line and this filter - var deferred_total_move_lines_num = self.model_bank_statement_line - .call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids, [], true]) - .then(function(num){ - move_lines_num = num; - }); - - return $.when(deferred_move_lines, deferred_total_move_lines_num).then(function(){ - self.total_move_lines_num = move_lines_num + deselected_lines_num; - self.set("mv_lines", move_lines); + var lines_to_show = []; + _.each(self.propositions_lines, function(line){ + if (self.getParent().excluded_move_lines_ids.indexOf(line.id) === -1 && line.q_label.toLowerCase().indexOf(self.filter.toLowerCase()) > -1) { + lines_to_show.push(line); + } }); + self.set("mv_lines", lines_to_show); }, // Changes the partner_id of the statement_line in the DB and reloads the widget @@ -1450,7 +1356,7 @@ openerp.account = function (instance) { var self = this; 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(_.map(self.get("mv_lines_selected"), function(o){ return o.id })); // Prepare data var mv_line_dicts = []; 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 b5a8492545d..2c410404a4d 100644 --- a/addons/account/static/src/xml/account_bank_statement_reconciliation.xml +++ b/addons/account/static/src/xml/account_bank_statement_reconciliation.xml @@ -128,7 +128,7 @@ - + From 10568ffd3b53be7dbba87ee0ef19697a4ae6f343 Mon Sep 17 00:00:00 2001 From: Cedric Snauwaert Date: Fri, 20 Jun 2014 16:56:27 +0200 Subject: [PATCH 05/13] [FIX] account: structured communication have a higher priority --- addons/account/account_bank_statement.py | 34 +++++++++++++------ .../account/static/src/js/account_widgets.js | 2 -- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py index 7a45cf85041..2a75c94d91b 100644 --- a/addons/account/account_bank_statement.py +++ b/addons/account/account_bank_statement.py @@ -448,15 +448,31 @@ class account_bank_statement_line(osv.osv): """ Used to instanciate a batch of reconciliations in a single request """ # Build a list of reconciliations data ret = [] + statement_line_done = {} mv_line_ids_selected = [] + for st_line in self.browse(cr, uid, ids, context=context): + # look for structured communication first + exact_match_id = self.search_structured_com(cr, uid, st_line, context=context) + if exact_match_id: + reconciliation_data = { + 'st_line': self.get_statement_line_for_reconciliation(cr, uid, st_line.id, context), + 'reconciliation_proposition': self.make_counter_part_lines(cr, uid, st_line, [exact_match_id], context=context) + } + for mv_line in reconciliation_data['reconciliation_proposition']: + mv_line_ids_selected.append(mv_line['id']) + statement_line_done[st_line.id] = reconciliation_data + for st_line_id in ids: - reconciliation_data = { - 'st_line': self.get_statement_line_for_reconciliation(cr, uid, st_line_id, context), - 'reconciliation_proposition': self.get_reconciliation_proposition(cr, uid, st_line_id, mv_line_ids_selected, context) - } - for mv_line in reconciliation_data['reconciliation_proposition']: - mv_line_ids_selected.append(mv_line['id']) - ret.append(reconciliation_data) + if statement_line_done.get(st_line_id): + ret.append(statement_line_done.get(st_line_id)) + else: + reconciliation_data = { + 'st_line': self.get_statement_line_for_reconciliation(cr, uid, st_line_id, context), + 'reconciliation_proposition': self.get_reconciliation_proposition(cr, uid, st_line_id, mv_line_ids_selected, context) + } + for mv_line in reconciliation_data['reconciliation_proposition']: + mv_line_ids_selected.append(mv_line['id']) + ret.append(reconciliation_data) # Check if, now that 'candidate' move lines were selected, there are moves left for statement lines #for reconciliation_data in ret: @@ -529,10 +545,6 @@ class account_bank_statement_line(osv.osv): if st_line.amount < 0: sign = -1 - # look for structured communication - exact_match_id = self.search_structured_com(cr, uid, st_line, context=context) - if exact_match_id: - return self.make_counter_part_lines(cr, uid, st_line, [exact_match_id], context=context) #we don't propose anything if there is no partner detected if not st_line.partner_id.id: return [] diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js index b78c8514cb8..806375290d1 100644 --- a/addons/account/static/src/js/account_widgets.js +++ b/addons/account/static/src/js/account_widgets.js @@ -1356,8 +1356,6 @@ openerp.account = function (instance) { var self = this; if (! self.is_consistent) return; - self.getParent().unexcludeMoveLines(_.map(self.get("mv_lines_selected"), function(o){ return o.id })); - // Prepare data var mv_line_dicts = []; _.each(self.get("mv_lines_selected"), function(o) { mv_line_dicts.push(self.prepareSelectedMoveLineForPersisting(o)) }); From 2a69cb0f1d9a59a0b5150c6b9c725c15023c4eb5 Mon Sep 17 00:00:00 2001 From: qdp-odoo Date: Mon, 23 Jun 2014 11:40:25 +0200 Subject: [PATCH 06/13] [FIX] account: display 5 proposals in the bank statement reconciliation widget --- addons/account/account_bank_statement.py.rej | 104 +++ .../demo/account_bank_statement.xml.rej | 38 + .../account/static/src/js/account_widgets.js | 2 +- .../static/src/js/account_widgets.js.rej | 14 + ...ount_bank_statement_reconciliation.xml.rej | 11 + mydiff.diff | 655 ++++++++++++++++++ mydiff.diff2 | 655 ++++++++++++++++++ 7 files changed, 1478 insertions(+), 1 deletion(-) create mode 100644 addons/account/account_bank_statement.py.rej create mode 100644 addons/account/demo/account_bank_statement.xml.rej create mode 100644 addons/account/static/src/js/account_widgets.js.rej create mode 100644 addons/account/static/src/xml/account_bank_statement_reconciliation.xml.rej create mode 100644 mydiff.diff create mode 100644 mydiff.diff2 diff --git a/addons/account/account_bank_statement.py.rej b/addons/account/account_bank_statement.py.rej new file mode 100644 index 00000000000..124530c24ea --- /dev/null +++ b/addons/account/account_bank_statement.py.rej @@ -0,0 +1,104 @@ +--- addons/account/account_bank_statement.py ++++ addons/account/account_bank_statement.py +@@ -409,6 +417,10 @@ + 'domain':[('statement_id','in',ids)], + 'context':ctx, + } ++ ++ def number_of_lines_reconciled(self, cr, uid, id, context=None): ++ bsl_obj = self.pool.get('account.bank.statement.line') ++ return bsl_obj.search_count(cr, uid, [('statement_id', '=', id), ('journal_entry_id', '!=', False)], context=context) + + def get_format_currency_js_function(self, cr, uid, id, context=None): + """ Returns a string that can be used to instanciate a javascript function. +@@ -432,9 +444,11 @@ + done_currencies.append(st_line_currency.id) + return function + +- def number_of_lines_reconciled(self, cr, uid, id, context=None): +- bsl_obj = self.pool.get('account.bank.statement.line') +- return bsl_obj.search_count(cr, uid, [('statement_id', '=', id), ('journal_entry_id', '!=', False)], context=context) ++ def link_bank_to_partner(self, cr, uid, ids, context=None): ++ for statement in self.browse(cr, uid, ids, context=context): ++ for st_line in statement.line_ids: ++ if st_line.bank_account_id and st_line.partner_id and st_line.bank_account_id.partner_id.id != st_line.partner_id.id: ++ self.pool.get('res.partner.bank').write(cr, uid, [st_line.bank_account_id.id], {'partner_id': st_line.partner_id.id}, context=context) + + class account_bank_statement_line(osv.osv): + +@@ -453,11 +467,11 @@ + ret.append(reconciliation_data) + + # Check if, now that 'candidate' move lines were selected, there are moves left for statement lines +- for reconciliation_data in ret: +- if not reconciliation_data['st_line']['has_no_partner']: +- st_line = self.browse(cr, uid, reconciliation_data['st_line']['id'], context=context) +- if self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=mv_line_ids_selected, count=True, context=context) == 0: +- reconciliation_data['st_line']['no_match'] = True ++ #for reconciliation_data in ret: ++ # if not reconciliation_data['st_line']['has_no_partner']: ++ # st_line = self.browse(cr, uid, reconciliation_data['st_line']['id'], context=context) ++ # if not self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=mv_line_ids_selected, count=True, context=context): ++ # reconciliation_data['st_line']['no_match'] = True + return ret + + def get_statement_line_for_reconciliation(self, cr, uid, id, context=None): +@@ -483,7 +497,7 @@ + 'amount': amount, + 'amount_str': amount_str, + 'currency_id': line.currency_id.id or statement_currency.id, +- 'no_match': self.get_move_lines_counterparts(cr, uid, line, count=True, context=context) == 0 and line.partner_id.id, ++ 'no_match': self.get_move_lines_counterparts(cr, uid, line, count=True, context=context) == 0, + 'partner_id': line.partner_id.id, + 'statement_id': line.statement_id.id, + 'account_code': line.journal_id.default_debit_account_id.code, +@@ -501,7 +515,7 @@ + def search_structured_com(self, cr, uid, st_line, context=None): + if not st_line.ref: + return +- domain = [('name', '=', st_line.ref)] ++ domain = [('ref', '=', st_line.ref)] + if st_line.partner_id: + domain += [('partner_id', '=', st_line.partner_id.id)] + ids = self.pool.get('account.move.line').search(cr, uid, domain, limit=1, context=context) +@@ -527,6 +540,9 @@ + exact_match_id = self.search_structured_com(cr, uid, st_line, context=context) + if exact_match_id: + return self.make_counter_part_lines(cr, uid, st_line, [exact_match_id], count=False, context=context) ++ #we don't propose anything if there is no partner detected ++ if not st_line.partner_id.id: ++ return [] + # look for exact match + exact_match_id = self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=excluded_ids, limit=1, additional_domain=[(amount_field, '=', (sign * st_line.amount))]) + if exact_match_id: +@@ -542,10 +558,10 @@ + # get_move_lines_counterparts inverts debit and credit + amount_field = 'debit' if amount_field == 'credit' else 'credit' + for line in mv_lines: +- if total + line[amount_field] <= st_line.amount: ++ if total + line[amount_field] <= abs(st_line.amount): + ret.append(line) + total += line[amount_field] +- if total >= st_line.amount: ++ if total >= abs(st_line.amount): + break + return ret + +@@ -574,14 +590,15 @@ + if st_line.partner_id.id: + domain += [('partner_id', '=', st_line.partner_id.id), + '|', ('account_id.type', '=', 'receivable'), +- ('account_id.type', '=', 'payable'), # Let the front-end warn the user if he tries to mix payable and receivable in the same reconciliation +- ] ++ ('account_id.type', '=', 'payable')] + else: + domain += [('account_id.reconcile', '=', True)] + #domain += [('account_id.reconcile', '=', True), ('account_id.type', '=', 'other')] + if excluded_ids: + domain.append(('id', 'not in', excluded_ids)) + if filter_str: ++ if not st_line.partner_id: ++ domain += [ '|', ('partner_id.name', 'ilike', filter_str)] + domain += ['|', ('move_id.name', 'ilike', filter_str), ('move_id.ref', 'ilike', filter_str)] + line_ids = mv_line_pool.search(cr, uid, domain, offset=offset, limit=limit, order="date_maturity asc, id asc", context=context) + return self.make_counter_part_lines(cr, uid, st_line, line_ids, count=count, context=context) diff --git a/addons/account/demo/account_bank_statement.xml.rej b/addons/account/demo/account_bank_statement.xml.rej new file mode 100644 index 00000000000..e4ac1b8c1c6 --- /dev/null +++ b/addons/account/demo/account_bank_statement.xml.rej @@ -0,0 +1,38 @@ +--- addons/account/demo/account_bank_statement.xml ++++ addons/account/demo/account_bank_statement.xml +@@ -16,7 +17,7 @@ + + + +- ++ 001 + + + +@@ -27,7 +28,7 @@ + + + +- SAJ2014002 ++ 002 + + + +@@ -38,7 +39,7 @@ + + + +- ++ 003 + + + +@@ -48,7 +49,7 @@ + + + +- ++ 004 + + + diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js index 806375290d1..f1d549db7ba 100644 --- a/addons/account/static/src/js/account_widgets.js +++ b/addons/account/static/src/js/account_widgets.js @@ -29,7 +29,7 @@ openerp.account = function (instance) { this.time_widget_loaded = Date.now(); // Stuff used by the children bankStatementReconciliationLine - this.max_move_lines_displayed = 2; + this.max_move_lines_displayed = 5; this.animation_speed = 100; // "Blocking" animations this.aestetic_animation_speed = 300; // eye candy this.map_tax_id_amount = {}; diff --git a/addons/account/static/src/js/account_widgets.js.rej b/addons/account/static/src/js/account_widgets.js.rej new file mode 100644 index 00000000000..91faf3e7434 --- /dev/null +++ b/addons/account/static/src/js/account_widgets.js.rej @@ -0,0 +1,14 @@ +--- addons/account/static/src/js/account_widgets.js ++++ addons/account/static/src/js/account_widgets.js +@@ -1369,10 +1371,9 @@ + move_lines = lines; + }); + } +- + // Fetch the number of move lines corresponding to this statement line and this filter + var deferred_total_move_lines_num = self.model_bank_statement_line +- .call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids, self.filter, offset, limit, true]) ++ .call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids, self.filter, 0, undefined, true]) + .then(function(num){ + move_lines_num = num; + }); diff --git a/addons/account/static/src/xml/account_bank_statement_reconciliation.xml.rej b/addons/account/static/src/xml/account_bank_statement_reconciliation.xml.rej new file mode 100644 index 00000000000..4567597894d --- /dev/null +++ b/addons/account/static/src/xml/account_bank_statement_reconciliation.xml.rej @@ -0,0 +1,11 @@ +--- addons/account/static/src/xml/account_bank_statement_reconciliation.xml ++++ addons/account/static/src/xml/account_bank_statement_reconciliation.xml +@@ -185,7 +185,7 @@ + + + +- Open balance ++ Open balance + + + diff --git a/mydiff.diff b/mydiff.diff new file mode 100644 index 00000000000..45aad42742a --- /dev/null +++ b/mydiff.diff @@ -0,0 +1,655 @@ +diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py +index 004bcd3..1ddab4b 100644 +--- a/addons/account/account_bank_statement.py ++++ b/addons/account/account_bank_statement.py +@@ -26,6 +26,9 @@ from openerp.report import report_sxw + + class account_bank_statement(osv.osv): + def create(self, cr, uid, vals, context=None): ++ if vals.get('name', '/') == '/': ++ journal_id = vals.get('journal_id', self._default_journal_id(cr, uid, context=context)) ++ vals['name'] = self._compute_default_statement_name(cr, uid, journal_id, context=context) + if 'line_ids' in vals: + for idx, line in enumerate(vals['line_ids']): + line[2]['sequence'] = idx + 1 +@@ -65,17 +68,14 @@ class account_bank_statement(osv.osv): + return periods[0] + return False + +- def _compute_default_statement_name(self, cr, uid, context=None): ++ def _compute_default_statement_name(self, cr, uid, journal_id, context=None): + if context is None: + context = {} + obj_seq = self.pool.get('ir.sequence') +- default_journal_id = self._default_journal_id(cr, uid, context=context) +- if default_journal_id != False: +- period = self.pool.get('account.period').browse(cr, uid, self._get_period(cr, uid, context=context), context=context) +- context['fiscalyear_id'] = period.fiscalyear_id.id +- journal = self.pool.get('account.journal').browse(cr, uid, default_journal_id, None) +- return obj_seq.next_by_id(cr, uid, journal.sequence_id.id, context=context) +- return obj_seq.next_by_code(cr, uid, 'account.bank.statement', context=context) ++ period = self.pool.get('account.period').browse(cr, uid, self._get_period(cr, uid, context=context), context=context) ++ context['fiscalyear_id'] = period.fiscalyear_id.id ++ journal = self.pool.get('account.journal').browse(cr, uid, journal_id, None) ++ return obj_seq.next_by_id(cr, uid, journal.sequence_id.id, context=context) + + def _currency(self, cursor, user, ids, name, args, context=None): + res = {} +@@ -150,7 +150,7 @@ class account_bank_statement(osv.osv): + } + + _defaults = { +- 'name': _compute_default_statement_name, ++ 'name': '/', + 'date': fields.date.context_today, + 'state': 'draft', + 'journal_id': _default_journal_id, +@@ -329,21 +329,29 @@ class account_bank_statement(osv.osv): + move_ids.append(st_line.journal_entry_id.id) + self.pool.get('account.move').post(cr, uid, move_ids, context=context) + self.message_post(cr, uid, [st.id], body=_('Statement %s confirmed, journal items were created.') % (st.name,), context=context) ++ self.link_bank_to_partner(cr, uid, ids, context=context) + return self.write(cr, uid, ids, {'state':'confirm'}, context=context) + + def button_cancel(self, cr, uid, ids, context=None): +- done = [] + account_move_obj = self.pool.get('account.move') ++ reconcile_pool = self.pool.get('account.move.reconcile') ++ move_line_pool = self.pool.get('account.move.line') ++ move_ids = [] + for st in self.browse(cr, uid, ids, context=context): +- if st.state=='draft': +- continue +- move_ids = [] + for line in st.line_ids: +- move_ids += [x.id for x in line.move_ids] ++ if line.journal_entry_id: ++ move_ids.append(line.journal_entry_id.id) ++ for aml in line.journal_entry_id.line_id: ++ if aml.reconcile_id: ++ move_lines = [l.id for l in aml.reconcile_id.line_id] ++ move_lines.remove(aml.id) ++ reconcile_pool.unlink(cr, uid, [aml.reconcile_id.id], context=context) ++ if len(move_lines) >= 2: ++ move_line_pool.reconcile_partial(cr, uid, move_lines, 'auto', context=context) ++ if move_ids: + account_move_obj.button_cancel(cr, uid, move_ids, context=context) + account_move_obj.unlink(cr, uid, move_ids, context) +- done.append(st.id) +- return self.write(cr, uid, done, {'state':'draft'}, context=context) ++ return self.write(cr, uid, ids, {'state': 'draft'}, context=context) + + def _compute_balance_end_real(self, cr, uid, journal_id, context=None): + res = False +@@ -401,6 +409,10 @@ class account_bank_statement(osv.osv): + 'domain':[('statement_id','in',ids)], + 'context':ctx, + } ++ ++ def number_of_lines_reconciled(self, cr, uid, id, context=None): ++ bsl_obj = self.pool.get('account.bank.statement.line') ++ return bsl_obj.search_count(cr, uid, [('statement_id', '=', id), ('journal_entry_id', '!=', False)], context=context) + + def get_format_currency_js_function(self, cr, uid, id, context=None): + """ Returns a string that can be used to instanciate a javascript function. +@@ -424,9 +436,11 @@ class account_bank_statement(osv.osv): + done_currencies.append(st_line_currency.id) + return function + +- def number_of_lines_reconciled(self, cr, uid, id, context=None): +- bsl_obj = self.pool.get('account.bank.statement.line') +- return bsl_obj.search_count(cr, uid, [('statement_id', '=', id), ('journal_entry_id', '!=', False)], context=context) ++ def link_bank_to_partner(self, cr, uid, ids, context=None): ++ for statement in self.browse(cr, uid, ids, context=context): ++ for st_line in statement.line_ids: ++ if st_line.bank_account_id and st_line.partner_id and st_line.bank_account_id.partner_id.id != st_line.partner_id.id: ++ self.pool.get('res.partner.bank').write(cr, uid, [st_line.bank_account_id.id], {'partner_id': st_line.partner_id.id}, context=context) + + class account_bank_statement_line(osv.osv): + +@@ -445,11 +459,11 @@ class account_bank_statement_line(osv.osv): + ret.append(reconciliation_data) + + # Check if, now that 'candidate' move lines were selected, there are moves left for statement lines +- for reconciliation_data in ret: +- if not reconciliation_data['st_line']['has_no_partner']: +- st_line = self.browse(cr, uid, reconciliation_data['st_line']['id'], context=context) +- if self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=mv_line_ids_selected, count=True, context=context) == 0: +- reconciliation_data['st_line']['no_match'] = True ++ #for reconciliation_data in ret: ++ # if not reconciliation_data['st_line']['has_no_partner']: ++ # st_line = self.browse(cr, uid, reconciliation_data['st_line']['id'], context=context) ++ # if not self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=mv_line_ids_selected, count=True, context=context): ++ # reconciliation_data['st_line']['no_match'] = True + return ret + + def get_statement_line_for_reconciliation(self, cr, uid, id, context=None): +@@ -475,7 +489,7 @@ class account_bank_statement_line(osv.osv): + 'amount': amount, + 'amount_str': amount_str, + 'currency_id': line.currency_id.id or statement_currency.id, +- 'no_match': self.get_move_lines_counterparts(cr, uid, line, count=True, context=context) == 0 and line.partner_id.id, ++ 'no_match': self.get_move_lines_counterparts(cr, uid, line, count=True, context=context) == 0, + 'partner_id': line.partner_id.id, + 'statement_id': line.statement_id.id, + 'account_code': line.journal_id.default_debit_account_id.code, +@@ -493,7 +507,7 @@ class account_bank_statement_line(osv.osv): + def search_structured_com(self, cr, uid, st_line, context=None): + if not st_line.ref: + return +- domain = [('name', '=', st_line.ref)] ++ domain = [('ref', '=', st_line.ref)] + if st_line.partner_id: + domain += [('partner_id', '=', st_line.partner_id.id)] + ids = self.pool.get('account.move.line').search(cr, uid, domain, limit=1, context=context) +@@ -504,7 +518,6 @@ class account_bank_statement_line(osv.osv): + st_line = self.browse(cr, uid, id, context=context) + company_currency = st_line.journal_id.company_id.currency_id.id + statement_currency = st_line.journal_id.currency.id or company_currency +- + # either use the unsigned debit/credit fields or the signed amount_currency field + sign = 1 + if statement_currency == company_currency: +@@ -520,6 +533,9 @@ class account_bank_statement_line(osv.osv): + exact_match_id = self.search_structured_com(cr, uid, st_line, context=context) + if exact_match_id: + return self.make_counter_part_lines(cr, uid, st_line, [exact_match_id], count=False, context=context) ++ #we don't propose anything if there is no partner detected ++ if not st_line.partner_id.id: ++ return [] + # look for exact match + exact_match_id = self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=excluded_ids, limit=1, additional_domain=[(amount_field, '=', (sign * st_line.amount))]) + if exact_match_id: +@@ -535,10 +551,10 @@ class account_bank_statement_line(osv.osv): + # get_move_lines_counterparts inverts debit and credit + amount_field = 'debit' if amount_field == 'credit' else 'credit' + for line in mv_lines: +- if total + line[amount_field] <= st_line.amount: ++ if total + line[amount_field] <= abs(st_line.amount): + ret.append(line) + total += line[amount_field] +- if total >= st_line.amount: ++ if total >= abs(st_line.amount): + break + return ret + +@@ -567,14 +583,15 @@ class account_bank_statement_line(osv.osv): + if st_line.partner_id.id: + domain += [('partner_id', '=', st_line.partner_id.id), + '|', ('account_id.type', '=', 'receivable'), +- ('account_id.type', '=', 'payable'), # Let the front-end warn the user if he tries to mix payable and receivable in the same reconciliation +- ] ++ ('account_id.type', '=', 'payable')] + else: + domain += [('account_id.reconcile', '=', True)] + #domain += [('account_id.reconcile', '=', True), ('account_id.type', '=', 'other')] + if excluded_ids: + domain.append(('id', 'not in', excluded_ids)) + if filter_str: ++ if not st_line.partner_id: ++ domain += [ '|', ('partner_id.name', 'ilike', filter_str)] + domain += ['|', ('move_id.name', 'ilike', filter_str), ('move_id.ref', 'ilike', filter_str)] + line_ids = mv_line_pool.search(cr, uid, domain, offset=offset, limit=limit, order="date_maturity asc, id asc", context=context) + return self.make_counter_part_lines(cr, uid, st_line, line_ids, count=count, context=context) +diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py +index a37ca6a..5926b97 100644 +--- a/addons/account/account_move_line.py ++++ b/addons/account/account_move_line.py +@@ -127,8 +127,8 @@ class account_move_line(osv.osv): + + if move_line.reconcile_id: + continue +- if not move_line.account_id.type in ('payable', 'receivable'): +- #this function does not suport to be used on move lines not related to payable or receivable accounts ++ if not move_line.account_id.reconcile: ++ #this function does not suport to be used on move lines not related to a reconcilable account + continue + + if move_line.currency_id: +diff --git a/addons/account/demo/account_bank_statement.xml b/addons/account/demo/account_bank_statement.xml +index 5266782..b79d8b9 100644 +--- a/addons/account/demo/account_bank_statement.xml ++++ b/addons/account/demo/account_bank_statement.xml +@@ -7,7 +7,6 @@ + + + +- none + BNK/2014/001 + + +@@ -16,7 +15,7 @@ + + + +- 001 ++ + + + +@@ -27,7 +26,7 @@ + + + +- 002 ++ SAJ2014002 + + + +@@ -38,7 +37,7 @@ + + + +- 003 ++ + + + +@@ -48,7 +47,7 @@ + + + +- 004 ++ + + + +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 626d1f3..05caeab 100644 +--- a/addons/account/static/src/css/account_bank_statement_reconciliation.css ++++ b/addons/account/static/src/css/account_bank_statement_reconciliation.css +@@ -120,8 +120,6 @@ + cursor: pointer; } + .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line.no_match:not(.no_partner) .toggle_match { + visibility: hidden !important; } +- .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line.no_partner .partner_name, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line.no_partner .line_open_balance { +- display: none !important; } + .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line > table > tbody > tr:nth-child(1) > td table { + margin-bottom: 10px; } + .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line table.details td:first-child { +@@ -202,10 +200,6 @@ + cursor: pointer; } + .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view td:nth-child(6) { + border-left: 1px solid black; } +- .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr.initial_line > td:nth-child(5) { +- border-top: 1px solid black; } +- .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr.initial_line > td:nth-child(6) { +- border-top: 1px solid black; } + .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 3b98689..248536b 100644 +--- a/addons/account/static/src/css/account_bank_statement_reconciliation.scss ++++ b/addons/account/static/src/css/account_bank_statement_reconciliation.scss +@@ -194,12 +194,6 @@ $initialLineBackground: #f0f0f0; + } + } + +- &.no_partner { +- .partner_name, .line_open_balance { +- display: none !important; +- } +- } +- + /* gap between accounting_view and action view */ + > table > tbody > tr:nth-child(1) > td table { + margin-bottom: 10px; +@@ -341,10 +335,6 @@ $initialLineBackground: #f0f0f0; + + // accounting "T" + td:nth-child(6) { border-left: $accountingBorder; } +- tr.initial_line > td { +- &:nth-child(5) { border-top: $accountingBorder; } +- &:nth-child(6) { border-top: $accountingBorder; } +- } + } + + +diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js +index 56fdaaf..8f5786e 100644 +--- a/addons/account/static/src/js/account_widgets.js ++++ b/addons/account/static/src/js/account_widgets.js +@@ -245,7 +245,7 @@ openerp.account = function (instance) { + + keyboardShortcutsHandler: function(e) { + var self = this; +- if (e.which === 13 && (e.ctrlKey || e.metaKey)) { ++ if ((e.which === 13 || e.which === 10) && (e.ctrlKey || e.metaKey)) { + $.each(self.getChildren(), function(i, o){ + if (o.is_valid && o.persistAndDestroy()) { + self.lines_reconciled_with_ctrl_enter++; +@@ -789,6 +789,9 @@ openerp.account = function (instance) { + line.q_amount = (line.debit !== 0 ? "- "+line.q_debit : "") + (line.credit !== 0 ? line.q_credit : ""); + line.q_popover = QWeb.render("bank_statement_reconciliation_move_line_details", {line: line}); + line.q_label = line.name; ++ if (line.has_no_partner){ ++ line.q_label = line.partner_name + ': ' +line.q_label; ++ } + + // WARNING : pretty much of a ugly hack + // The value of account_move.ref is either the move's communication or it's name without the slashes +@@ -981,6 +984,7 @@ openerp.account = function (instance) { + lineOpenBalanceClickHandler: function() { + var self = this; + if (self.get("mode") === "create") { ++ self.addLineBeingEdited(); + self.set("mode", "match"); + } else { + self.set("mode", "create"); +@@ -1038,7 +1042,8 @@ openerp.account = function (instance) { + var slice_start = self.get("pager_index") * self.max_move_lines_displayed; + var slice_end = (self.get("pager_index")+1) * self.max_move_lines_displayed; + _( _.filter(self.mv_lines_deselected, function(o){ +- return o.name.indexOf(self.filter) !== -1 || o.ref.indexOf(self.filter) !== -1 }) ++ return o.q_label.indexOf(self.filter) !== -1 || (o.ref && o.ref.indexOf(self.filter) !== -1) ++ }) + .slice(slice_start, slice_end)).each(function(line){ + var $line = $(QWeb.render("bank_statement_reconciliation_move_line", {line: line, selected: false})); + self.bindPopoverTo($line.find(".line_info_button")); +@@ -1057,7 +1062,6 @@ openerp.account = function (instance) { + + updatePagerControls: function() { + var self = this; +- + if (self.get("pager_index") === 0) + self.$(".pager_control_left").addClass("disabled"); + else +@@ -1075,7 +1079,7 @@ openerp.account = function (instance) { + balanceChanged: function() { + var self = this; + var balance = self.get("balance"); +- ++ self.$(".tbody_open_balance").empty(); + // Special case hack : no identified partner + if (self.st_line.has_no_partner) { + if (Math.abs(balance).toFixed(3) === "0.000") { +@@ -1088,11 +1092,15 @@ openerp.account = function (instance) { + self.$(".button_ok").attr("disabled", "disabled"); + self.$(".button_ok").text("OK"); + self.is_valid = false; ++ var debit = (balance > 0 ? self.formatCurrency(balance, self.st_line.currency_id) : ""); ++ var credit = (balance < 0 ? self.formatCurrency(-1*balance, self.st_line.currency_id) : ""); ++ var $line = $(QWeb.render("bank_statement_reconciliation_line_open_balance", {debit: debit, credit: credit, account_code: self.map_account_id_code[self.st_line.open_balance_account_id]})); ++ $line.find('.js_open_balance')[0].innerHTML = "Choose counterpart"; ++ self.$(".tbody_open_balance").append($line); + } + return; + } + +- self.$(".tbody_open_balance").empty(); + if (Math.abs(balance).toFixed(3) === "0.000") { + self.$(".button_ok").addClass("oe_highlight"); + self.$(".button_ok").text("OK"); +@@ -1111,21 +1119,15 @@ openerp.account = function (instance) { + + self.$(".action_pane.active").removeClass("active"); + +- // Special case hack : if no_partner, either inactive or create ++ // Special case hack : if no_partner and mode == inactive + 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; ++ return; ++ } + } + + if (self.get("mode") === "inactive") { +@@ -1367,10 +1369,9 @@ openerp.account = function (instance) { + move_lines = lines; + }); + } +- + // Fetch the number of move lines corresponding to this statement line and this filter + var deferred_total_move_lines_num = self.model_bank_statement_line +- .call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids, self.filter, offset, limit, true]) ++ .call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids, self.filter, 0, undefined, true]) + .then(function(num){ + move_lines_num = num; + }); +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 4ea6761..b5a8492 100644 +--- a/addons/account/static/src/xml/account_bank_statement_reconciliation.xml ++++ b/addons/account/static/src/xml/account_bank_statement_reconciliation.xml +@@ -128,7 +128,7 @@ + + + +- : ++ + + + +@@ -185,7 +185,7 @@ + + + +- Open balance ++ Open balance + + + +diff --git a/addons/l10n_be_coda/l10n_be_coda.py b/addons/l10n_be_coda/l10n_be_coda.py +index 0dfa9bf..c4cd8ab 100644 +--- a/addons/l10n_be_coda/l10n_be_coda.py ++++ b/addons/l10n_be_coda/l10n_be_coda.py +@@ -28,46 +28,4 @@ class account_bank_statement(osv.osv): + } + + +-class account_bank_statement_line(osv.osv): +- _inherit = 'account.bank.statement.line' +- _columns = { +- 'coda_account_number': fields.char('Account Number', help="The Counter Party Account Number") +- } +- +- def create(self, cr, uid, data, context=None): +- """ +- This function creates a Bank Account Number if, for a bank statement line, +- the partner_id field and the coda_account_number field are set, +- and the account number does not exist in the database +- """ +- if 'partner_id' in data and data['partner_id'] and 'coda_account_number' in data and data['coda_account_number']: +- acc_number_ids = self.pool.get('res.partner.bank').search(cr, uid, [('acc_number', '=', data['coda_account_number'])]) +- if len(acc_number_ids) == 0: +- try: +- type_model, type_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'bank_normal') +- type_id = self.pool.get('res.partner.bank.type').browse(cr, uid, type_id, context=context) +- self.pool.get('res.partner.bank').create(cr, uid, {'acc_number': data['coda_account_number'], 'partner_id': data['partner_id'], 'state': type_id.code}, context=context) +- except ValueError: +- pass +- return super(account_bank_statement_line, self).create(cr, uid, data, context=context) +- +- def write(self, cr, uid, ids, vals, context=None): +- super(account_bank_statement_line, self).write(cr, uid, ids, vals, context) +- """ +- Same as create function above, but for write function +- """ +- if 'partner_id' in vals: +- for line in self.pool.get('account.bank.statement.line').browse(cr, uid, ids, context=context): +- if line.coda_account_number: +- acc_number_ids = self.pool.get('res.partner.bank').search(cr, uid, [('acc_number', '=', line.coda_account_number)]) +- if len(acc_number_ids) == 0: +- try: +- type_model, type_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'bank_normal') +- type_id = self.pool.get('res.partner.bank.type').browse(cr, uid, type_id, context=context) +- self.pool.get('res.partner.bank').create(cr, uid, {'acc_number': line.coda_account_number, 'partner_id': vals['partner_id'], 'state': type_id.code}, context=context) +- except ValueError: +- pass +- return True +- +- + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: +diff --git a/addons/l10n_be_coda/l10n_be_coda_demo.xml b/addons/l10n_be_coda/l10n_be_coda_demo.xml +index 63436a6..ce44539 100644 +--- a/addons/l10n_be_coda/l10n_be_coda_demo.xml ++++ b/addons/l10n_be_coda/l10n_be_coda_demo.xml +@@ -32,5 +32,27 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ draft ++ out_invoice ++ ++ ++ bba ++ +++240/2838/42818+++ ++ ++ ++ Otpez Laptop without OS ++ ++ 608.89 ++ 10 ++ ++ ++ + + +diff --git a/addons/l10n_be_coda/test_coda_file/Ontvangen_CODA.2011-01-11-18.59.15.txt b/addons/l10n_be_coda/test_coda_file/Ontvangen_CODA.2011-01-11-18.59.15.txt +index bc3af59..d0add85 100644 +--- a/addons/l10n_be_coda/test_coda_file/Ontvangen_CODA.2011-01-11-18.59.15.txt ++++ b/addons/l10n_be_coda/test_coda_file/Ontvangen_CODA.2011-01-11-18.59.15.txt +@@ -4,7 +4,7 @@ + 2200010000 GKCCBEBB 1 0 + 2300010000BE41063012345610 PARTNER 1 0 1 + 3100010001OL44483FW SCTOFBIONLO001010001001PARTNER 1 0 0 +-2100020000OL4414AC8BOVSOVSOVERS00000000030444501101110015000002010237 11011113501 0 ++2100020000OL4414AC8BOVSOVSOVERS0000000003044450110111001500001101240283842818 11011113501 0 + 2200020000 BBRUBEBB 1 0 + 2300020000BE61310126985517 PARTNER 2 0 1 + 3100020001OL4414AC8BOVSOVSOVERS001500001001PARTNER 2 1 0 +diff --git a/addons/l10n_be_coda/wizard/account_coda_import.py b/addons/l10n_be_coda/wizard/account_coda_import.py +index e50f853..cac4cce 100644 +--- a/addons/l10n_be_coda/wizard/account_coda_import.py ++++ b/addons/l10n_be_coda/wizard/account_coda_import.py +@@ -291,79 +291,38 @@ class account_coda_import(osv.osv_memory): + if 'counterpartyAddress' in line and line['counterpartyAddress'] != '': + note.append(_('Counter Party Address') + ': ' + line['counterpartyAddress']) + line['name'] = "\n".join(filter(None, [line['counterpartyName'], line['communication']])) +- partner = None + partner_id = None +- invoice = False ++ structured_com = "" ++ bank_account_id = False + if line['communication_struct'] and 'communication_type' in line and line['communication_type'] == '101': +- ids = self.pool.get('account.invoice').search(cr, uid, [('reference', '=', line['communication']), ('reference_type', '=', 'bba')]) +- +-# Gère les communications structurées +-# TODO : à faire primer sur resolution_proposition : si la communication indique une facture, on la sélectionne +- +-# if ids: +-# invoice = self.pool.get('account.invoice').browse(cr, uid, ids[0]) +-# partner = invoice.partner_id +-# partner_id = partner.id +-# if invoice.type in ['in_invoice', 'in_refund'] and line['debit'] == '1': +-# line['transaction_type'] = 'supplier' +-# elif invoice.type in ['out_invoice', 'out_refund'] and line['debit'] == '0': +-# line['transaction_type'] = 'customer' +-# line['account'] = invoice.account_id.id +-# line['reconcile'] = False +-# if invoice.type in ['in_invoice', 'out_invoice']: +-# iml_ids = self.pool.get('account.move.line').search(cr, uid, [('move_id', '=', invoice.move_id.id), ('reconcile_id', '=', False), ('account_id.reconcile', '=', True)]) +-# if iml_ids: +-# line['reconcile'] = iml_ids[0] +-# if line['reconcile']: +-# voucher_vals = { +-# 'type': line['transaction_type'] == 'supplier' and 'payment' or 'receipt', +-# 'name': line['name'], +-# 'partner_id': partner_id, +-# 'journal_id': statement['journal_id'].id, +-# 'account_id': statement['journal_id'].default_credit_account_id.id, +-# 'company_id': statement['journal_id'].company_id.id, +-# 'currency_id': statement['journal_id'].company_id.currency_id.id, +-# 'date': line['entryDate'], +-# 'amount': abs(line['amount']), +-# 'period_id': statement['period_id'], +-# 'invoice_id': invoice.id, +-# } +-# context['invoice_id'] = invoice.id +-# voucher_vals.update(self.pool.get('account.voucher').onchange_partner_id(cr, uid, [], +-# partner_id=partner_id, +-# journal_id=statement['journal_id'].id, +-# amount=abs(line['amount']), +-# currency_id=statement['journal_id'].company_id.currency_id.id, +-# ttype=line['transaction_type'] == 'supplier' and 'payment' or 'receipt', +-# date=line['transactionDate'], +-# context=context +-# )['value']) +-# line_drs = [] +-# for line_dr in voucher_vals['line_dr_ids']: +-# line_drs.append((0, 0, line_dr)) +-# voucher_vals['line_dr_ids'] = line_drs +-# line_crs = [] +-# for line_cr in voucher_vals['line_cr_ids']: +-# line_crs.append((0, 0, line_cr)) +-# voucher_vals['line_cr_ids'] = line_crs +-# line['voucher_id'] = self.pool.get('account.voucher').create(cr, uid, voucher_vals, context=context) ++ structured_com = line['communication'] + if 'counterpartyNumber' in line and line['counterpartyNumber']: + ids = self.pool.get('res.partner.bank').search(cr, uid, [('acc_number', '=', str(line['counterpartyNumber']))]) +- if ids and len(ids) > 0: +- partner = self.pool.get('res.partner.bank').browse(cr, uid, ids[0], context=context).partner_id +- partner_id = partner.id ++ if ids: ++ bank_account_id = ids[0] ++ partner_id = self.pool.get('res.partner.bank').browse(cr, uid, bank_account_id, context=context).partner_id.id ++ else: ++ #create the bank account, not linked to any partner. The reconciliation will link the partner manually ++ #chosen at the bank statement final confirmation time. ++ try: ++ type_model, type_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'bank_normal') ++ type_id = self.pool.get('res.partner.bank.type').browse(cr, uid, type_id, context=context) ++ bank_code = type_id.code ++ except ValueError: ++ bank_code = 'bank' ++ bank_account_id = self.pool.get('res.partner.bank').create(cr, uid, {'acc_number': str(line['counterpartyNumber']), 'state': bank_code}, context=context) + if 'communication' in line and line['communication'] != '': + note.append(_('Communication') + ': ' + line['communication']) + data = { + 'name': line['name'], +- 'note': "\n".join(note), ++ 'note': "\n".join(note), + 'date': line['entryDate'], + 'amount': line['amount'], + 'partner_id': partner_id, + 'statement_id': statement['id'], +- 'ref': line['ref'], ++ 'ref': structured_com, + 'sequence': line['sequence'], +- 'coda_account_number': line['counterpartyNumber'], ++ 'bank_account_id': bank_account_id, + } + self.pool.get('account.bank.statement.line').create(cr, uid, data, context=context) + if statement['coda_note'] != '': +diff --git a/openerp/addons/base/res/res_bank.py b/openerp/addons/base/res/res_bank.py +index cc29c50..e8477ec 100644 +--- a/openerp/addons/base/res/res_bank.py ++++ b/openerp/addons/base/res/res_bank.py +@@ -128,8 +128,7 @@ class res_partner_bank(osv.osv): + change_default=True, domain="[('country_id','=',country_id)]"), + 'company_id': fields.many2one('res.company', 'Company', + ondelete='cascade', help="Only if this bank account belong to your company"), +- 'partner_id': fields.many2one('res.partner', 'Account Owner', required=True, +- ondelete='cascade', select=True), ++ 'partner_id': fields.many2one('res.partner', 'Account Owner', ondelete='cascade', select=True), + 'state': fields.selection(_bank_type_get, 'Bank Account Type', required=True, + change_default=True), + 'sequence': fields.integer('Sequence'), diff --git a/mydiff.diff2 b/mydiff.diff2 new file mode 100644 index 00000000000..45aad42742a --- /dev/null +++ b/mydiff.diff2 @@ -0,0 +1,655 @@ +diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py +index 004bcd3..1ddab4b 100644 +--- a/addons/account/account_bank_statement.py ++++ b/addons/account/account_bank_statement.py +@@ -26,6 +26,9 @@ from openerp.report import report_sxw + + class account_bank_statement(osv.osv): + def create(self, cr, uid, vals, context=None): ++ if vals.get('name', '/') == '/': ++ journal_id = vals.get('journal_id', self._default_journal_id(cr, uid, context=context)) ++ vals['name'] = self._compute_default_statement_name(cr, uid, journal_id, context=context) + if 'line_ids' in vals: + for idx, line in enumerate(vals['line_ids']): + line[2]['sequence'] = idx + 1 +@@ -65,17 +68,14 @@ class account_bank_statement(osv.osv): + return periods[0] + return False + +- def _compute_default_statement_name(self, cr, uid, context=None): ++ def _compute_default_statement_name(self, cr, uid, journal_id, context=None): + if context is None: + context = {} + obj_seq = self.pool.get('ir.sequence') +- default_journal_id = self._default_journal_id(cr, uid, context=context) +- if default_journal_id != False: +- period = self.pool.get('account.period').browse(cr, uid, self._get_period(cr, uid, context=context), context=context) +- context['fiscalyear_id'] = period.fiscalyear_id.id +- journal = self.pool.get('account.journal').browse(cr, uid, default_journal_id, None) +- return obj_seq.next_by_id(cr, uid, journal.sequence_id.id, context=context) +- return obj_seq.next_by_code(cr, uid, 'account.bank.statement', context=context) ++ period = self.pool.get('account.period').browse(cr, uid, self._get_period(cr, uid, context=context), context=context) ++ context['fiscalyear_id'] = period.fiscalyear_id.id ++ journal = self.pool.get('account.journal').browse(cr, uid, journal_id, None) ++ return obj_seq.next_by_id(cr, uid, journal.sequence_id.id, context=context) + + def _currency(self, cursor, user, ids, name, args, context=None): + res = {} +@@ -150,7 +150,7 @@ class account_bank_statement(osv.osv): + } + + _defaults = { +- 'name': _compute_default_statement_name, ++ 'name': '/', + 'date': fields.date.context_today, + 'state': 'draft', + 'journal_id': _default_journal_id, +@@ -329,21 +329,29 @@ class account_bank_statement(osv.osv): + move_ids.append(st_line.journal_entry_id.id) + self.pool.get('account.move').post(cr, uid, move_ids, context=context) + self.message_post(cr, uid, [st.id], body=_('Statement %s confirmed, journal items were created.') % (st.name,), context=context) ++ self.link_bank_to_partner(cr, uid, ids, context=context) + return self.write(cr, uid, ids, {'state':'confirm'}, context=context) + + def button_cancel(self, cr, uid, ids, context=None): +- done = [] + account_move_obj = self.pool.get('account.move') ++ reconcile_pool = self.pool.get('account.move.reconcile') ++ move_line_pool = self.pool.get('account.move.line') ++ move_ids = [] + for st in self.browse(cr, uid, ids, context=context): +- if st.state=='draft': +- continue +- move_ids = [] + for line in st.line_ids: +- move_ids += [x.id for x in line.move_ids] ++ if line.journal_entry_id: ++ move_ids.append(line.journal_entry_id.id) ++ for aml in line.journal_entry_id.line_id: ++ if aml.reconcile_id: ++ move_lines = [l.id for l in aml.reconcile_id.line_id] ++ move_lines.remove(aml.id) ++ reconcile_pool.unlink(cr, uid, [aml.reconcile_id.id], context=context) ++ if len(move_lines) >= 2: ++ move_line_pool.reconcile_partial(cr, uid, move_lines, 'auto', context=context) ++ if move_ids: + account_move_obj.button_cancel(cr, uid, move_ids, context=context) + account_move_obj.unlink(cr, uid, move_ids, context) +- done.append(st.id) +- return self.write(cr, uid, done, {'state':'draft'}, context=context) ++ return self.write(cr, uid, ids, {'state': 'draft'}, context=context) + + def _compute_balance_end_real(self, cr, uid, journal_id, context=None): + res = False +@@ -401,6 +409,10 @@ class account_bank_statement(osv.osv): + 'domain':[('statement_id','in',ids)], + 'context':ctx, + } ++ ++ def number_of_lines_reconciled(self, cr, uid, id, context=None): ++ bsl_obj = self.pool.get('account.bank.statement.line') ++ return bsl_obj.search_count(cr, uid, [('statement_id', '=', id), ('journal_entry_id', '!=', False)], context=context) + + def get_format_currency_js_function(self, cr, uid, id, context=None): + """ Returns a string that can be used to instanciate a javascript function. +@@ -424,9 +436,11 @@ class account_bank_statement(osv.osv): + done_currencies.append(st_line_currency.id) + return function + +- def number_of_lines_reconciled(self, cr, uid, id, context=None): +- bsl_obj = self.pool.get('account.bank.statement.line') +- return bsl_obj.search_count(cr, uid, [('statement_id', '=', id), ('journal_entry_id', '!=', False)], context=context) ++ def link_bank_to_partner(self, cr, uid, ids, context=None): ++ for statement in self.browse(cr, uid, ids, context=context): ++ for st_line in statement.line_ids: ++ if st_line.bank_account_id and st_line.partner_id and st_line.bank_account_id.partner_id.id != st_line.partner_id.id: ++ self.pool.get('res.partner.bank').write(cr, uid, [st_line.bank_account_id.id], {'partner_id': st_line.partner_id.id}, context=context) + + class account_bank_statement_line(osv.osv): + +@@ -445,11 +459,11 @@ class account_bank_statement_line(osv.osv): + ret.append(reconciliation_data) + + # Check if, now that 'candidate' move lines were selected, there are moves left for statement lines +- for reconciliation_data in ret: +- if not reconciliation_data['st_line']['has_no_partner']: +- st_line = self.browse(cr, uid, reconciliation_data['st_line']['id'], context=context) +- if self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=mv_line_ids_selected, count=True, context=context) == 0: +- reconciliation_data['st_line']['no_match'] = True ++ #for reconciliation_data in ret: ++ # if not reconciliation_data['st_line']['has_no_partner']: ++ # st_line = self.browse(cr, uid, reconciliation_data['st_line']['id'], context=context) ++ # if not self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=mv_line_ids_selected, count=True, context=context): ++ # reconciliation_data['st_line']['no_match'] = True + return ret + + def get_statement_line_for_reconciliation(self, cr, uid, id, context=None): +@@ -475,7 +489,7 @@ class account_bank_statement_line(osv.osv): + 'amount': amount, + 'amount_str': amount_str, + 'currency_id': line.currency_id.id or statement_currency.id, +- 'no_match': self.get_move_lines_counterparts(cr, uid, line, count=True, context=context) == 0 and line.partner_id.id, ++ 'no_match': self.get_move_lines_counterparts(cr, uid, line, count=True, context=context) == 0, + 'partner_id': line.partner_id.id, + 'statement_id': line.statement_id.id, + 'account_code': line.journal_id.default_debit_account_id.code, +@@ -493,7 +507,7 @@ class account_bank_statement_line(osv.osv): + def search_structured_com(self, cr, uid, st_line, context=None): + if not st_line.ref: + return +- domain = [('name', '=', st_line.ref)] ++ domain = [('ref', '=', st_line.ref)] + if st_line.partner_id: + domain += [('partner_id', '=', st_line.partner_id.id)] + ids = self.pool.get('account.move.line').search(cr, uid, domain, limit=1, context=context) +@@ -504,7 +518,6 @@ class account_bank_statement_line(osv.osv): + st_line = self.browse(cr, uid, id, context=context) + company_currency = st_line.journal_id.company_id.currency_id.id + statement_currency = st_line.journal_id.currency.id or company_currency +- + # either use the unsigned debit/credit fields or the signed amount_currency field + sign = 1 + if statement_currency == company_currency: +@@ -520,6 +533,9 @@ class account_bank_statement_line(osv.osv): + exact_match_id = self.search_structured_com(cr, uid, st_line, context=context) + if exact_match_id: + return self.make_counter_part_lines(cr, uid, st_line, [exact_match_id], count=False, context=context) ++ #we don't propose anything if there is no partner detected ++ if not st_line.partner_id.id: ++ return [] + # look for exact match + exact_match_id = self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=excluded_ids, limit=1, additional_domain=[(amount_field, '=', (sign * st_line.amount))]) + if exact_match_id: +@@ -535,10 +551,10 @@ class account_bank_statement_line(osv.osv): + # get_move_lines_counterparts inverts debit and credit + amount_field = 'debit' if amount_field == 'credit' else 'credit' + for line in mv_lines: +- if total + line[amount_field] <= st_line.amount: ++ if total + line[amount_field] <= abs(st_line.amount): + ret.append(line) + total += line[amount_field] +- if total >= st_line.amount: ++ if total >= abs(st_line.amount): + break + return ret + +@@ -567,14 +583,15 @@ class account_bank_statement_line(osv.osv): + if st_line.partner_id.id: + domain += [('partner_id', '=', st_line.partner_id.id), + '|', ('account_id.type', '=', 'receivable'), +- ('account_id.type', '=', 'payable'), # Let the front-end warn the user if he tries to mix payable and receivable in the same reconciliation +- ] ++ ('account_id.type', '=', 'payable')] + else: + domain += [('account_id.reconcile', '=', True)] + #domain += [('account_id.reconcile', '=', True), ('account_id.type', '=', 'other')] + if excluded_ids: + domain.append(('id', 'not in', excluded_ids)) + if filter_str: ++ if not st_line.partner_id: ++ domain += [ '|', ('partner_id.name', 'ilike', filter_str)] + domain += ['|', ('move_id.name', 'ilike', filter_str), ('move_id.ref', 'ilike', filter_str)] + line_ids = mv_line_pool.search(cr, uid, domain, offset=offset, limit=limit, order="date_maturity asc, id asc", context=context) + return self.make_counter_part_lines(cr, uid, st_line, line_ids, count=count, context=context) +diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py +index a37ca6a..5926b97 100644 +--- a/addons/account/account_move_line.py ++++ b/addons/account/account_move_line.py +@@ -127,8 +127,8 @@ class account_move_line(osv.osv): + + if move_line.reconcile_id: + continue +- if not move_line.account_id.type in ('payable', 'receivable'): +- #this function does not suport to be used on move lines not related to payable or receivable accounts ++ if not move_line.account_id.reconcile: ++ #this function does not suport to be used on move lines not related to a reconcilable account + continue + + if move_line.currency_id: +diff --git a/addons/account/demo/account_bank_statement.xml b/addons/account/demo/account_bank_statement.xml +index 5266782..b79d8b9 100644 +--- a/addons/account/demo/account_bank_statement.xml ++++ b/addons/account/demo/account_bank_statement.xml +@@ -7,7 +7,6 @@ + + + +- none + BNK/2014/001 + + +@@ -16,7 +15,7 @@ + + + +- 001 ++ + + + +@@ -27,7 +26,7 @@ + + + +- 002 ++ SAJ2014002 + + + +@@ -38,7 +37,7 @@ + + + +- 003 ++ + + + +@@ -48,7 +47,7 @@ + + + +- 004 ++ + + + +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 626d1f3..05caeab 100644 +--- a/addons/account/static/src/css/account_bank_statement_reconciliation.css ++++ b/addons/account/static/src/css/account_bank_statement_reconciliation.css +@@ -120,8 +120,6 @@ + cursor: pointer; } + .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line.no_match:not(.no_partner) .toggle_match { + visibility: hidden !important; } +- .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line.no_partner .partner_name, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line.no_partner .line_open_balance { +- display: none !important; } + .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line > table > tbody > tr:nth-child(1) > td table { + margin-bottom: 10px; } + .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line table.details td:first-child { +@@ -202,10 +200,6 @@ + cursor: pointer; } + .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view td:nth-child(6) { + border-left: 1px solid black; } +- .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr.initial_line > td:nth-child(5) { +- border-top: 1px solid black; } +- .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr.initial_line > td:nth-child(6) { +- border-top: 1px solid black; } + .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 3b98689..248536b 100644 +--- a/addons/account/static/src/css/account_bank_statement_reconciliation.scss ++++ b/addons/account/static/src/css/account_bank_statement_reconciliation.scss +@@ -194,12 +194,6 @@ $initialLineBackground: #f0f0f0; + } + } + +- &.no_partner { +- .partner_name, .line_open_balance { +- display: none !important; +- } +- } +- + /* gap between accounting_view and action view */ + > table > tbody > tr:nth-child(1) > td table { + margin-bottom: 10px; +@@ -341,10 +335,6 @@ $initialLineBackground: #f0f0f0; + + // accounting "T" + td:nth-child(6) { border-left: $accountingBorder; } +- tr.initial_line > td { +- &:nth-child(5) { border-top: $accountingBorder; } +- &:nth-child(6) { border-top: $accountingBorder; } +- } + } + + +diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js +index 56fdaaf..8f5786e 100644 +--- a/addons/account/static/src/js/account_widgets.js ++++ b/addons/account/static/src/js/account_widgets.js +@@ -245,7 +245,7 @@ openerp.account = function (instance) { + + keyboardShortcutsHandler: function(e) { + var self = this; +- if (e.which === 13 && (e.ctrlKey || e.metaKey)) { ++ if ((e.which === 13 || e.which === 10) && (e.ctrlKey || e.metaKey)) { + $.each(self.getChildren(), function(i, o){ + if (o.is_valid && o.persistAndDestroy()) { + self.lines_reconciled_with_ctrl_enter++; +@@ -789,6 +789,9 @@ openerp.account = function (instance) { + line.q_amount = (line.debit !== 0 ? "- "+line.q_debit : "") + (line.credit !== 0 ? line.q_credit : ""); + line.q_popover = QWeb.render("bank_statement_reconciliation_move_line_details", {line: line}); + line.q_label = line.name; ++ if (line.has_no_partner){ ++ line.q_label = line.partner_name + ': ' +line.q_label; ++ } + + // WARNING : pretty much of a ugly hack + // The value of account_move.ref is either the move's communication or it's name without the slashes +@@ -981,6 +984,7 @@ openerp.account = function (instance) { + lineOpenBalanceClickHandler: function() { + var self = this; + if (self.get("mode") === "create") { ++ self.addLineBeingEdited(); + self.set("mode", "match"); + } else { + self.set("mode", "create"); +@@ -1038,7 +1042,8 @@ openerp.account = function (instance) { + var slice_start = self.get("pager_index") * self.max_move_lines_displayed; + var slice_end = (self.get("pager_index")+1) * self.max_move_lines_displayed; + _( _.filter(self.mv_lines_deselected, function(o){ +- return o.name.indexOf(self.filter) !== -1 || o.ref.indexOf(self.filter) !== -1 }) ++ return o.q_label.indexOf(self.filter) !== -1 || (o.ref && o.ref.indexOf(self.filter) !== -1) ++ }) + .slice(slice_start, slice_end)).each(function(line){ + var $line = $(QWeb.render("bank_statement_reconciliation_move_line", {line: line, selected: false})); + self.bindPopoverTo($line.find(".line_info_button")); +@@ -1057,7 +1062,6 @@ openerp.account = function (instance) { + + updatePagerControls: function() { + var self = this; +- + if (self.get("pager_index") === 0) + self.$(".pager_control_left").addClass("disabled"); + else +@@ -1075,7 +1079,7 @@ openerp.account = function (instance) { + balanceChanged: function() { + var self = this; + var balance = self.get("balance"); +- ++ self.$(".tbody_open_balance").empty(); + // Special case hack : no identified partner + if (self.st_line.has_no_partner) { + if (Math.abs(balance).toFixed(3) === "0.000") { +@@ -1088,11 +1092,15 @@ openerp.account = function (instance) { + self.$(".button_ok").attr("disabled", "disabled"); + self.$(".button_ok").text("OK"); + self.is_valid = false; ++ var debit = (balance > 0 ? self.formatCurrency(balance, self.st_line.currency_id) : ""); ++ var credit = (balance < 0 ? self.formatCurrency(-1*balance, self.st_line.currency_id) : ""); ++ var $line = $(QWeb.render("bank_statement_reconciliation_line_open_balance", {debit: debit, credit: credit, account_code: self.map_account_id_code[self.st_line.open_balance_account_id]})); ++ $line.find('.js_open_balance')[0].innerHTML = "Choose counterpart"; ++ self.$(".tbody_open_balance").append($line); + } + return; + } + +- self.$(".tbody_open_balance").empty(); + if (Math.abs(balance).toFixed(3) === "0.000") { + self.$(".button_ok").addClass("oe_highlight"); + self.$(".button_ok").text("OK"); +@@ -1111,21 +1119,15 @@ openerp.account = function (instance) { + + self.$(".action_pane.active").removeClass("active"); + +- // Special case hack : if no_partner, either inactive or create ++ // Special case hack : if no_partner and mode == inactive + 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; ++ return; ++ } + } + + if (self.get("mode") === "inactive") { +@@ -1367,10 +1369,9 @@ openerp.account = function (instance) { + move_lines = lines; + }); + } +- + // Fetch the number of move lines corresponding to this statement line and this filter + var deferred_total_move_lines_num = self.model_bank_statement_line +- .call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids, self.filter, offset, limit, true]) ++ .call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids, self.filter, 0, undefined, true]) + .then(function(num){ + move_lines_num = num; + }); +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 4ea6761..b5a8492 100644 +--- a/addons/account/static/src/xml/account_bank_statement_reconciliation.xml ++++ b/addons/account/static/src/xml/account_bank_statement_reconciliation.xml +@@ -128,7 +128,7 @@ + + + +- : ++ + + + +@@ -185,7 +185,7 @@ + + + +- Open balance ++ Open balance + + + +diff --git a/addons/l10n_be_coda/l10n_be_coda.py b/addons/l10n_be_coda/l10n_be_coda.py +index 0dfa9bf..c4cd8ab 100644 +--- a/addons/l10n_be_coda/l10n_be_coda.py ++++ b/addons/l10n_be_coda/l10n_be_coda.py +@@ -28,46 +28,4 @@ class account_bank_statement(osv.osv): + } + + +-class account_bank_statement_line(osv.osv): +- _inherit = 'account.bank.statement.line' +- _columns = { +- 'coda_account_number': fields.char('Account Number', help="The Counter Party Account Number") +- } +- +- def create(self, cr, uid, data, context=None): +- """ +- This function creates a Bank Account Number if, for a bank statement line, +- the partner_id field and the coda_account_number field are set, +- and the account number does not exist in the database +- """ +- if 'partner_id' in data and data['partner_id'] and 'coda_account_number' in data and data['coda_account_number']: +- acc_number_ids = self.pool.get('res.partner.bank').search(cr, uid, [('acc_number', '=', data['coda_account_number'])]) +- if len(acc_number_ids) == 0: +- try: +- type_model, type_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'bank_normal') +- type_id = self.pool.get('res.partner.bank.type').browse(cr, uid, type_id, context=context) +- self.pool.get('res.partner.bank').create(cr, uid, {'acc_number': data['coda_account_number'], 'partner_id': data['partner_id'], 'state': type_id.code}, context=context) +- except ValueError: +- pass +- return super(account_bank_statement_line, self).create(cr, uid, data, context=context) +- +- def write(self, cr, uid, ids, vals, context=None): +- super(account_bank_statement_line, self).write(cr, uid, ids, vals, context) +- """ +- Same as create function above, but for write function +- """ +- if 'partner_id' in vals: +- for line in self.pool.get('account.bank.statement.line').browse(cr, uid, ids, context=context): +- if line.coda_account_number: +- acc_number_ids = self.pool.get('res.partner.bank').search(cr, uid, [('acc_number', '=', line.coda_account_number)]) +- if len(acc_number_ids) == 0: +- try: +- type_model, type_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'bank_normal') +- type_id = self.pool.get('res.partner.bank.type').browse(cr, uid, type_id, context=context) +- self.pool.get('res.partner.bank').create(cr, uid, {'acc_number': line.coda_account_number, 'partner_id': vals['partner_id'], 'state': type_id.code}, context=context) +- except ValueError: +- pass +- return True +- +- + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: +diff --git a/addons/l10n_be_coda/l10n_be_coda_demo.xml b/addons/l10n_be_coda/l10n_be_coda_demo.xml +index 63436a6..ce44539 100644 +--- a/addons/l10n_be_coda/l10n_be_coda_demo.xml ++++ b/addons/l10n_be_coda/l10n_be_coda_demo.xml +@@ -32,5 +32,27 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ draft ++ out_invoice ++ ++ ++ bba ++ +++240/2838/42818+++ ++ ++ ++ Otpez Laptop without OS ++ ++ 608.89 ++ 10 ++ ++ ++ + + +diff --git a/addons/l10n_be_coda/test_coda_file/Ontvangen_CODA.2011-01-11-18.59.15.txt b/addons/l10n_be_coda/test_coda_file/Ontvangen_CODA.2011-01-11-18.59.15.txt +index bc3af59..d0add85 100644 +--- a/addons/l10n_be_coda/test_coda_file/Ontvangen_CODA.2011-01-11-18.59.15.txt ++++ b/addons/l10n_be_coda/test_coda_file/Ontvangen_CODA.2011-01-11-18.59.15.txt +@@ -4,7 +4,7 @@ + 2200010000 GKCCBEBB 1 0 + 2300010000BE41063012345610 PARTNER 1 0 1 + 3100010001OL44483FW SCTOFBIONLO001010001001PARTNER 1 0 0 +-2100020000OL4414AC8BOVSOVSOVERS00000000030444501101110015000002010237 11011113501 0 ++2100020000OL4414AC8BOVSOVSOVERS0000000003044450110111001500001101240283842818 11011113501 0 + 2200020000 BBRUBEBB 1 0 + 2300020000BE61310126985517 PARTNER 2 0 1 + 3100020001OL4414AC8BOVSOVSOVERS001500001001PARTNER 2 1 0 +diff --git a/addons/l10n_be_coda/wizard/account_coda_import.py b/addons/l10n_be_coda/wizard/account_coda_import.py +index e50f853..cac4cce 100644 +--- a/addons/l10n_be_coda/wizard/account_coda_import.py ++++ b/addons/l10n_be_coda/wizard/account_coda_import.py +@@ -291,79 +291,38 @@ class account_coda_import(osv.osv_memory): + if 'counterpartyAddress' in line and line['counterpartyAddress'] != '': + note.append(_('Counter Party Address') + ': ' + line['counterpartyAddress']) + line['name'] = "\n".join(filter(None, [line['counterpartyName'], line['communication']])) +- partner = None + partner_id = None +- invoice = False ++ structured_com = "" ++ bank_account_id = False + if line['communication_struct'] and 'communication_type' in line and line['communication_type'] == '101': +- ids = self.pool.get('account.invoice').search(cr, uid, [('reference', '=', line['communication']), ('reference_type', '=', 'bba')]) +- +-# Gère les communications structurées +-# TODO : à faire primer sur resolution_proposition : si la communication indique une facture, on la sélectionne +- +-# if ids: +-# invoice = self.pool.get('account.invoice').browse(cr, uid, ids[0]) +-# partner = invoice.partner_id +-# partner_id = partner.id +-# if invoice.type in ['in_invoice', 'in_refund'] and line['debit'] == '1': +-# line['transaction_type'] = 'supplier' +-# elif invoice.type in ['out_invoice', 'out_refund'] and line['debit'] == '0': +-# line['transaction_type'] = 'customer' +-# line['account'] = invoice.account_id.id +-# line['reconcile'] = False +-# if invoice.type in ['in_invoice', 'out_invoice']: +-# iml_ids = self.pool.get('account.move.line').search(cr, uid, [('move_id', '=', invoice.move_id.id), ('reconcile_id', '=', False), ('account_id.reconcile', '=', True)]) +-# if iml_ids: +-# line['reconcile'] = iml_ids[0] +-# if line['reconcile']: +-# voucher_vals = { +-# 'type': line['transaction_type'] == 'supplier' and 'payment' or 'receipt', +-# 'name': line['name'], +-# 'partner_id': partner_id, +-# 'journal_id': statement['journal_id'].id, +-# 'account_id': statement['journal_id'].default_credit_account_id.id, +-# 'company_id': statement['journal_id'].company_id.id, +-# 'currency_id': statement['journal_id'].company_id.currency_id.id, +-# 'date': line['entryDate'], +-# 'amount': abs(line['amount']), +-# 'period_id': statement['period_id'], +-# 'invoice_id': invoice.id, +-# } +-# context['invoice_id'] = invoice.id +-# voucher_vals.update(self.pool.get('account.voucher').onchange_partner_id(cr, uid, [], +-# partner_id=partner_id, +-# journal_id=statement['journal_id'].id, +-# amount=abs(line['amount']), +-# currency_id=statement['journal_id'].company_id.currency_id.id, +-# ttype=line['transaction_type'] == 'supplier' and 'payment' or 'receipt', +-# date=line['transactionDate'], +-# context=context +-# )['value']) +-# line_drs = [] +-# for line_dr in voucher_vals['line_dr_ids']: +-# line_drs.append((0, 0, line_dr)) +-# voucher_vals['line_dr_ids'] = line_drs +-# line_crs = [] +-# for line_cr in voucher_vals['line_cr_ids']: +-# line_crs.append((0, 0, line_cr)) +-# voucher_vals['line_cr_ids'] = line_crs +-# line['voucher_id'] = self.pool.get('account.voucher').create(cr, uid, voucher_vals, context=context) ++ structured_com = line['communication'] + if 'counterpartyNumber' in line and line['counterpartyNumber']: + ids = self.pool.get('res.partner.bank').search(cr, uid, [('acc_number', '=', str(line['counterpartyNumber']))]) +- if ids and len(ids) > 0: +- partner = self.pool.get('res.partner.bank').browse(cr, uid, ids[0], context=context).partner_id +- partner_id = partner.id ++ if ids: ++ bank_account_id = ids[0] ++ partner_id = self.pool.get('res.partner.bank').browse(cr, uid, bank_account_id, context=context).partner_id.id ++ else: ++ #create the bank account, not linked to any partner. The reconciliation will link the partner manually ++ #chosen at the bank statement final confirmation time. ++ try: ++ type_model, type_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'bank_normal') ++ type_id = self.pool.get('res.partner.bank.type').browse(cr, uid, type_id, context=context) ++ bank_code = type_id.code ++ except ValueError: ++ bank_code = 'bank' ++ bank_account_id = self.pool.get('res.partner.bank').create(cr, uid, {'acc_number': str(line['counterpartyNumber']), 'state': bank_code}, context=context) + if 'communication' in line and line['communication'] != '': + note.append(_('Communication') + ': ' + line['communication']) + data = { + 'name': line['name'], +- 'note': "\n".join(note), ++ 'note': "\n".join(note), + 'date': line['entryDate'], + 'amount': line['amount'], + 'partner_id': partner_id, + 'statement_id': statement['id'], +- 'ref': line['ref'], ++ 'ref': structured_com, + 'sequence': line['sequence'], +- 'coda_account_number': line['counterpartyNumber'], ++ 'bank_account_id': bank_account_id, + } + self.pool.get('account.bank.statement.line').create(cr, uid, data, context=context) + if statement['coda_note'] != '': +diff --git a/openerp/addons/base/res/res_bank.py b/openerp/addons/base/res/res_bank.py +index cc29c50..e8477ec 100644 +--- a/openerp/addons/base/res/res_bank.py ++++ b/openerp/addons/base/res/res_bank.py +@@ -128,8 +128,7 @@ class res_partner_bank(osv.osv): + change_default=True, domain="[('country_id','=',country_id)]"), + 'company_id': fields.many2one('res.company', 'Company', + ondelete='cascade', help="Only if this bank account belong to your company"), +- 'partner_id': fields.many2one('res.partner', 'Account Owner', required=True, +- ondelete='cascade', select=True), ++ 'partner_id': fields.many2one('res.partner', 'Account Owner', ondelete='cascade', select=True), + 'state': fields.selection(_bank_type_get, 'Bank Account Type', required=True, + change_default=True), + 'sequence': fields.integer('Sequence'), From b8e4be018bae6ea1aeb3e59d012b0013e172e8e6 Mon Sep 17 00:00:00 2001 From: Cedric Snauwaert Date: Fri, 20 Jun 2014 17:04:42 +0200 Subject: [PATCH 07/13] [FIX]remove unused variable --- addons/account/static/src/js/account_widgets.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js index f1d549db7ba..5020086a1bc 100644 --- a/addons/account/static/src/js/account_widgets.js +++ b/addons/account/static/src/js/account_widgets.js @@ -29,7 +29,7 @@ openerp.account = function (instance) { this.time_widget_loaded = Date.now(); // Stuff used by the children bankStatementReconciliationLine - this.max_move_lines_displayed = 5; + this.max_move_lines_displayed = 1; this.animation_speed = 100; // "Blocking" animations this.aestetic_animation_speed = 300; // eye candy this.map_tax_id_amount = {}; @@ -486,7 +486,6 @@ openerp.account = function (instance) { this.presets = this.getParent().presets; this.is_valid = true; this.is_consistent = true; // Used to prevent bad server requests - this.total_move_lines_num = undefined; // Used for pagers this.filter = ""; this.set("balance", undefined); // Debit is +, credit is - @@ -838,16 +837,12 @@ openerp.account = function (instance) { pagerControlLeftHandler: function() { var self = this; - if (self.$(".pager_control_left").hasClass("disabled")) { return; /* shouldn't happen, anyway*/ } - if (self.total_move_lines_num < 0) { return; } self.set("pager_index", self.get("pager_index")-1 ); }, pagerControlRightHandler: function() { var self = this; var new_index = self.get("pager_index")+1; - if (self.$(".pager_control_right").hasClass("disabled")) { return; /* shouldn't happen, anyway*/ } - if ((new_index * self.max_move_lines_displayed) >= self.total_move_lines_num) { return; } self.set("pager_index", new_index ); }, @@ -1105,10 +1100,6 @@ openerp.account = function (instance) { mvLinesChanged: function() { var self = this; - // If pager_index is out of range, set it to display the last page - if (self.get("pager_index") !== 0 && self.total_move_lines_num <= (self.get("pager_index") * self.max_move_lines_displayed)) { - self.set("pager_index", Math.ceil(self.total_move_lines_num/self.max_move_lines_displayed)-1); - } // If there is no match to display, disable match view and pass in mode inactive if (self.get("mv_lines").length === 0 && self.filter === "") { From 301cfbb4fbec474fc35bba2297ea7133487cf525 Mon Sep 17 00:00:00 2001 From: qdp-odoo Date: Mon, 23 Jun 2014 11:47:41 +0200 Subject: [PATCH 08/13] [FIX] account: display 5 items in the bank statement reconciliation proposals --- addons/account/static/src/js/account_widgets.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js index 5020086a1bc..f78f7f5cb5b 100644 --- a/addons/account/static/src/js/account_widgets.js +++ b/addons/account/static/src/js/account_widgets.js @@ -29,7 +29,7 @@ openerp.account = function (instance) { this.time_widget_loaded = Date.now(); // Stuff used by the children bankStatementReconciliationLine - this.max_move_lines_displayed = 1; + this.max_move_lines_displayed = 5; this.animation_speed = 100; // "Blocking" animations this.aestetic_animation_speed = 300; // eye candy this.map_tax_id_amount = {}; From d2732dab913d4bd257af3c80f7715216ee2e3809 Mon Sep 17 00:00:00 2001 From: qdp-odoo Date: Mon, 23 Jun 2014 12:02:49 +0200 Subject: [PATCH 09/13] [REM] removed some files wrongly commited preivously because of that bitchin 'git add .' command --- addons/account/account_bank_statement.py.rej | 104 --- .../demo/account_bank_statement.xml.rej | 38 - .../static/src/js/account_widgets.js.rej | 14 - ...ount_bank_statement_reconciliation.xml.rej | 11 - mydiff.diff | 655 ------------------ mydiff.diff2 | 655 ------------------ 6 files changed, 1477 deletions(-) delete mode 100644 addons/account/account_bank_statement.py.rej delete mode 100644 addons/account/demo/account_bank_statement.xml.rej delete mode 100644 addons/account/static/src/js/account_widgets.js.rej delete mode 100644 addons/account/static/src/xml/account_bank_statement_reconciliation.xml.rej delete mode 100644 mydiff.diff delete mode 100644 mydiff.diff2 diff --git a/addons/account/account_bank_statement.py.rej b/addons/account/account_bank_statement.py.rej deleted file mode 100644 index 124530c24ea..00000000000 --- a/addons/account/account_bank_statement.py.rej +++ /dev/null @@ -1,104 +0,0 @@ ---- addons/account/account_bank_statement.py -+++ addons/account/account_bank_statement.py -@@ -409,6 +417,10 @@ - 'domain':[('statement_id','in',ids)], - 'context':ctx, - } -+ -+ def number_of_lines_reconciled(self, cr, uid, id, context=None): -+ bsl_obj = self.pool.get('account.bank.statement.line') -+ return bsl_obj.search_count(cr, uid, [('statement_id', '=', id), ('journal_entry_id', '!=', False)], context=context) - - def get_format_currency_js_function(self, cr, uid, id, context=None): - """ Returns a string that can be used to instanciate a javascript function. -@@ -432,9 +444,11 @@ - done_currencies.append(st_line_currency.id) - return function - -- def number_of_lines_reconciled(self, cr, uid, id, context=None): -- bsl_obj = self.pool.get('account.bank.statement.line') -- return bsl_obj.search_count(cr, uid, [('statement_id', '=', id), ('journal_entry_id', '!=', False)], context=context) -+ def link_bank_to_partner(self, cr, uid, ids, context=None): -+ for statement in self.browse(cr, uid, ids, context=context): -+ for st_line in statement.line_ids: -+ if st_line.bank_account_id and st_line.partner_id and st_line.bank_account_id.partner_id.id != st_line.partner_id.id: -+ self.pool.get('res.partner.bank').write(cr, uid, [st_line.bank_account_id.id], {'partner_id': st_line.partner_id.id}, context=context) - - class account_bank_statement_line(osv.osv): - -@@ -453,11 +467,11 @@ - ret.append(reconciliation_data) - - # Check if, now that 'candidate' move lines were selected, there are moves left for statement lines -- for reconciliation_data in ret: -- if not reconciliation_data['st_line']['has_no_partner']: -- st_line = self.browse(cr, uid, reconciliation_data['st_line']['id'], context=context) -- if self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=mv_line_ids_selected, count=True, context=context) == 0: -- reconciliation_data['st_line']['no_match'] = True -+ #for reconciliation_data in ret: -+ # if not reconciliation_data['st_line']['has_no_partner']: -+ # st_line = self.browse(cr, uid, reconciliation_data['st_line']['id'], context=context) -+ # if not self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=mv_line_ids_selected, count=True, context=context): -+ # reconciliation_data['st_line']['no_match'] = True - return ret - - def get_statement_line_for_reconciliation(self, cr, uid, id, context=None): -@@ -483,7 +497,7 @@ - 'amount': amount, - 'amount_str': amount_str, - 'currency_id': line.currency_id.id or statement_currency.id, -- 'no_match': self.get_move_lines_counterparts(cr, uid, line, count=True, context=context) == 0 and line.partner_id.id, -+ 'no_match': self.get_move_lines_counterparts(cr, uid, line, count=True, context=context) == 0, - 'partner_id': line.partner_id.id, - 'statement_id': line.statement_id.id, - 'account_code': line.journal_id.default_debit_account_id.code, -@@ -501,7 +515,7 @@ - def search_structured_com(self, cr, uid, st_line, context=None): - if not st_line.ref: - return -- domain = [('name', '=', st_line.ref)] -+ domain = [('ref', '=', st_line.ref)] - if st_line.partner_id: - domain += [('partner_id', '=', st_line.partner_id.id)] - ids = self.pool.get('account.move.line').search(cr, uid, domain, limit=1, context=context) -@@ -527,6 +540,9 @@ - exact_match_id = self.search_structured_com(cr, uid, st_line, context=context) - if exact_match_id: - return self.make_counter_part_lines(cr, uid, st_line, [exact_match_id], count=False, context=context) -+ #we don't propose anything if there is no partner detected -+ if not st_line.partner_id.id: -+ return [] - # look for exact match - exact_match_id = self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=excluded_ids, limit=1, additional_domain=[(amount_field, '=', (sign * st_line.amount))]) - if exact_match_id: -@@ -542,10 +558,10 @@ - # get_move_lines_counterparts inverts debit and credit - amount_field = 'debit' if amount_field == 'credit' else 'credit' - for line in mv_lines: -- if total + line[amount_field] <= st_line.amount: -+ if total + line[amount_field] <= abs(st_line.amount): - ret.append(line) - total += line[amount_field] -- if total >= st_line.amount: -+ if total >= abs(st_line.amount): - break - return ret - -@@ -574,14 +590,15 @@ - if st_line.partner_id.id: - domain += [('partner_id', '=', st_line.partner_id.id), - '|', ('account_id.type', '=', 'receivable'), -- ('account_id.type', '=', 'payable'), # Let the front-end warn the user if he tries to mix payable and receivable in the same reconciliation -- ] -+ ('account_id.type', '=', 'payable')] - else: - domain += [('account_id.reconcile', '=', True)] - #domain += [('account_id.reconcile', '=', True), ('account_id.type', '=', 'other')] - if excluded_ids: - domain.append(('id', 'not in', excluded_ids)) - if filter_str: -+ if not st_line.partner_id: -+ domain += [ '|', ('partner_id.name', 'ilike', filter_str)] - domain += ['|', ('move_id.name', 'ilike', filter_str), ('move_id.ref', 'ilike', filter_str)] - line_ids = mv_line_pool.search(cr, uid, domain, offset=offset, limit=limit, order="date_maturity asc, id asc", context=context) - return self.make_counter_part_lines(cr, uid, st_line, line_ids, count=count, context=context) diff --git a/addons/account/demo/account_bank_statement.xml.rej b/addons/account/demo/account_bank_statement.xml.rej deleted file mode 100644 index e4ac1b8c1c6..00000000000 --- a/addons/account/demo/account_bank_statement.xml.rej +++ /dev/null @@ -1,38 +0,0 @@ ---- addons/account/demo/account_bank_statement.xml -+++ addons/account/demo/account_bank_statement.xml -@@ -16,7 +17,7 @@ - - - -- -+ 001 - - - -@@ -27,7 +28,7 @@ - - - -- SAJ2014002 -+ 002 - - - -@@ -38,7 +39,7 @@ - - - -- -+ 003 - - - -@@ -48,7 +49,7 @@ - - - -- -+ 004 - - - diff --git a/addons/account/static/src/js/account_widgets.js.rej b/addons/account/static/src/js/account_widgets.js.rej deleted file mode 100644 index 91faf3e7434..00000000000 --- a/addons/account/static/src/js/account_widgets.js.rej +++ /dev/null @@ -1,14 +0,0 @@ ---- addons/account/static/src/js/account_widgets.js -+++ addons/account/static/src/js/account_widgets.js -@@ -1369,10 +1371,9 @@ - move_lines = lines; - }); - } -- - // Fetch the number of move lines corresponding to this statement line and this filter - var deferred_total_move_lines_num = self.model_bank_statement_line -- .call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids, self.filter, offset, limit, true]) -+ .call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids, self.filter, 0, undefined, true]) - .then(function(num){ - move_lines_num = num; - }); diff --git a/addons/account/static/src/xml/account_bank_statement_reconciliation.xml.rej b/addons/account/static/src/xml/account_bank_statement_reconciliation.xml.rej deleted file mode 100644 index 4567597894d..00000000000 --- a/addons/account/static/src/xml/account_bank_statement_reconciliation.xml.rej +++ /dev/null @@ -1,11 +0,0 @@ ---- addons/account/static/src/xml/account_bank_statement_reconciliation.xml -+++ addons/account/static/src/xml/account_bank_statement_reconciliation.xml -@@ -185,7 +185,7 @@ - - - -- Open balance -+ Open balance - - - diff --git a/mydiff.diff b/mydiff.diff deleted file mode 100644 index 45aad42742a..00000000000 --- a/mydiff.diff +++ /dev/null @@ -1,655 +0,0 @@ -diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py -index 004bcd3..1ddab4b 100644 ---- a/addons/account/account_bank_statement.py -+++ b/addons/account/account_bank_statement.py -@@ -26,6 +26,9 @@ from openerp.report import report_sxw - - class account_bank_statement(osv.osv): - def create(self, cr, uid, vals, context=None): -+ if vals.get('name', '/') == '/': -+ journal_id = vals.get('journal_id', self._default_journal_id(cr, uid, context=context)) -+ vals['name'] = self._compute_default_statement_name(cr, uid, journal_id, context=context) - if 'line_ids' in vals: - for idx, line in enumerate(vals['line_ids']): - line[2]['sequence'] = idx + 1 -@@ -65,17 +68,14 @@ class account_bank_statement(osv.osv): - return periods[0] - return False - -- def _compute_default_statement_name(self, cr, uid, context=None): -+ def _compute_default_statement_name(self, cr, uid, journal_id, context=None): - if context is None: - context = {} - obj_seq = self.pool.get('ir.sequence') -- default_journal_id = self._default_journal_id(cr, uid, context=context) -- if default_journal_id != False: -- period = self.pool.get('account.period').browse(cr, uid, self._get_period(cr, uid, context=context), context=context) -- context['fiscalyear_id'] = period.fiscalyear_id.id -- journal = self.pool.get('account.journal').browse(cr, uid, default_journal_id, None) -- return obj_seq.next_by_id(cr, uid, journal.sequence_id.id, context=context) -- return obj_seq.next_by_code(cr, uid, 'account.bank.statement', context=context) -+ period = self.pool.get('account.period').browse(cr, uid, self._get_period(cr, uid, context=context), context=context) -+ context['fiscalyear_id'] = period.fiscalyear_id.id -+ journal = self.pool.get('account.journal').browse(cr, uid, journal_id, None) -+ return obj_seq.next_by_id(cr, uid, journal.sequence_id.id, context=context) - - def _currency(self, cursor, user, ids, name, args, context=None): - res = {} -@@ -150,7 +150,7 @@ class account_bank_statement(osv.osv): - } - - _defaults = { -- 'name': _compute_default_statement_name, -+ 'name': '/', - 'date': fields.date.context_today, - 'state': 'draft', - 'journal_id': _default_journal_id, -@@ -329,21 +329,29 @@ class account_bank_statement(osv.osv): - move_ids.append(st_line.journal_entry_id.id) - self.pool.get('account.move').post(cr, uid, move_ids, context=context) - self.message_post(cr, uid, [st.id], body=_('Statement %s confirmed, journal items were created.') % (st.name,), context=context) -+ self.link_bank_to_partner(cr, uid, ids, context=context) - return self.write(cr, uid, ids, {'state':'confirm'}, context=context) - - def button_cancel(self, cr, uid, ids, context=None): -- done = [] - account_move_obj = self.pool.get('account.move') -+ reconcile_pool = self.pool.get('account.move.reconcile') -+ move_line_pool = self.pool.get('account.move.line') -+ move_ids = [] - for st in self.browse(cr, uid, ids, context=context): -- if st.state=='draft': -- continue -- move_ids = [] - for line in st.line_ids: -- move_ids += [x.id for x in line.move_ids] -+ if line.journal_entry_id: -+ move_ids.append(line.journal_entry_id.id) -+ for aml in line.journal_entry_id.line_id: -+ if aml.reconcile_id: -+ move_lines = [l.id for l in aml.reconcile_id.line_id] -+ move_lines.remove(aml.id) -+ reconcile_pool.unlink(cr, uid, [aml.reconcile_id.id], context=context) -+ if len(move_lines) >= 2: -+ move_line_pool.reconcile_partial(cr, uid, move_lines, 'auto', context=context) -+ if move_ids: - account_move_obj.button_cancel(cr, uid, move_ids, context=context) - account_move_obj.unlink(cr, uid, move_ids, context) -- done.append(st.id) -- return self.write(cr, uid, done, {'state':'draft'}, context=context) -+ return self.write(cr, uid, ids, {'state': 'draft'}, context=context) - - def _compute_balance_end_real(self, cr, uid, journal_id, context=None): - res = False -@@ -401,6 +409,10 @@ class account_bank_statement(osv.osv): - 'domain':[('statement_id','in',ids)], - 'context':ctx, - } -+ -+ def number_of_lines_reconciled(self, cr, uid, id, context=None): -+ bsl_obj = self.pool.get('account.bank.statement.line') -+ return bsl_obj.search_count(cr, uid, [('statement_id', '=', id), ('journal_entry_id', '!=', False)], context=context) - - def get_format_currency_js_function(self, cr, uid, id, context=None): - """ Returns a string that can be used to instanciate a javascript function. -@@ -424,9 +436,11 @@ class account_bank_statement(osv.osv): - done_currencies.append(st_line_currency.id) - return function - -- def number_of_lines_reconciled(self, cr, uid, id, context=None): -- bsl_obj = self.pool.get('account.bank.statement.line') -- return bsl_obj.search_count(cr, uid, [('statement_id', '=', id), ('journal_entry_id', '!=', False)], context=context) -+ def link_bank_to_partner(self, cr, uid, ids, context=None): -+ for statement in self.browse(cr, uid, ids, context=context): -+ for st_line in statement.line_ids: -+ if st_line.bank_account_id and st_line.partner_id and st_line.bank_account_id.partner_id.id != st_line.partner_id.id: -+ self.pool.get('res.partner.bank').write(cr, uid, [st_line.bank_account_id.id], {'partner_id': st_line.partner_id.id}, context=context) - - class account_bank_statement_line(osv.osv): - -@@ -445,11 +459,11 @@ class account_bank_statement_line(osv.osv): - ret.append(reconciliation_data) - - # Check if, now that 'candidate' move lines were selected, there are moves left for statement lines -- for reconciliation_data in ret: -- if not reconciliation_data['st_line']['has_no_partner']: -- st_line = self.browse(cr, uid, reconciliation_data['st_line']['id'], context=context) -- if self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=mv_line_ids_selected, count=True, context=context) == 0: -- reconciliation_data['st_line']['no_match'] = True -+ #for reconciliation_data in ret: -+ # if not reconciliation_data['st_line']['has_no_partner']: -+ # st_line = self.browse(cr, uid, reconciliation_data['st_line']['id'], context=context) -+ # if not self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=mv_line_ids_selected, count=True, context=context): -+ # reconciliation_data['st_line']['no_match'] = True - return ret - - def get_statement_line_for_reconciliation(self, cr, uid, id, context=None): -@@ -475,7 +489,7 @@ class account_bank_statement_line(osv.osv): - 'amount': amount, - 'amount_str': amount_str, - 'currency_id': line.currency_id.id or statement_currency.id, -- 'no_match': self.get_move_lines_counterparts(cr, uid, line, count=True, context=context) == 0 and line.partner_id.id, -+ 'no_match': self.get_move_lines_counterparts(cr, uid, line, count=True, context=context) == 0, - 'partner_id': line.partner_id.id, - 'statement_id': line.statement_id.id, - 'account_code': line.journal_id.default_debit_account_id.code, -@@ -493,7 +507,7 @@ class account_bank_statement_line(osv.osv): - def search_structured_com(self, cr, uid, st_line, context=None): - if not st_line.ref: - return -- domain = [('name', '=', st_line.ref)] -+ domain = [('ref', '=', st_line.ref)] - if st_line.partner_id: - domain += [('partner_id', '=', st_line.partner_id.id)] - ids = self.pool.get('account.move.line').search(cr, uid, domain, limit=1, context=context) -@@ -504,7 +518,6 @@ class account_bank_statement_line(osv.osv): - st_line = self.browse(cr, uid, id, context=context) - company_currency = st_line.journal_id.company_id.currency_id.id - statement_currency = st_line.journal_id.currency.id or company_currency -- - # either use the unsigned debit/credit fields or the signed amount_currency field - sign = 1 - if statement_currency == company_currency: -@@ -520,6 +533,9 @@ class account_bank_statement_line(osv.osv): - exact_match_id = self.search_structured_com(cr, uid, st_line, context=context) - if exact_match_id: - return self.make_counter_part_lines(cr, uid, st_line, [exact_match_id], count=False, context=context) -+ #we don't propose anything if there is no partner detected -+ if not st_line.partner_id.id: -+ return [] - # look for exact match - exact_match_id = self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=excluded_ids, limit=1, additional_domain=[(amount_field, '=', (sign * st_line.amount))]) - if exact_match_id: -@@ -535,10 +551,10 @@ class account_bank_statement_line(osv.osv): - # get_move_lines_counterparts inverts debit and credit - amount_field = 'debit' if amount_field == 'credit' else 'credit' - for line in mv_lines: -- if total + line[amount_field] <= st_line.amount: -+ if total + line[amount_field] <= abs(st_line.amount): - ret.append(line) - total += line[amount_field] -- if total >= st_line.amount: -+ if total >= abs(st_line.amount): - break - return ret - -@@ -567,14 +583,15 @@ class account_bank_statement_line(osv.osv): - if st_line.partner_id.id: - domain += [('partner_id', '=', st_line.partner_id.id), - '|', ('account_id.type', '=', 'receivable'), -- ('account_id.type', '=', 'payable'), # Let the front-end warn the user if he tries to mix payable and receivable in the same reconciliation -- ] -+ ('account_id.type', '=', 'payable')] - else: - domain += [('account_id.reconcile', '=', True)] - #domain += [('account_id.reconcile', '=', True), ('account_id.type', '=', 'other')] - if excluded_ids: - domain.append(('id', 'not in', excluded_ids)) - if filter_str: -+ if not st_line.partner_id: -+ domain += [ '|', ('partner_id.name', 'ilike', filter_str)] - domain += ['|', ('move_id.name', 'ilike', filter_str), ('move_id.ref', 'ilike', filter_str)] - line_ids = mv_line_pool.search(cr, uid, domain, offset=offset, limit=limit, order="date_maturity asc, id asc", context=context) - return self.make_counter_part_lines(cr, uid, st_line, line_ids, count=count, context=context) -diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py -index a37ca6a..5926b97 100644 ---- a/addons/account/account_move_line.py -+++ b/addons/account/account_move_line.py -@@ -127,8 +127,8 @@ class account_move_line(osv.osv): - - if move_line.reconcile_id: - continue -- if not move_line.account_id.type in ('payable', 'receivable'): -- #this function does not suport to be used on move lines not related to payable or receivable accounts -+ if not move_line.account_id.reconcile: -+ #this function does not suport to be used on move lines not related to a reconcilable account - continue - - if move_line.currency_id: -diff --git a/addons/account/demo/account_bank_statement.xml b/addons/account/demo/account_bank_statement.xml -index 5266782..b79d8b9 100644 ---- a/addons/account/demo/account_bank_statement.xml -+++ b/addons/account/demo/account_bank_statement.xml -@@ -7,7 +7,6 @@ - - - -- none - BNK/2014/001 - - -@@ -16,7 +15,7 @@ - - - -- 001 -+ - - - -@@ -27,7 +26,7 @@ - - - -- 002 -+ SAJ2014002 - - - -@@ -38,7 +37,7 @@ - - - -- 003 -+ - - - -@@ -48,7 +47,7 @@ - - - -- 004 -+ - - - -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 626d1f3..05caeab 100644 ---- a/addons/account/static/src/css/account_bank_statement_reconciliation.css -+++ b/addons/account/static/src/css/account_bank_statement_reconciliation.css -@@ -120,8 +120,6 @@ - cursor: pointer; } - .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line.no_match:not(.no_partner) .toggle_match { - visibility: hidden !important; } -- .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line.no_partner .partner_name, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line.no_partner .line_open_balance { -- display: none !important; } - .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line > table > tbody > tr:nth-child(1) > td table { - margin-bottom: 10px; } - .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line table.details td:first-child { -@@ -202,10 +200,6 @@ - cursor: pointer; } - .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view td:nth-child(6) { - border-left: 1px solid black; } -- .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr.initial_line > td:nth-child(5) { -- border-top: 1px solid black; } -- .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr.initial_line > td:nth-child(6) { -- border-top: 1px solid black; } - .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 3b98689..248536b 100644 ---- a/addons/account/static/src/css/account_bank_statement_reconciliation.scss -+++ b/addons/account/static/src/css/account_bank_statement_reconciliation.scss -@@ -194,12 +194,6 @@ $initialLineBackground: #f0f0f0; - } - } - -- &.no_partner { -- .partner_name, .line_open_balance { -- display: none !important; -- } -- } -- - /* gap between accounting_view and action view */ - > table > tbody > tr:nth-child(1) > td table { - margin-bottom: 10px; -@@ -341,10 +335,6 @@ $initialLineBackground: #f0f0f0; - - // accounting "T" - td:nth-child(6) { border-left: $accountingBorder; } -- tr.initial_line > td { -- &:nth-child(5) { border-top: $accountingBorder; } -- &:nth-child(6) { border-top: $accountingBorder; } -- } - } - - -diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js -index 56fdaaf..8f5786e 100644 ---- a/addons/account/static/src/js/account_widgets.js -+++ b/addons/account/static/src/js/account_widgets.js -@@ -245,7 +245,7 @@ openerp.account = function (instance) { - - keyboardShortcutsHandler: function(e) { - var self = this; -- if (e.which === 13 && (e.ctrlKey || e.metaKey)) { -+ if ((e.which === 13 || e.which === 10) && (e.ctrlKey || e.metaKey)) { - $.each(self.getChildren(), function(i, o){ - if (o.is_valid && o.persistAndDestroy()) { - self.lines_reconciled_with_ctrl_enter++; -@@ -789,6 +789,9 @@ openerp.account = function (instance) { - line.q_amount = (line.debit !== 0 ? "- "+line.q_debit : "") + (line.credit !== 0 ? line.q_credit : ""); - line.q_popover = QWeb.render("bank_statement_reconciliation_move_line_details", {line: line}); - line.q_label = line.name; -+ if (line.has_no_partner){ -+ line.q_label = line.partner_name + ': ' +line.q_label; -+ } - - // WARNING : pretty much of a ugly hack - // The value of account_move.ref is either the move's communication or it's name without the slashes -@@ -981,6 +984,7 @@ openerp.account = function (instance) { - lineOpenBalanceClickHandler: function() { - var self = this; - if (self.get("mode") === "create") { -+ self.addLineBeingEdited(); - self.set("mode", "match"); - } else { - self.set("mode", "create"); -@@ -1038,7 +1042,8 @@ openerp.account = function (instance) { - var slice_start = self.get("pager_index") * self.max_move_lines_displayed; - var slice_end = (self.get("pager_index")+1) * self.max_move_lines_displayed; - _( _.filter(self.mv_lines_deselected, function(o){ -- return o.name.indexOf(self.filter) !== -1 || o.ref.indexOf(self.filter) !== -1 }) -+ return o.q_label.indexOf(self.filter) !== -1 || (o.ref && o.ref.indexOf(self.filter) !== -1) -+ }) - .slice(slice_start, slice_end)).each(function(line){ - var $line = $(QWeb.render("bank_statement_reconciliation_move_line", {line: line, selected: false})); - self.bindPopoverTo($line.find(".line_info_button")); -@@ -1057,7 +1062,6 @@ openerp.account = function (instance) { - - updatePagerControls: function() { - var self = this; -- - if (self.get("pager_index") === 0) - self.$(".pager_control_left").addClass("disabled"); - else -@@ -1075,7 +1079,7 @@ openerp.account = function (instance) { - balanceChanged: function() { - var self = this; - var balance = self.get("balance"); -- -+ self.$(".tbody_open_balance").empty(); - // Special case hack : no identified partner - if (self.st_line.has_no_partner) { - if (Math.abs(balance).toFixed(3) === "0.000") { -@@ -1088,11 +1092,15 @@ openerp.account = function (instance) { - self.$(".button_ok").attr("disabled", "disabled"); - self.$(".button_ok").text("OK"); - self.is_valid = false; -+ var debit = (balance > 0 ? self.formatCurrency(balance, self.st_line.currency_id) : ""); -+ var credit = (balance < 0 ? self.formatCurrency(-1*balance, self.st_line.currency_id) : ""); -+ var $line = $(QWeb.render("bank_statement_reconciliation_line_open_balance", {debit: debit, credit: credit, account_code: self.map_account_id_code[self.st_line.open_balance_account_id]})); -+ $line.find('.js_open_balance')[0].innerHTML = "Choose counterpart"; -+ self.$(".tbody_open_balance").append($line); - } - return; - } - -- self.$(".tbody_open_balance").empty(); - if (Math.abs(balance).toFixed(3) === "0.000") { - self.$(".button_ok").addClass("oe_highlight"); - self.$(".button_ok").text("OK"); -@@ -1111,21 +1119,15 @@ openerp.account = function (instance) { - - self.$(".action_pane.active").removeClass("active"); - -- // Special case hack : if no_partner, either inactive or create -+ // Special case hack : if no_partner and mode == inactive - 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; -+ return; -+ } - } - - if (self.get("mode") === "inactive") { -@@ -1367,10 +1369,9 @@ openerp.account = function (instance) { - move_lines = lines; - }); - } -- - // Fetch the number of move lines corresponding to this statement line and this filter - var deferred_total_move_lines_num = self.model_bank_statement_line -- .call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids, self.filter, offset, limit, true]) -+ .call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids, self.filter, 0, undefined, true]) - .then(function(num){ - move_lines_num = num; - }); -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 4ea6761..b5a8492 100644 ---- a/addons/account/static/src/xml/account_bank_statement_reconciliation.xml -+++ b/addons/account/static/src/xml/account_bank_statement_reconciliation.xml -@@ -128,7 +128,7 @@ - - - -- : -+ - - - -@@ -185,7 +185,7 @@ - - - -- Open balance -+ Open balance - - - -diff --git a/addons/l10n_be_coda/l10n_be_coda.py b/addons/l10n_be_coda/l10n_be_coda.py -index 0dfa9bf..c4cd8ab 100644 ---- a/addons/l10n_be_coda/l10n_be_coda.py -+++ b/addons/l10n_be_coda/l10n_be_coda.py -@@ -28,46 +28,4 @@ class account_bank_statement(osv.osv): - } - - --class account_bank_statement_line(osv.osv): -- _inherit = 'account.bank.statement.line' -- _columns = { -- 'coda_account_number': fields.char('Account Number', help="The Counter Party Account Number") -- } -- -- def create(self, cr, uid, data, context=None): -- """ -- This function creates a Bank Account Number if, for a bank statement line, -- the partner_id field and the coda_account_number field are set, -- and the account number does not exist in the database -- """ -- if 'partner_id' in data and data['partner_id'] and 'coda_account_number' in data and data['coda_account_number']: -- acc_number_ids = self.pool.get('res.partner.bank').search(cr, uid, [('acc_number', '=', data['coda_account_number'])]) -- if len(acc_number_ids) == 0: -- try: -- type_model, type_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'bank_normal') -- type_id = self.pool.get('res.partner.bank.type').browse(cr, uid, type_id, context=context) -- self.pool.get('res.partner.bank').create(cr, uid, {'acc_number': data['coda_account_number'], 'partner_id': data['partner_id'], 'state': type_id.code}, context=context) -- except ValueError: -- pass -- return super(account_bank_statement_line, self).create(cr, uid, data, context=context) -- -- def write(self, cr, uid, ids, vals, context=None): -- super(account_bank_statement_line, self).write(cr, uid, ids, vals, context) -- """ -- Same as create function above, but for write function -- """ -- if 'partner_id' in vals: -- for line in self.pool.get('account.bank.statement.line').browse(cr, uid, ids, context=context): -- if line.coda_account_number: -- acc_number_ids = self.pool.get('res.partner.bank').search(cr, uid, [('acc_number', '=', line.coda_account_number)]) -- if len(acc_number_ids) == 0: -- try: -- type_model, type_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'bank_normal') -- type_id = self.pool.get('res.partner.bank.type').browse(cr, uid, type_id, context=context) -- self.pool.get('res.partner.bank').create(cr, uid, {'acc_number': line.coda_account_number, 'partner_id': vals['partner_id'], 'state': type_id.code}, context=context) -- except ValueError: -- pass -- return True -- -- - # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: -diff --git a/addons/l10n_be_coda/l10n_be_coda_demo.xml b/addons/l10n_be_coda/l10n_be_coda_demo.xml -index 63436a6..ce44539 100644 ---- a/addons/l10n_be_coda/l10n_be_coda_demo.xml -+++ b/addons/l10n_be_coda/l10n_be_coda_demo.xml -@@ -32,5 +32,27 @@ - - - -+ -+ -+ -+ -+ -+ -+ -+ draft -+ out_invoice -+ -+ -+ bba -+ +++240/2838/42818+++ -+ -+ -+ Otpez Laptop without OS -+ -+ 608.89 -+ 10 -+ -+ -+ - - -diff --git a/addons/l10n_be_coda/test_coda_file/Ontvangen_CODA.2011-01-11-18.59.15.txt b/addons/l10n_be_coda/test_coda_file/Ontvangen_CODA.2011-01-11-18.59.15.txt -index bc3af59..d0add85 100644 ---- a/addons/l10n_be_coda/test_coda_file/Ontvangen_CODA.2011-01-11-18.59.15.txt -+++ b/addons/l10n_be_coda/test_coda_file/Ontvangen_CODA.2011-01-11-18.59.15.txt -@@ -4,7 +4,7 @@ - 2200010000 GKCCBEBB 1 0 - 2300010000BE41063012345610 PARTNER 1 0 1 - 3100010001OL44483FW SCTOFBIONLO001010001001PARTNER 1 0 0 --2100020000OL4414AC8BOVSOVSOVERS00000000030444501101110015000002010237 11011113501 0 -+2100020000OL4414AC8BOVSOVSOVERS0000000003044450110111001500001101240283842818 11011113501 0 - 2200020000 BBRUBEBB 1 0 - 2300020000BE61310126985517 PARTNER 2 0 1 - 3100020001OL4414AC8BOVSOVSOVERS001500001001PARTNER 2 1 0 -diff --git a/addons/l10n_be_coda/wizard/account_coda_import.py b/addons/l10n_be_coda/wizard/account_coda_import.py -index e50f853..cac4cce 100644 ---- a/addons/l10n_be_coda/wizard/account_coda_import.py -+++ b/addons/l10n_be_coda/wizard/account_coda_import.py -@@ -291,79 +291,38 @@ class account_coda_import(osv.osv_memory): - if 'counterpartyAddress' in line and line['counterpartyAddress'] != '': - note.append(_('Counter Party Address') + ': ' + line['counterpartyAddress']) - line['name'] = "\n".join(filter(None, [line['counterpartyName'], line['communication']])) -- partner = None - partner_id = None -- invoice = False -+ structured_com = "" -+ bank_account_id = False - if line['communication_struct'] and 'communication_type' in line and line['communication_type'] == '101': -- ids = self.pool.get('account.invoice').search(cr, uid, [('reference', '=', line['communication']), ('reference_type', '=', 'bba')]) -- --# Gère les communications structurées --# TODO : à faire primer sur resolution_proposition : si la communication indique une facture, on la sélectionne -- --# if ids: --# invoice = self.pool.get('account.invoice').browse(cr, uid, ids[0]) --# partner = invoice.partner_id --# partner_id = partner.id --# if invoice.type in ['in_invoice', 'in_refund'] and line['debit'] == '1': --# line['transaction_type'] = 'supplier' --# elif invoice.type in ['out_invoice', 'out_refund'] and line['debit'] == '0': --# line['transaction_type'] = 'customer' --# line['account'] = invoice.account_id.id --# line['reconcile'] = False --# if invoice.type in ['in_invoice', 'out_invoice']: --# iml_ids = self.pool.get('account.move.line').search(cr, uid, [('move_id', '=', invoice.move_id.id), ('reconcile_id', '=', False), ('account_id.reconcile', '=', True)]) --# if iml_ids: --# line['reconcile'] = iml_ids[0] --# if line['reconcile']: --# voucher_vals = { --# 'type': line['transaction_type'] == 'supplier' and 'payment' or 'receipt', --# 'name': line['name'], --# 'partner_id': partner_id, --# 'journal_id': statement['journal_id'].id, --# 'account_id': statement['journal_id'].default_credit_account_id.id, --# 'company_id': statement['journal_id'].company_id.id, --# 'currency_id': statement['journal_id'].company_id.currency_id.id, --# 'date': line['entryDate'], --# 'amount': abs(line['amount']), --# 'period_id': statement['period_id'], --# 'invoice_id': invoice.id, --# } --# context['invoice_id'] = invoice.id --# voucher_vals.update(self.pool.get('account.voucher').onchange_partner_id(cr, uid, [], --# partner_id=partner_id, --# journal_id=statement['journal_id'].id, --# amount=abs(line['amount']), --# currency_id=statement['journal_id'].company_id.currency_id.id, --# ttype=line['transaction_type'] == 'supplier' and 'payment' or 'receipt', --# date=line['transactionDate'], --# context=context --# )['value']) --# line_drs = [] --# for line_dr in voucher_vals['line_dr_ids']: --# line_drs.append((0, 0, line_dr)) --# voucher_vals['line_dr_ids'] = line_drs --# line_crs = [] --# for line_cr in voucher_vals['line_cr_ids']: --# line_crs.append((0, 0, line_cr)) --# voucher_vals['line_cr_ids'] = line_crs --# line['voucher_id'] = self.pool.get('account.voucher').create(cr, uid, voucher_vals, context=context) -+ structured_com = line['communication'] - if 'counterpartyNumber' in line and line['counterpartyNumber']: - ids = self.pool.get('res.partner.bank').search(cr, uid, [('acc_number', '=', str(line['counterpartyNumber']))]) -- if ids and len(ids) > 0: -- partner = self.pool.get('res.partner.bank').browse(cr, uid, ids[0], context=context).partner_id -- partner_id = partner.id -+ if ids: -+ bank_account_id = ids[0] -+ partner_id = self.pool.get('res.partner.bank').browse(cr, uid, bank_account_id, context=context).partner_id.id -+ else: -+ #create the bank account, not linked to any partner. The reconciliation will link the partner manually -+ #chosen at the bank statement final confirmation time. -+ try: -+ type_model, type_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'bank_normal') -+ type_id = self.pool.get('res.partner.bank.type').browse(cr, uid, type_id, context=context) -+ bank_code = type_id.code -+ except ValueError: -+ bank_code = 'bank' -+ bank_account_id = self.pool.get('res.partner.bank').create(cr, uid, {'acc_number': str(line['counterpartyNumber']), 'state': bank_code}, context=context) - if 'communication' in line and line['communication'] != '': - note.append(_('Communication') + ': ' + line['communication']) - data = { - 'name': line['name'], -- 'note': "\n".join(note), -+ 'note': "\n".join(note), - 'date': line['entryDate'], - 'amount': line['amount'], - 'partner_id': partner_id, - 'statement_id': statement['id'], -- 'ref': line['ref'], -+ 'ref': structured_com, - 'sequence': line['sequence'], -- 'coda_account_number': line['counterpartyNumber'], -+ 'bank_account_id': bank_account_id, - } - self.pool.get('account.bank.statement.line').create(cr, uid, data, context=context) - if statement['coda_note'] != '': -diff --git a/openerp/addons/base/res/res_bank.py b/openerp/addons/base/res/res_bank.py -index cc29c50..e8477ec 100644 ---- a/openerp/addons/base/res/res_bank.py -+++ b/openerp/addons/base/res/res_bank.py -@@ -128,8 +128,7 @@ class res_partner_bank(osv.osv): - change_default=True, domain="[('country_id','=',country_id)]"), - 'company_id': fields.many2one('res.company', 'Company', - ondelete='cascade', help="Only if this bank account belong to your company"), -- 'partner_id': fields.many2one('res.partner', 'Account Owner', required=True, -- ondelete='cascade', select=True), -+ 'partner_id': fields.many2one('res.partner', 'Account Owner', ondelete='cascade', select=True), - 'state': fields.selection(_bank_type_get, 'Bank Account Type', required=True, - change_default=True), - 'sequence': fields.integer('Sequence'), diff --git a/mydiff.diff2 b/mydiff.diff2 deleted file mode 100644 index 45aad42742a..00000000000 --- a/mydiff.diff2 +++ /dev/null @@ -1,655 +0,0 @@ -diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py -index 004bcd3..1ddab4b 100644 ---- a/addons/account/account_bank_statement.py -+++ b/addons/account/account_bank_statement.py -@@ -26,6 +26,9 @@ from openerp.report import report_sxw - - class account_bank_statement(osv.osv): - def create(self, cr, uid, vals, context=None): -+ if vals.get('name', '/') == '/': -+ journal_id = vals.get('journal_id', self._default_journal_id(cr, uid, context=context)) -+ vals['name'] = self._compute_default_statement_name(cr, uid, journal_id, context=context) - if 'line_ids' in vals: - for idx, line in enumerate(vals['line_ids']): - line[2]['sequence'] = idx + 1 -@@ -65,17 +68,14 @@ class account_bank_statement(osv.osv): - return periods[0] - return False - -- def _compute_default_statement_name(self, cr, uid, context=None): -+ def _compute_default_statement_name(self, cr, uid, journal_id, context=None): - if context is None: - context = {} - obj_seq = self.pool.get('ir.sequence') -- default_journal_id = self._default_journal_id(cr, uid, context=context) -- if default_journal_id != False: -- period = self.pool.get('account.period').browse(cr, uid, self._get_period(cr, uid, context=context), context=context) -- context['fiscalyear_id'] = period.fiscalyear_id.id -- journal = self.pool.get('account.journal').browse(cr, uid, default_journal_id, None) -- return obj_seq.next_by_id(cr, uid, journal.sequence_id.id, context=context) -- return obj_seq.next_by_code(cr, uid, 'account.bank.statement', context=context) -+ period = self.pool.get('account.period').browse(cr, uid, self._get_period(cr, uid, context=context), context=context) -+ context['fiscalyear_id'] = period.fiscalyear_id.id -+ journal = self.pool.get('account.journal').browse(cr, uid, journal_id, None) -+ return obj_seq.next_by_id(cr, uid, journal.sequence_id.id, context=context) - - def _currency(self, cursor, user, ids, name, args, context=None): - res = {} -@@ -150,7 +150,7 @@ class account_bank_statement(osv.osv): - } - - _defaults = { -- 'name': _compute_default_statement_name, -+ 'name': '/', - 'date': fields.date.context_today, - 'state': 'draft', - 'journal_id': _default_journal_id, -@@ -329,21 +329,29 @@ class account_bank_statement(osv.osv): - move_ids.append(st_line.journal_entry_id.id) - self.pool.get('account.move').post(cr, uid, move_ids, context=context) - self.message_post(cr, uid, [st.id], body=_('Statement %s confirmed, journal items were created.') % (st.name,), context=context) -+ self.link_bank_to_partner(cr, uid, ids, context=context) - return self.write(cr, uid, ids, {'state':'confirm'}, context=context) - - def button_cancel(self, cr, uid, ids, context=None): -- done = [] - account_move_obj = self.pool.get('account.move') -+ reconcile_pool = self.pool.get('account.move.reconcile') -+ move_line_pool = self.pool.get('account.move.line') -+ move_ids = [] - for st in self.browse(cr, uid, ids, context=context): -- if st.state=='draft': -- continue -- move_ids = [] - for line in st.line_ids: -- move_ids += [x.id for x in line.move_ids] -+ if line.journal_entry_id: -+ move_ids.append(line.journal_entry_id.id) -+ for aml in line.journal_entry_id.line_id: -+ if aml.reconcile_id: -+ move_lines = [l.id for l in aml.reconcile_id.line_id] -+ move_lines.remove(aml.id) -+ reconcile_pool.unlink(cr, uid, [aml.reconcile_id.id], context=context) -+ if len(move_lines) >= 2: -+ move_line_pool.reconcile_partial(cr, uid, move_lines, 'auto', context=context) -+ if move_ids: - account_move_obj.button_cancel(cr, uid, move_ids, context=context) - account_move_obj.unlink(cr, uid, move_ids, context) -- done.append(st.id) -- return self.write(cr, uid, done, {'state':'draft'}, context=context) -+ return self.write(cr, uid, ids, {'state': 'draft'}, context=context) - - def _compute_balance_end_real(self, cr, uid, journal_id, context=None): - res = False -@@ -401,6 +409,10 @@ class account_bank_statement(osv.osv): - 'domain':[('statement_id','in',ids)], - 'context':ctx, - } -+ -+ def number_of_lines_reconciled(self, cr, uid, id, context=None): -+ bsl_obj = self.pool.get('account.bank.statement.line') -+ return bsl_obj.search_count(cr, uid, [('statement_id', '=', id), ('journal_entry_id', '!=', False)], context=context) - - def get_format_currency_js_function(self, cr, uid, id, context=None): - """ Returns a string that can be used to instanciate a javascript function. -@@ -424,9 +436,11 @@ class account_bank_statement(osv.osv): - done_currencies.append(st_line_currency.id) - return function - -- def number_of_lines_reconciled(self, cr, uid, id, context=None): -- bsl_obj = self.pool.get('account.bank.statement.line') -- return bsl_obj.search_count(cr, uid, [('statement_id', '=', id), ('journal_entry_id', '!=', False)], context=context) -+ def link_bank_to_partner(self, cr, uid, ids, context=None): -+ for statement in self.browse(cr, uid, ids, context=context): -+ for st_line in statement.line_ids: -+ if st_line.bank_account_id and st_line.partner_id and st_line.bank_account_id.partner_id.id != st_line.partner_id.id: -+ self.pool.get('res.partner.bank').write(cr, uid, [st_line.bank_account_id.id], {'partner_id': st_line.partner_id.id}, context=context) - - class account_bank_statement_line(osv.osv): - -@@ -445,11 +459,11 @@ class account_bank_statement_line(osv.osv): - ret.append(reconciliation_data) - - # Check if, now that 'candidate' move lines were selected, there are moves left for statement lines -- for reconciliation_data in ret: -- if not reconciliation_data['st_line']['has_no_partner']: -- st_line = self.browse(cr, uid, reconciliation_data['st_line']['id'], context=context) -- if self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=mv_line_ids_selected, count=True, context=context) == 0: -- reconciliation_data['st_line']['no_match'] = True -+ #for reconciliation_data in ret: -+ # if not reconciliation_data['st_line']['has_no_partner']: -+ # st_line = self.browse(cr, uid, reconciliation_data['st_line']['id'], context=context) -+ # if not self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=mv_line_ids_selected, count=True, context=context): -+ # reconciliation_data['st_line']['no_match'] = True - return ret - - def get_statement_line_for_reconciliation(self, cr, uid, id, context=None): -@@ -475,7 +489,7 @@ class account_bank_statement_line(osv.osv): - 'amount': amount, - 'amount_str': amount_str, - 'currency_id': line.currency_id.id or statement_currency.id, -- 'no_match': self.get_move_lines_counterparts(cr, uid, line, count=True, context=context) == 0 and line.partner_id.id, -+ 'no_match': self.get_move_lines_counterparts(cr, uid, line, count=True, context=context) == 0, - 'partner_id': line.partner_id.id, - 'statement_id': line.statement_id.id, - 'account_code': line.journal_id.default_debit_account_id.code, -@@ -493,7 +507,7 @@ class account_bank_statement_line(osv.osv): - def search_structured_com(self, cr, uid, st_line, context=None): - if not st_line.ref: - return -- domain = [('name', '=', st_line.ref)] -+ domain = [('ref', '=', st_line.ref)] - if st_line.partner_id: - domain += [('partner_id', '=', st_line.partner_id.id)] - ids = self.pool.get('account.move.line').search(cr, uid, domain, limit=1, context=context) -@@ -504,7 +518,6 @@ class account_bank_statement_line(osv.osv): - st_line = self.browse(cr, uid, id, context=context) - company_currency = st_line.journal_id.company_id.currency_id.id - statement_currency = st_line.journal_id.currency.id or company_currency -- - # either use the unsigned debit/credit fields or the signed amount_currency field - sign = 1 - if statement_currency == company_currency: -@@ -520,6 +533,9 @@ class account_bank_statement_line(osv.osv): - exact_match_id = self.search_structured_com(cr, uid, st_line, context=context) - if exact_match_id: - return self.make_counter_part_lines(cr, uid, st_line, [exact_match_id], count=False, context=context) -+ #we don't propose anything if there is no partner detected -+ if not st_line.partner_id.id: -+ return [] - # look for exact match - exact_match_id = self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=excluded_ids, limit=1, additional_domain=[(amount_field, '=', (sign * st_line.amount))]) - if exact_match_id: -@@ -535,10 +551,10 @@ class account_bank_statement_line(osv.osv): - # get_move_lines_counterparts inverts debit and credit - amount_field = 'debit' if amount_field == 'credit' else 'credit' - for line in mv_lines: -- if total + line[amount_field] <= st_line.amount: -+ if total + line[amount_field] <= abs(st_line.amount): - ret.append(line) - total += line[amount_field] -- if total >= st_line.amount: -+ if total >= abs(st_line.amount): - break - return ret - -@@ -567,14 +583,15 @@ class account_bank_statement_line(osv.osv): - if st_line.partner_id.id: - domain += [('partner_id', '=', st_line.partner_id.id), - '|', ('account_id.type', '=', 'receivable'), -- ('account_id.type', '=', 'payable'), # Let the front-end warn the user if he tries to mix payable and receivable in the same reconciliation -- ] -+ ('account_id.type', '=', 'payable')] - else: - domain += [('account_id.reconcile', '=', True)] - #domain += [('account_id.reconcile', '=', True), ('account_id.type', '=', 'other')] - if excluded_ids: - domain.append(('id', 'not in', excluded_ids)) - if filter_str: -+ if not st_line.partner_id: -+ domain += [ '|', ('partner_id.name', 'ilike', filter_str)] - domain += ['|', ('move_id.name', 'ilike', filter_str), ('move_id.ref', 'ilike', filter_str)] - line_ids = mv_line_pool.search(cr, uid, domain, offset=offset, limit=limit, order="date_maturity asc, id asc", context=context) - return self.make_counter_part_lines(cr, uid, st_line, line_ids, count=count, context=context) -diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py -index a37ca6a..5926b97 100644 ---- a/addons/account/account_move_line.py -+++ b/addons/account/account_move_line.py -@@ -127,8 +127,8 @@ class account_move_line(osv.osv): - - if move_line.reconcile_id: - continue -- if not move_line.account_id.type in ('payable', 'receivable'): -- #this function does not suport to be used on move lines not related to payable or receivable accounts -+ if not move_line.account_id.reconcile: -+ #this function does not suport to be used on move lines not related to a reconcilable account - continue - - if move_line.currency_id: -diff --git a/addons/account/demo/account_bank_statement.xml b/addons/account/demo/account_bank_statement.xml -index 5266782..b79d8b9 100644 ---- a/addons/account/demo/account_bank_statement.xml -+++ b/addons/account/demo/account_bank_statement.xml -@@ -7,7 +7,6 @@ - - - -- none - BNK/2014/001 - - -@@ -16,7 +15,7 @@ - - - -- 001 -+ - - - -@@ -27,7 +26,7 @@ - - - -- 002 -+ SAJ2014002 - - - -@@ -38,7 +37,7 @@ - - - -- 003 -+ - - - -@@ -48,7 +47,7 @@ - - - -- 004 -+ - - - -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 626d1f3..05caeab 100644 ---- a/addons/account/static/src/css/account_bank_statement_reconciliation.css -+++ b/addons/account/static/src/css/account_bank_statement_reconciliation.css -@@ -120,8 +120,6 @@ - cursor: pointer; } - .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line.no_match:not(.no_partner) .toggle_match { - visibility: hidden !important; } -- .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line.no_partner .partner_name, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line.no_partner .line_open_balance { -- display: none !important; } - .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line > table > tbody > tr:nth-child(1) > td table { - margin-bottom: 10px; } - .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line table.details td:first-child { -@@ -202,10 +200,6 @@ - cursor: pointer; } - .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view td:nth-child(6) { - border-left: 1px solid black; } -- .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr.initial_line > td:nth-child(5) { -- border-top: 1px solid black; } -- .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr.initial_line > td:nth-child(6) { -- border-top: 1px solid black; } - .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 3b98689..248536b 100644 ---- a/addons/account/static/src/css/account_bank_statement_reconciliation.scss -+++ b/addons/account/static/src/css/account_bank_statement_reconciliation.scss -@@ -194,12 +194,6 @@ $initialLineBackground: #f0f0f0; - } - } - -- &.no_partner { -- .partner_name, .line_open_balance { -- display: none !important; -- } -- } -- - /* gap between accounting_view and action view */ - > table > tbody > tr:nth-child(1) > td table { - margin-bottom: 10px; -@@ -341,10 +335,6 @@ $initialLineBackground: #f0f0f0; - - // accounting "T" - td:nth-child(6) { border-left: $accountingBorder; } -- tr.initial_line > td { -- &:nth-child(5) { border-top: $accountingBorder; } -- &:nth-child(6) { border-top: $accountingBorder; } -- } - } - - -diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js -index 56fdaaf..8f5786e 100644 ---- a/addons/account/static/src/js/account_widgets.js -+++ b/addons/account/static/src/js/account_widgets.js -@@ -245,7 +245,7 @@ openerp.account = function (instance) { - - keyboardShortcutsHandler: function(e) { - var self = this; -- if (e.which === 13 && (e.ctrlKey || e.metaKey)) { -+ if ((e.which === 13 || e.which === 10) && (e.ctrlKey || e.metaKey)) { - $.each(self.getChildren(), function(i, o){ - if (o.is_valid && o.persistAndDestroy()) { - self.lines_reconciled_with_ctrl_enter++; -@@ -789,6 +789,9 @@ openerp.account = function (instance) { - line.q_amount = (line.debit !== 0 ? "- "+line.q_debit : "") + (line.credit !== 0 ? line.q_credit : ""); - line.q_popover = QWeb.render("bank_statement_reconciliation_move_line_details", {line: line}); - line.q_label = line.name; -+ if (line.has_no_partner){ -+ line.q_label = line.partner_name + ': ' +line.q_label; -+ } - - // WARNING : pretty much of a ugly hack - // The value of account_move.ref is either the move's communication or it's name without the slashes -@@ -981,6 +984,7 @@ openerp.account = function (instance) { - lineOpenBalanceClickHandler: function() { - var self = this; - if (self.get("mode") === "create") { -+ self.addLineBeingEdited(); - self.set("mode", "match"); - } else { - self.set("mode", "create"); -@@ -1038,7 +1042,8 @@ openerp.account = function (instance) { - var slice_start = self.get("pager_index") * self.max_move_lines_displayed; - var slice_end = (self.get("pager_index")+1) * self.max_move_lines_displayed; - _( _.filter(self.mv_lines_deselected, function(o){ -- return o.name.indexOf(self.filter) !== -1 || o.ref.indexOf(self.filter) !== -1 }) -+ return o.q_label.indexOf(self.filter) !== -1 || (o.ref && o.ref.indexOf(self.filter) !== -1) -+ }) - .slice(slice_start, slice_end)).each(function(line){ - var $line = $(QWeb.render("bank_statement_reconciliation_move_line", {line: line, selected: false})); - self.bindPopoverTo($line.find(".line_info_button")); -@@ -1057,7 +1062,6 @@ openerp.account = function (instance) { - - updatePagerControls: function() { - var self = this; -- - if (self.get("pager_index") === 0) - self.$(".pager_control_left").addClass("disabled"); - else -@@ -1075,7 +1079,7 @@ openerp.account = function (instance) { - balanceChanged: function() { - var self = this; - var balance = self.get("balance"); -- -+ self.$(".tbody_open_balance").empty(); - // Special case hack : no identified partner - if (self.st_line.has_no_partner) { - if (Math.abs(balance).toFixed(3) === "0.000") { -@@ -1088,11 +1092,15 @@ openerp.account = function (instance) { - self.$(".button_ok").attr("disabled", "disabled"); - self.$(".button_ok").text("OK"); - self.is_valid = false; -+ var debit = (balance > 0 ? self.formatCurrency(balance, self.st_line.currency_id) : ""); -+ var credit = (balance < 0 ? self.formatCurrency(-1*balance, self.st_line.currency_id) : ""); -+ var $line = $(QWeb.render("bank_statement_reconciliation_line_open_balance", {debit: debit, credit: credit, account_code: self.map_account_id_code[self.st_line.open_balance_account_id]})); -+ $line.find('.js_open_balance')[0].innerHTML = "Choose counterpart"; -+ self.$(".tbody_open_balance").append($line); - } - return; - } - -- self.$(".tbody_open_balance").empty(); - if (Math.abs(balance).toFixed(3) === "0.000") { - self.$(".button_ok").addClass("oe_highlight"); - self.$(".button_ok").text("OK"); -@@ -1111,21 +1119,15 @@ openerp.account = function (instance) { - - self.$(".action_pane.active").removeClass("active"); - -- // Special case hack : if no_partner, either inactive or create -+ // Special case hack : if no_partner and mode == inactive - 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; -+ return; -+ } - } - - if (self.get("mode") === "inactive") { -@@ -1367,10 +1369,9 @@ openerp.account = function (instance) { - move_lines = lines; - }); - } -- - // Fetch the number of move lines corresponding to this statement line and this filter - var deferred_total_move_lines_num = self.model_bank_statement_line -- .call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids, self.filter, offset, limit, true]) -+ .call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids, self.filter, 0, undefined, true]) - .then(function(num){ - move_lines_num = num; - }); -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 4ea6761..b5a8492 100644 ---- a/addons/account/static/src/xml/account_bank_statement_reconciliation.xml -+++ b/addons/account/static/src/xml/account_bank_statement_reconciliation.xml -@@ -128,7 +128,7 @@ - - - -- : -+ - - - -@@ -185,7 +185,7 @@ - - - -- Open balance -+ Open balance - - - -diff --git a/addons/l10n_be_coda/l10n_be_coda.py b/addons/l10n_be_coda/l10n_be_coda.py -index 0dfa9bf..c4cd8ab 100644 ---- a/addons/l10n_be_coda/l10n_be_coda.py -+++ b/addons/l10n_be_coda/l10n_be_coda.py -@@ -28,46 +28,4 @@ class account_bank_statement(osv.osv): - } - - --class account_bank_statement_line(osv.osv): -- _inherit = 'account.bank.statement.line' -- _columns = { -- 'coda_account_number': fields.char('Account Number', help="The Counter Party Account Number") -- } -- -- def create(self, cr, uid, data, context=None): -- """ -- This function creates a Bank Account Number if, for a bank statement line, -- the partner_id field and the coda_account_number field are set, -- and the account number does not exist in the database -- """ -- if 'partner_id' in data and data['partner_id'] and 'coda_account_number' in data and data['coda_account_number']: -- acc_number_ids = self.pool.get('res.partner.bank').search(cr, uid, [('acc_number', '=', data['coda_account_number'])]) -- if len(acc_number_ids) == 0: -- try: -- type_model, type_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'bank_normal') -- type_id = self.pool.get('res.partner.bank.type').browse(cr, uid, type_id, context=context) -- self.pool.get('res.partner.bank').create(cr, uid, {'acc_number': data['coda_account_number'], 'partner_id': data['partner_id'], 'state': type_id.code}, context=context) -- except ValueError: -- pass -- return super(account_bank_statement_line, self).create(cr, uid, data, context=context) -- -- def write(self, cr, uid, ids, vals, context=None): -- super(account_bank_statement_line, self).write(cr, uid, ids, vals, context) -- """ -- Same as create function above, but for write function -- """ -- if 'partner_id' in vals: -- for line in self.pool.get('account.bank.statement.line').browse(cr, uid, ids, context=context): -- if line.coda_account_number: -- acc_number_ids = self.pool.get('res.partner.bank').search(cr, uid, [('acc_number', '=', line.coda_account_number)]) -- if len(acc_number_ids) == 0: -- try: -- type_model, type_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'bank_normal') -- type_id = self.pool.get('res.partner.bank.type').browse(cr, uid, type_id, context=context) -- self.pool.get('res.partner.bank').create(cr, uid, {'acc_number': line.coda_account_number, 'partner_id': vals['partner_id'], 'state': type_id.code}, context=context) -- except ValueError: -- pass -- return True -- -- - # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: -diff --git a/addons/l10n_be_coda/l10n_be_coda_demo.xml b/addons/l10n_be_coda/l10n_be_coda_demo.xml -index 63436a6..ce44539 100644 ---- a/addons/l10n_be_coda/l10n_be_coda_demo.xml -+++ b/addons/l10n_be_coda/l10n_be_coda_demo.xml -@@ -32,5 +32,27 @@ - - - -+ -+ -+ -+ -+ -+ -+ -+ draft -+ out_invoice -+ -+ -+ bba -+ +++240/2838/42818+++ -+ -+ -+ Otpez Laptop without OS -+ -+ 608.89 -+ 10 -+ -+ -+ - - -diff --git a/addons/l10n_be_coda/test_coda_file/Ontvangen_CODA.2011-01-11-18.59.15.txt b/addons/l10n_be_coda/test_coda_file/Ontvangen_CODA.2011-01-11-18.59.15.txt -index bc3af59..d0add85 100644 ---- a/addons/l10n_be_coda/test_coda_file/Ontvangen_CODA.2011-01-11-18.59.15.txt -+++ b/addons/l10n_be_coda/test_coda_file/Ontvangen_CODA.2011-01-11-18.59.15.txt -@@ -4,7 +4,7 @@ - 2200010000 GKCCBEBB 1 0 - 2300010000BE41063012345610 PARTNER 1 0 1 - 3100010001OL44483FW SCTOFBIONLO001010001001PARTNER 1 0 0 --2100020000OL4414AC8BOVSOVSOVERS00000000030444501101110015000002010237 11011113501 0 -+2100020000OL4414AC8BOVSOVSOVERS0000000003044450110111001500001101240283842818 11011113501 0 - 2200020000 BBRUBEBB 1 0 - 2300020000BE61310126985517 PARTNER 2 0 1 - 3100020001OL4414AC8BOVSOVSOVERS001500001001PARTNER 2 1 0 -diff --git a/addons/l10n_be_coda/wizard/account_coda_import.py b/addons/l10n_be_coda/wizard/account_coda_import.py -index e50f853..cac4cce 100644 ---- a/addons/l10n_be_coda/wizard/account_coda_import.py -+++ b/addons/l10n_be_coda/wizard/account_coda_import.py -@@ -291,79 +291,38 @@ class account_coda_import(osv.osv_memory): - if 'counterpartyAddress' in line and line['counterpartyAddress'] != '': - note.append(_('Counter Party Address') + ': ' + line['counterpartyAddress']) - line['name'] = "\n".join(filter(None, [line['counterpartyName'], line['communication']])) -- partner = None - partner_id = None -- invoice = False -+ structured_com = "" -+ bank_account_id = False - if line['communication_struct'] and 'communication_type' in line and line['communication_type'] == '101': -- ids = self.pool.get('account.invoice').search(cr, uid, [('reference', '=', line['communication']), ('reference_type', '=', 'bba')]) -- --# Gère les communications structurées --# TODO : à faire primer sur resolution_proposition : si la communication indique une facture, on la sélectionne -- --# if ids: --# invoice = self.pool.get('account.invoice').browse(cr, uid, ids[0]) --# partner = invoice.partner_id --# partner_id = partner.id --# if invoice.type in ['in_invoice', 'in_refund'] and line['debit'] == '1': --# line['transaction_type'] = 'supplier' --# elif invoice.type in ['out_invoice', 'out_refund'] and line['debit'] == '0': --# line['transaction_type'] = 'customer' --# line['account'] = invoice.account_id.id --# line['reconcile'] = False --# if invoice.type in ['in_invoice', 'out_invoice']: --# iml_ids = self.pool.get('account.move.line').search(cr, uid, [('move_id', '=', invoice.move_id.id), ('reconcile_id', '=', False), ('account_id.reconcile', '=', True)]) --# if iml_ids: --# line['reconcile'] = iml_ids[0] --# if line['reconcile']: --# voucher_vals = { --# 'type': line['transaction_type'] == 'supplier' and 'payment' or 'receipt', --# 'name': line['name'], --# 'partner_id': partner_id, --# 'journal_id': statement['journal_id'].id, --# 'account_id': statement['journal_id'].default_credit_account_id.id, --# 'company_id': statement['journal_id'].company_id.id, --# 'currency_id': statement['journal_id'].company_id.currency_id.id, --# 'date': line['entryDate'], --# 'amount': abs(line['amount']), --# 'period_id': statement['period_id'], --# 'invoice_id': invoice.id, --# } --# context['invoice_id'] = invoice.id --# voucher_vals.update(self.pool.get('account.voucher').onchange_partner_id(cr, uid, [], --# partner_id=partner_id, --# journal_id=statement['journal_id'].id, --# amount=abs(line['amount']), --# currency_id=statement['journal_id'].company_id.currency_id.id, --# ttype=line['transaction_type'] == 'supplier' and 'payment' or 'receipt', --# date=line['transactionDate'], --# context=context --# )['value']) --# line_drs = [] --# for line_dr in voucher_vals['line_dr_ids']: --# line_drs.append((0, 0, line_dr)) --# voucher_vals['line_dr_ids'] = line_drs --# line_crs = [] --# for line_cr in voucher_vals['line_cr_ids']: --# line_crs.append((0, 0, line_cr)) --# voucher_vals['line_cr_ids'] = line_crs --# line['voucher_id'] = self.pool.get('account.voucher').create(cr, uid, voucher_vals, context=context) -+ structured_com = line['communication'] - if 'counterpartyNumber' in line and line['counterpartyNumber']: - ids = self.pool.get('res.partner.bank').search(cr, uid, [('acc_number', '=', str(line['counterpartyNumber']))]) -- if ids and len(ids) > 0: -- partner = self.pool.get('res.partner.bank').browse(cr, uid, ids[0], context=context).partner_id -- partner_id = partner.id -+ if ids: -+ bank_account_id = ids[0] -+ partner_id = self.pool.get('res.partner.bank').browse(cr, uid, bank_account_id, context=context).partner_id.id -+ else: -+ #create the bank account, not linked to any partner. The reconciliation will link the partner manually -+ #chosen at the bank statement final confirmation time. -+ try: -+ type_model, type_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'bank_normal') -+ type_id = self.pool.get('res.partner.bank.type').browse(cr, uid, type_id, context=context) -+ bank_code = type_id.code -+ except ValueError: -+ bank_code = 'bank' -+ bank_account_id = self.pool.get('res.partner.bank').create(cr, uid, {'acc_number': str(line['counterpartyNumber']), 'state': bank_code}, context=context) - if 'communication' in line and line['communication'] != '': - note.append(_('Communication') + ': ' + line['communication']) - data = { - 'name': line['name'], -- 'note': "\n".join(note), -+ 'note': "\n".join(note), - 'date': line['entryDate'], - 'amount': line['amount'], - 'partner_id': partner_id, - 'statement_id': statement['id'], -- 'ref': line['ref'], -+ 'ref': structured_com, - 'sequence': line['sequence'], -- 'coda_account_number': line['counterpartyNumber'], -+ 'bank_account_id': bank_account_id, - } - self.pool.get('account.bank.statement.line').create(cr, uid, data, context=context) - if statement['coda_note'] != '': -diff --git a/openerp/addons/base/res/res_bank.py b/openerp/addons/base/res/res_bank.py -index cc29c50..e8477ec 100644 ---- a/openerp/addons/base/res/res_bank.py -+++ b/openerp/addons/base/res/res_bank.py -@@ -128,8 +128,7 @@ class res_partner_bank(osv.osv): - change_default=True, domain="[('country_id','=',country_id)]"), - 'company_id': fields.many2one('res.company', 'Company', - ondelete='cascade', help="Only if this bank account belong to your company"), -- 'partner_id': fields.many2one('res.partner', 'Account Owner', required=True, -- ondelete='cascade', select=True), -+ 'partner_id': fields.many2one('res.partner', 'Account Owner', ondelete='cascade', select=True), - 'state': fields.selection(_bank_type_get, 'Bank Account Type', required=True, - change_default=True), - 'sequence': fields.integer('Sequence'), From 31f1fad0f6f0a9176e046e359af59ce3e3ceaf56 Mon Sep 17 00:00:00 2001 From: Cedric Snauwaert Date: Mon, 23 Jun 2014 17:20:42 +0200 Subject: [PATCH 10/13] [FIX]account reconciliation widget: add account_code to filter --- addons/account/static/src/js/account_widgets.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js index f78f7f5cb5b..c60bf4122d6 100644 --- a/addons/account/static/src/js/account_widgets.js +++ b/addons/account/static/src/js/account_widgets.js @@ -1283,7 +1283,8 @@ openerp.account = function (instance) { var self = this; var lines_to_show = []; _.each(self.propositions_lines, function(line){ - if (self.getParent().excluded_move_lines_ids.indexOf(line.id) === -1 && line.q_label.toLowerCase().indexOf(self.filter.toLowerCase()) > -1) { + var filter = (line.q_label.toLowerCase().indexOf(self.filter.toLowerCase()) > -1 || line.account_code.toLowerCase().indexOf(self.filter.toLowerCase()) > -1); + if (self.getParent().excluded_move_lines_ids.indexOf(line.id) === -1 && filter) { lines_to_show.push(line); } }); From ea00789e3582c84a7f3503c14e9a3eee1ebca7ee Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (aka lmi)" Date: Tue, 24 Jun 2014 14:22:41 +0200 Subject: [PATCH 11/13] [IMP] take into account the context parameter 'defer_parent_store_computation' also on write operations --- openerp/osv/orm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 4289d6660f8..7fe2cf31a40 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -3860,7 +3860,7 @@ class BaseModel(object): parents_changed = [] parent_order = self._parent_order or self._order - if self._parent_store and (self._parent_name in vals): + if self._parent_store and (self._parent_name in vals) and not context.get('defer_parent_store_computation'): # The parent_left/right computation may take up to # 5 seconds. No need to recompute the values if the # parent is the same. From 56ba15a3c81a328351a70a685fc191ad6dfdea91 Mon Sep 17 00:00:00 2001 From: Atul Patel Date: Tue, 24 Jun 2014 19:37:00 +0530 Subject: [PATCH 12/13] [IMP]: Remove user id domain changes from ir rule --- addons/crm_claim/crm_claim.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/crm_claim/crm_claim.py b/addons/crm_claim/crm_claim.py index e38bf973cdf..bfd130d6c60 100644 --- a/addons/crm_claim/crm_claim.py +++ b/addons/crm_claim/crm_claim.py @@ -87,7 +87,7 @@ class crm_claim(osv.osv): ('object_id.model', '=', 'crm.claim')]"), 'priority': fields.selection([('0','Low'), ('1','Normal'), ('2','High')], 'Priority'), 'type_action': fields.selection([('correction','Corrective Action'),('prevention','Preventive Action')], 'Action Type'), - 'user_id': fields.many2one('res.users', 'Responsible'), + 'user_id': fields.many2one('res.users', 'Responsible', track_visibility='always'), 'user_fault': fields.char('Trouble Responsible', size=64), 'section_id': fields.many2one('crm.case.section', 'Sales Team', \ select=True, help="Responsible sales team."\ From 5112421a937904180f2755889fce03740ce3b93b Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 24 Jun 2014 20:55:26 +0200 Subject: [PATCH 13/13] [FIX] website: correct slug parsing --- addons/website/models/ir_http.py | 6 ++--- addons/website/models/website.py | 14 ++++++++++- addons/website/tests/test_converter.py | 23 ++++++++++++++++++- .../controllers/main.py | 8 +++---- addons/website_customer/controllers/main.py | 8 +++---- addons/website_membership/controllers/main.py | 8 +++---- 6 files changed, 47 insertions(+), 20 deletions(-) diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py index 6ffb267c214..56194dd34fe 100644 --- a/addons/website/models/ir_http.py +++ b/addons/website/models/ir_http.py @@ -10,7 +10,7 @@ import werkzeug.routing import openerp from openerp.addons.base import ir from openerp.addons.base.ir import ir_qweb -from openerp.addons.website.models.website import slug, url_for +from openerp.addons.website.models.website import slug, url_for, _UNSLUG_RE from openerp.http import request from openerp.osv import orm @@ -202,7 +202,7 @@ class ModelConverter(ir.ir_http.ModelConverter): def __init__(self, url_map, model=False, domain='[]'): super(ModelConverter, self).__init__(url_map, model) self.domain = domain - self.regex = r'(?:[A-Za-z0-9-_]+?-)?(\d+)(?=$|/)' + self.regex = _UNSLUG_RE.pattern def to_url(self, value): return slug(value) @@ -211,7 +211,7 @@ class ModelConverter(ir.ir_http.ModelConverter): m = re.match(self.regex, value) _uid = RequestUID(value=value, match=m, converter=self) return request.registry[self.model].browse( - request.cr, _uid, int(m.group(1)), context=request.context) + request.cr, _uid, int(m.group(2)), context=request.context) def generate(self, cr, uid, query=None, args=None, context=None): obj = request.registry[self.model] diff --git a/addons/website/models/website.py b/addons/website/models/website.py index 7c9c0295e73..ec1b1eda69d 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -118,11 +118,23 @@ def slug(value): else: # assume name_search result tuple id, name = value - slugname = slugify(name or '') + slugname = slugify(name or '').strip().strip('-') if not slugname: return str(id) return "%s-%d" % (slugname, id) + +_UNSLUG_RE = re.compile(r'(?:(\w{1,2}|\w[a-z0-9-_]+?\w)-)?(-?\d+)(?=$|/)', re.I) + +def unslug(s): + """Extract slug and id from a string. + Always return un 2-tuple (str|None, int|None) + """ + m = _UNSLUG_RE.match(s) + if not m: + return None, None + return m.group(1), int(m.group(2)) + def urlplus(url, params): return werkzeug.Href(url)(params or None) diff --git a/addons/website/tests/test_converter.py b/addons/website/tests/test_converter.py index 288715b9b26..bcc6ef1b9cb 100644 --- a/addons/website/tests/test_converter.py +++ b/addons/website/tests/test_converter.py @@ -9,11 +9,32 @@ from lxml.builder import E from openerp.tests import common from openerp.addons.base.ir import ir_qweb from openerp.addons.website.models.ir_qweb import html_to_text -from openerp.addons.website.models.website import slugify +from openerp.addons.website.models.website import slugify, unslug impl = getDOMImplementation() document = impl.createDocument(None, None, None) +class TestUnslug(unittest2.TestCase): + def test_unslug(self): + tests = { + '': (None, None), + 'foo': (None, None), + 'foo-': (None, None), + '-': (None, None), + 'foo-1': ('foo', 1), + 'foo-bar-1': ('foo-bar', 1), + 'foo--1': ('foo', -1), + '1': (None, 1), + '1-1': ('1', 1), + '--1': (None, None), + 'foo---1': (None, None), + 'foo1': (None, None), + } + + for slug, expected in tests.iteritems(): + self.assertEqual(unslug(slug), expected) + + class TestHTMLToText(unittest2.TestCase): def test_rawstring(self): self.assertEqual( diff --git a/addons/website_crm_partner_assign/controllers/main.py b/addons/website_crm_partner_assign/controllers/main.py index 9ae7a43289f..ca08478d8d1 100644 --- a/addons/website_crm_partner_assign/controllers/main.py +++ b/addons/website_crm_partner_assign/controllers/main.py @@ -1,10 +1,9 @@ # -*- coding: utf-8 -*- -import re import werkzeug from openerp import SUPERUSER_ID from openerp.addons.web import http from openerp.addons.web.http import request -from openerp.addons.website.models.website import slug +from openerp.addons.website.models.website import slug, unslug from openerp.tools.translate import _ @@ -131,7 +130,7 @@ class WebsiteCrmPartnerAssign(http.Controller): # Do not use semantic controller due to SUPERUSER_ID @http.route(['/partners/'], type='http', auth="public", website=True) def partners_detail(self, partner_id, partner_name='', **post): - mo = re.search('([-0-9]+)$', str(partner_id)) + _, partner_id = unslug(partner_id) current_grade, current_country = None, None grade_id = post.get('grade_id') country_id = post.get('country_id') @@ -143,8 +142,7 @@ class WebsiteCrmPartnerAssign(http.Controller): country_ids = request.registry['res.country'].exists(request.cr, request.uid, int(country_id), context=request.context) if country_ids: current_country = request.registry['res.country'].browse(request.cr, request.uid, country_ids[0], context=request.context) - if mo: - partner_id = int(mo.group(1)) + if partner_id: partner = request.registry['res.partner'].browse(request.cr, SUPERUSER_ID, partner_id, context=request.context) if partner.exists() and partner.website_published: values = { diff --git a/addons/website_customer/controllers/main.py b/addons/website_customer/controllers/main.py index 6310fe4986d..fcb2d0d8ded 100644 --- a/addons/website_customer/controllers/main.py +++ b/addons/website_customer/controllers/main.py @@ -1,9 +1,8 @@ # -*- coding: utf-8 -*- -import re - import openerp from openerp import SUPERUSER_ID from openerp.addons.web import http +from openerp.addons.website.models.website import unslug from openerp.tools.translate import _ from openerp.addons.web.http import request import werkzeug.urls @@ -84,9 +83,8 @@ class WebsiteCustomer(http.Controller): # Do not use semantic controller due to SUPERUSER_ID @http.route(['/customers/'], type='http', auth="public", website=True) def partners_detail(self, partner_id, **post): - mo = re.search('([-0-9]+)$', str(partner_id)) - if mo: - partner_id = int(mo.group(1)) + _, partner_id = unslug(partner_id) + if partner_id: partner = request.registry['res.partner'].browse(request.cr, SUPERUSER_ID, partner_id, context=request.context) if partner.exists() and partner.website_published: values = {} diff --git a/addons/website_membership/controllers/main.py b/addons/website_membership/controllers/main.py index 171b56825c0..52ba31324f0 100644 --- a/addons/website_membership/controllers/main.py +++ b/addons/website_membership/controllers/main.py @@ -1,9 +1,8 @@ # -*- coding: utf-8 -*- -import re - from openerp import SUPERUSER_ID from openerp.addons.web import http from openerp.addons.web.http import request +from openerp.addons.website.models.website import unslug from openerp.tools.translate import _ import werkzeug.urls @@ -105,9 +104,8 @@ class WebsiteMembership(http.Controller): # Do not use semantic controller due to SUPERUSER_ID @http.route(['/members/'], type='http', auth="public", website=True) def partners_detail(self, partner_id, **post): - mo = re.search('([-0-9]+)$', str(partner_id)) - if mo: - partner_id = int(mo.group(1)) + _, partner_id = unslug(partner_id) + if partner_id: partner = request.registry['res.partner'].browse(request.cr, SUPERUSER_ID, partner_id, context=request.context) if partner.exists() and partner.website_published: values = {}