[IMP] account: bank statement reconciliation proposition:
authorArthur Maniet <me@whisno.be>
Tue, 25 Nov 2014 15:46:30 +0000 (16:46 +0100)
committerArthur Maniet <me@whisno.be>
Tue, 25 Nov 2014 15:48:32 +0000 (16:48 +0100)
- find a move line whose amount exactly matches the bank statement line amount even if it has no partner
- properly handle multicurrency
- if there's no exact match, look for a set of move line whose amount is <= to the statement line's amount

addons/account/account_bank_statement.py

index 99afc92..0e16ba6 100644 (file)
@@ -547,34 +547,49 @@ class account_bank_statement_line(osv.osv):
                     mv_line['has_no_partner'] = False
                 return [mv_line]
 
-        # If there is no identified partner or structured communication, don't look further
-        if not st_line.partner_id.id:
-            return []
-
-        # Look for a move line whose amount matches the statement line's amount
-        company_currency = st_line.journal_id.company_id.currency_id.id
-        statement_currency = st_line.journal_id.currency.id or company_currency
-        sign = 1
-        if statement_currency == company_currency:
-            amount_field = 'credit'
-            if st_line.amount > 0:
-                amount_field = 'debit'
-            else:
+        # How to compare statement line amount and move lines amount
+        currency_id = st_line.currency_id.id or st_line.journal_id.currency.id
+        amount = st_line.amount_currency or st_line.amount
+        domain = [('reconcile_partial_id', '=', False)]
+        if currency_id:
+            domain += [('currency_id', '=', currency_id)]
+        sign = 1 # correct the fact that st_line.amount is signed and debit/credit is not
+        amount_field = 'debit'
+        if currency_id == False:
+            if amount < 0:
+                amount_field = 'credit'
                 sign = -1
         else:
             amount_field = 'amount_currency'
-            if st_line.amount < 0:
-                sign = -1
-        if st_line.amount_currency:
-            amount = st_line.amount_currency
-        else:
-            amount = st_line.amount
 
-        match_id = self.get_move_lines_for_reconciliation(cr, uid, st_line, excluded_ids=excluded_ids, offset=0, limit=1, additional_domain=[(amount_field, '=', (sign * amount))])
+        # Look for an matching amount
+        domain_exact_amount = domain + [(amount_field, '=', (sign * amount))]
+        match_id = self.get_move_lines_for_reconciliation(cr, uid, st_line, excluded_ids=excluded_ids, offset=0, limit=1, additional_domain=domain_exact_amount)
         if match_id:
-            return [match_id[0]]
+            return match_id
 
-        return []
+        if not st_line.partner_id.id:
+            return []
+
+        # Look for a set of move line whose amount is <= to the line's amount
+        if amount > 0: # Make sure we can't mix receivable and payable
+            domain += [('account_id.type', '=', 'receivable')]
+        else:
+            domain += [('account_id.type', '=', 'payable')]
+        if amount_field == 'amount_currency' and amount < 0:
+            domain += [(amount_field, '<', 0), (amount_field, '>', (sign * amount))]
+        else:
+            domain += [(amount_field, '>', 0), (amount_field, '<', (sign * amount))]
+        mv_lines = self.get_move_lines_for_reconciliation(cr, uid, st_line, excluded_ids=excluded_ids, limit=5, additional_domain=domain)
+        ret = []
+        total = 0
+        for line in mv_lines:
+            if total + abs(line['debit'] - line['credit']) <= abs(amount):
+                ret.append(line)
+                total += abs(line['debit'] - line['credit'])
+            if total >= abs(amount):
+                break
+        return ret
 
     def get_move_lines_for_reconciliation_by_statement_line_id(self, cr, uid, st_line_id, excluded_ids=None, str=False, offset=0, limit=None, count=False, additional_domain=None, context=None):
         """ Bridge between the web client reconciliation widget and get_move_lines_for_reconciliation (which expects a browse record) """