Merge lp:~camptocamp/banking-addons/bank-statement-reconcile-7.0-account_easy_reconcile-analytic-account into lp:banking-addons

Proposed by Guewen Baconnier @ Camptocamp
Status: Superseded
Proposed branch: lp:~camptocamp/banking-addons/bank-statement-reconcile-7.0-account_easy_reconcile-analytic-account
Merge into: lp:banking-addons
Diff against target: 12704 lines (+11864/-0)
156 files modified
account_advanced_reconcile/__init__.py (+24/-0)
account_advanced_reconcile/__openerp__.py (+83/-0)
account_advanced_reconcile/advanced_reconciliation.py (+118/-0)
account_advanced_reconcile/base_advanced_reconciliation.py (+272/-0)
account_advanced_reconcile/easy_reconcile.py (+36/-0)
account_advanced_reconcile/easy_reconcile_view.xml (+19/-0)
account_advanced_reconcile/i18n/account_advanced_reconcile.pot (+90/-0)
account_advanced_reconcile/i18n/fr.po (+98/-0)
account_advanced_reconcile_transaction_ref/__init__.py (+24/-0)
account_advanced_reconcile_transaction_ref/__openerp__.py (+40/-0)
account_advanced_reconcile_transaction_ref/account.py (+54/-0)
account_advanced_reconcile_transaction_ref/advanced_reconciliation.py (+43/-0)
account_advanced_reconcile_transaction_ref/base_advanced_reconciliation.py (+46/-0)
account_advanced_reconcile_transaction_ref/easy_reconcile.py (+37/-0)
account_advanced_reconcile_transaction_ref/easy_reconcile_view.xml (+19/-0)
account_advanced_reconcile_transaction_ref/i18n/account_advanced_reconcile_transaction_ref.pot (+97/-0)
account_advanced_reconcile_transaction_ref/i18n/fr.po (+106/-0)
account_easy_reconcile/__init__.py (+25/-0)
account_easy_reconcile/__openerp__.py (+66/-0)
account_easy_reconcile/base_reconciliation.py (+211/-0)
account_easy_reconcile/easy_reconcile.py (+290/-0)
account_easy_reconcile/easy_reconcile.xml (+158/-0)
account_easy_reconcile/easy_reconcile_history.py (+153/-0)
account_easy_reconcile/easy_reconcile_history_view.xml (+98/-0)
account_easy_reconcile/i18n/account_easy_reconcile.pot (+406/-0)
account_easy_reconcile/i18n/fr.po (+432/-0)
account_easy_reconcile/security/ir.model.access.csv (+15/-0)
account_easy_reconcile/security/ir_rule.xml (+25/-0)
account_easy_reconcile/simple_reconciliation.py (+120/-0)
account_statement_bankaccount_completion/__init__.py (+21/-0)
account_statement_bankaccount_completion/__openerp__.py (+48/-0)
account_statement_bankaccount_completion/data.xml (+12/-0)
account_statement_bankaccount_completion/i18n/account_statement_bankaccount_completion.pot (+43/-0)
account_statement_bankaccount_completion/statement.py (+96/-0)
account_statement_bankaccount_completion/tests/__init__.py (+27/-0)
account_statement_bankaccount_completion/tests/test_bankaccount_completion.py (+91/-0)
account_statement_base_completion/__init__.py (+23/-0)
account_statement_base_completion/__openerp__.py (+77/-0)
account_statement_base_completion/data.xml (+31/-0)
account_statement_base_completion/i18n/account_statement_base_completion.pot (+199/-0)
account_statement_base_completion/i18n/fr.po (+216/-0)
account_statement_base_completion/partner.py (+38/-0)
account_statement_base_completion/partner_view.xml (+22/-0)
account_statement_base_completion/security/ir.model.access.csv (+3/-0)
account_statement_base_completion/statement.py (+573/-0)
account_statement_base_completion/statement_view.xml (+104/-0)
account_statement_base_completion/test/completion_test.yml (+87/-0)
account_statement_base_completion/test/invoice.yml (+32/-0)
account_statement_base_completion/test/partner.yml (+5/-0)
account_statement_base_completion/test/supplier_invoice.yml (+31/-0)
account_statement_base_completion/tests/__init__.py (+27/-0)
account_statement_base_completion/tests/test_base_completion.py (+95/-0)
account_statement_base_import/__init__.py (+23/-0)
account_statement_base_import/__openerp__.py (+69/-0)
account_statement_base_import/data/statement.csv (+4/-0)
account_statement_base_import/i18n/account_statement_base_import.pot (+289/-0)
account_statement_base_import/i18n/fr.po (+303/-0)
account_statement_base_import/parser/__init__.py (+25/-0)
account_statement_base_import/parser/file_parser.py (+221/-0)
account_statement_base_import/parser/generic_file_parser.py (+74/-0)
account_statement_base_import/parser/parser.py (+222/-0)
account_statement_base_import/statement.py (+240/-0)
account_statement_base_import/statement_view.xml (+30/-0)
account_statement_base_import/wizard/__init__.py (+20/-0)
account_statement_base_import/wizard/import_statement.py (+116/-0)
account_statement_base_import/wizard/import_statement_view.xml (+42/-0)
account_statement_commission/__init__.py (+22/-0)
account_statement_commission/__openerp__.py (+47/-0)
account_statement_commission/commission.py (+72/-0)
account_statement_commission/i18n/account_statement_commission.pot (+53/-0)
account_statement_commission/import_statement_view.xml (+18/-0)
account_statement_commission/statement_view.xml (+21/-0)
account_statement_completion_voucher/__init__.py (+20/-0)
account_statement_completion_voucher/__openerp__.py (+46/-0)
account_statement_completion_voucher/statement_view.xml (+21/-0)
account_statement_ext/__init__.py (+25/-0)
account_statement_ext/__openerp__.py (+88/-0)
account_statement_ext/account.py (+41/-0)
account_statement_ext/i18n/fr.po (+301/-0)
account_statement_ext/report.xml (+25/-0)
account_statement_ext/report/__init__.py (+26/-0)
account_statement_ext/report/bank_statement_report.mako (+70/-0)
account_statement_ext/report/bank_statement_report.py (+71/-0)
account_statement_ext/report/bank_statement_webkit_header.xml (+180/-0)
account_statement_ext/security/ir.model.access.csv (+3/-0)
account_statement_ext/security/ir_rule.xml (+10/-0)
account_statement_ext/statement.py (+745/-0)
account_statement_ext/statement_view.xml (+160/-0)
account_statement_ext/test/test_profile_related_fields.yml (+78/-0)
account_statement_ext/voucher.py (+49/-0)
account_statement_ext_point_of_sale/__init__.py (+22/-0)
account_statement_ext_point_of_sale/__openerp__.py (+43/-0)
account_statement_ext_point_of_sale/point_of_sale.py (+123/-0)
account_statement_ext_voucher/__init__.py (+20/-0)
account_statement_ext_voucher/__openerp__.py (+52/-0)
account_statement_ext_voucher/statement_voucher.py (+51/-0)
account_statement_no_invoice_import/__init__.py (+22/-0)
account_statement_no_invoice_import/__openerp__.py (+40/-0)
account_statement_no_invoice_import/statement_view.xml (+21/-0)
account_statement_ofx_import/__init__.py (+22/-0)
account_statement_ofx_import/__openerp__.py (+49/-0)
account_statement_ofx_import/i18n/account_statement_ofx_import.pot (+34/-0)
account_statement_ofx_import/parser/__init__.py (+22/-0)
account_statement_ofx_import/parser/ofx_parser.py (+118/-0)
account_statement_ofx_import/statement.py (+35/-0)
account_statement_one_move/__init__.py (+23/-0)
account_statement_one_move/__openerp__.py (+45/-0)
account_statement_one_move/statement.py (+225/-0)
account_statement_one_move/statement_view.xml (+26/-0)
account_statement_regex_account_completion/__init__.py (+32/-0)
account_statement_regex_account_completion/__openerp__.py (+56/-0)
account_statement_regex_account_completion/i18n/account_statement_regex_account_completion.pot (+32/-0)
account_statement_regex_account_completion/i18n/fr.po (+32/-0)
account_statement_regex_account_completion/statement.py (+75/-0)
account_statement_regex_account_completion/statement_view.xml (+21/-0)
account_statement_regex_account_completion/tests/__init__.py (+36/-0)
account_statement_regex_account_completion/tests/test_regex_account_completion.py (+91/-0)
account_statement_so_completion/__init__.py (+25/-0)
account_statement_so_completion/__openerp__.py (+52/-0)
account_statement_so_completion/data.xml (+12/-0)
account_statement_so_completion/i18n/account_statement_so_completion.pot (+28/-0)
account_statement_so_completion/statement.py (+94/-0)
account_statement_so_completion/test/completion_so_test.yml (+44/-0)
account_statement_transactionid_completion/__init__.py (+22/-0)
account_statement_transactionid_completion/__openerp__.py (+59/-0)
account_statement_transactionid_completion/data.xml (+12/-0)
account_statement_transactionid_completion/i18n/account_statement_transactionid_completion.pot (+43/-0)
account_statement_transactionid_completion/statement.py (+94/-0)
account_statement_transactionid_completion/statement_view.xml (+22/-0)
account_statement_transactionid_completion/test/completion_transactionid_test.yml (+44/-0)
account_statement_transactionid_completion/test/sale.yml (+11/-0)
account_statement_transactionid_import/__init__.py (+22/-0)
account_statement_transactionid_import/__openerp__.py (+60/-0)
account_statement_transactionid_import/data/statement.csv (+4/-0)
account_statement_transactionid_import/i18n/account_statement_transactionid_import.pot (+21/-0)
account_statement_transactionid_import/parser/__init__.py (+22/-0)
account_statement_transactionid_import/parser/transactionid_file_parser.py (+80/-0)
account_statement_transactionid_import/statement.py (+47/-0)
base_transaction_id/__init__.py (+24/-0)
base_transaction_id/__openerp__.py (+57/-0)
base_transaction_id/i18n/base_transaction_id.pot (+58/-0)
base_transaction_id/invoice.py (+36/-0)
base_transaction_id/invoice_view.xml (+30/-0)
base_transaction_id/sale.py (+43/-0)
base_transaction_id/sale_view.xml (+21/-0)
base_transaction_id/stock.py (+42/-0)
invoicing_voucher_killer/__init__.py (+20/-0)
invoicing_voucher_killer/__openerp__.py (+39/-0)
invoicing_voucher_killer/i18n/invoicing_voucher_killer.pot (+32/-0)
invoicing_voucher_killer/invoice_data.xml (+7/-0)
invoicing_voucher_killer/invoice_view.xml (+48/-0)
statement_voucher_killer/__init__.py (+21/-0)
statement_voucher_killer/__openerp__.py (+48/-0)
statement_voucher_killer/i18n/statement_voucher_killer.pot (+27/-0)
statement_voucher_killer/statement_view.xml (+20/-0)
statement_voucher_killer/voucher.py (+129/-0)
To merge this branch: bzr merge lp:~camptocamp/banking-addons/bank-statement-reconcile-7.0-account_easy_reconcile-analytic-account
Reviewer Review Type Date Requested Status
Banking Addons Core Editors Pending
Review via email: mp+213006@code.launchpad.net

This proposal has been superseded by a proposal from 2014-03-27.

Description of the change

Allow to set an analytic account on write-off entries created during reconciliations.

To post a comment you must log in.

Unmerged revisions

138. By Guewen Baconnier @ Camptocamp

In account_easy_reconcile, now write-off entries can be created with an analytic account

137. By Launchpad Translations on behalf of banking-addons-team

Launchpad automatic translations update.

136. By Pedro Manuel Baeza

[IMP] Translation template files.

135. By Launchpad Translations on behalf of banking-addons-team

Launchpad automatic translations update.

134. By Leonardo Pistone

[fix] account_statement_ext: trigger related fields

133. By Alexandre Fayolle - camptocamp

fix issue when creating empty statement (lp:1247876) and add a module which enables bank statement creation from the point of sale with the banking framework installed.

132. By Florian da Costa

[IMP] Allow to import xlsx files

131. By Sébastien BEAU - http://www.akretion.com

[ADD] module account_statement_one_move

130. By Stéphane Bidoul (Acsone)

Do not auto_install account_statement_bankaccount_completion.

129. By Sébastien BEAU - http://www.akretion.com

Little trick to avoid headhack

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'account_advanced_reconcile'
2=== added file 'account_advanced_reconcile/__init__.py'
3--- account_advanced_reconcile/__init__.py 1970-01-01 00:00:00 +0000
4+++ account_advanced_reconcile/__init__.py 2014-03-27 09:24:37 +0000
5@@ -0,0 +1,24 @@
6+# -*- coding: utf-8 -*-
7+##############################################################################
8+#
9+# Author: Guewen Baconnier
10+# Copyright 2012 Camptocamp SA
11+#
12+# This program is free software: you can redistribute it and/or modify
13+# it under the terms of the GNU Affero General Public License as
14+# published by the Free Software Foundation, either version 3 of the
15+# License, or (at your option) any later version.
16+#
17+# This program is distributed in the hope that it will be useful,
18+# but WITHOUT ANY WARRANTY; without even the implied warranty of
19+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+# GNU Affero General Public License for more details.
21+#
22+# You should have received a copy of the GNU Affero General Public License
23+# along with this program. If not, see <http://www.gnu.org/licenses/>.
24+#
25+##############################################################################
26+
27+import easy_reconcile
28+import base_advanced_reconciliation
29+import advanced_reconciliation
30
31=== added file 'account_advanced_reconcile/__openerp__.py'
32--- account_advanced_reconcile/__openerp__.py 1970-01-01 00:00:00 +0000
33+++ account_advanced_reconcile/__openerp__.py 2014-03-27 09:24:37 +0000
34@@ -0,0 +1,83 @@
35+# -*- coding: utf-8 -*-
36+##############################################################################
37+#
38+# Author: Guewen Baconnier
39+# Copyright 2012 Camptocamp SA
40+#
41+# This program is free software: you can redistribute it and/or modify
42+# it under the terms of the GNU Affero General Public License as
43+# published by the Free Software Foundation, either version 3 of the
44+# License, or (at your option) any later version.
45+#
46+# This program is distributed in the hope that it will be useful,
47+# but WITHOUT ANY WARRANTY; without even the implied warranty of
48+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
49+# GNU Affero General Public License for more details.
50+#
51+# You should have received a copy of the GNU Affero General Public License
52+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53+#
54+##############################################################################
55+
56+{'name': "Advanced Reconcile",
57+ 'version': '1.0',
58+ 'author': 'Camptocamp',
59+ 'maintainer': 'Camptocamp',
60+ 'category': 'Finance',
61+ 'complexity': 'normal',
62+ 'depends': ['account_easy_reconcile',
63+ ],
64+ 'description': """
65+Advanced reconciliation methods for the module account_easy_reconcile.
66+
67+In addition to the features implemented in account_easy_reconcile, which are:
68+ - reconciliation facilities for big volume of transactions
69+ - setup different profiles of reconciliation by account
70+ - each profile can use many methods of reconciliation
71+ - this module is also a base to create others reconciliation methods
72+ which can plug in the profiles
73+ - a profile a reconciliation can be run manually or by a cron
74+ - monitoring of reconcilation runs with an history
75+
76+It implements a basis to created advanced reconciliation methods in a few lines
77+of code.
78+
79+Typically, such a method can be:
80+ - Reconcile Journal items if the partner and the ref are equal
81+ - Reconcile Journal items if the partner is equal and the ref
82+ is the same than ref or name
83+ - Reconcile Journal items if the partner is equal and the ref
84+ match with a pattern
85+
86+And they allows:
87+ - Reconciliations with multiple credit / multiple debit lines
88+ - Partial reconciliations
89+ - Write-off amount as well
90+
91+A method is already implemented in this module, it matches on items:
92+ - Partner
93+ - Ref on credit move lines should be case insensitive equals to the ref or
94+ the name of the debit move line
95+
96+The base class to find the reconciliations is built to be as efficient as
97+possible.
98+
99+So basically, if you have an invoice with 3 payments (one per month), the first
100+month, it will partial reconcile the debit move line with the first payment, the second
101+month, it will partial reconcile the debit move line with 2 first payments,
102+the third month, it will make the full reconciliation.
103+
104+This module is perfectly adapted for E-Commerce business where a big volume of
105+move lines and so, reconciliations, are involved and payments often come from
106+many offices.
107+
108+ """,
109+ 'website': 'http://www.camptocamp.com',
110+ 'data': ['easy_reconcile_view.xml'],
111+ 'test': [],
112+ 'images': [],
113+ 'installable': True,
114+ 'auto_install': False,
115+ 'license': 'AGPL-3',
116+ 'application': True,
117+}
118
119=== added file 'account_advanced_reconcile/advanced_reconciliation.py'
120--- account_advanced_reconcile/advanced_reconciliation.py 1970-01-01 00:00:00 +0000
121+++ account_advanced_reconcile/advanced_reconciliation.py 2014-03-27 09:24:37 +0000
122@@ -0,0 +1,118 @@
123+# -*- coding: utf-8 -*-
124+##############################################################################
125+#
126+# Author: Guewen Baconnier
127+# Copyright 2012 Camptocamp SA
128+#
129+# This program is free software: you can redistribute it and/or modify
130+# it under the terms of the GNU Affero General Public License as
131+# published by the Free Software Foundation, either version 3 of the
132+# License, or (at your option) any later version.
133+#
134+# This program is distributed in the hope that it will be useful,
135+# but WITHOUT ANY WARRANTY; without even the implied warranty of
136+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
137+# GNU Affero General Public License for more details.
138+#
139+# You should have received a copy of the GNU Affero General Public License
140+# along with this program. If not, see <http://www.gnu.org/licenses/>.
141+#
142+##############################################################################
143+
144+from openerp.osv import orm
145+
146+
147+class easy_reconcile_advanced_ref(orm.TransientModel):
148+
149+ _name = 'easy.reconcile.advanced.ref'
150+ _inherit = 'easy.reconcile.advanced'
151+
152+ def _skip_line(self, cr, uid, rec, move_line, context=None):
153+ """
154+ When True is returned on some conditions, the credit move line
155+ will be skipped for reconciliation. Can be inherited to
156+ skip on some conditions. ie: ref or partner_id is empty.
157+ """
158+ return not (move_line.get('ref') and move_line.get('partner_id'))
159+
160+ def _matchers(self, cr, uid, rec, move_line, context=None):
161+ """
162+ Return the values used as matchers to find the opposite lines
163+
164+ All the matcher keys in the dict must have their equivalent in
165+ the `_opposite_matchers`.
166+
167+ The values of each matcher key will be searched in the
168+ one returned by the `_opposite_matchers`
169+
170+ Must be inherited to implement the matchers for one method
171+
172+ For instance, it can return:
173+ return ('ref', move_line['rec'])
174+
175+ or
176+ return (('partner_id', move_line['partner_id']),
177+ ('ref', "prefix_%s" % move_line['rec']))
178+
179+ All the matchers have to be found in the opposite lines
180+ to consider them as "opposite"
181+
182+ The matchers will be evaluated in the same order as declared
183+ vs the the opposite matchers, so you can gain performance by
184+ declaring first the partners with the less computation.
185+
186+ All matchers should match with their opposite to be considered
187+ as "matching".
188+ So with the previous example, partner_id and ref have to be
189+ equals on the opposite line matchers.
190+
191+ :return: tuple of tuples (key, value) where the keys are
192+ the matchers keys
193+ (must be the same than `_opposite_matchers` returns,
194+ and their values to match in the opposite lines.
195+ A matching key can have multiples values.
196+ """
197+ return (('partner_id', move_line['partner_id']),
198+ ('ref', move_line['ref'].lower().strip()))
199+
200+ def _opposite_matchers(self, cr, uid, rec, move_line, context=None):
201+ """
202+ Return the values of the opposite line used as matchers
203+ so the line is matched
204+
205+ Must be inherited to implement the matchers for one method
206+ It can be inherited to apply some formatting of fields
207+ (strip(), lower() and so on)
208+
209+ This method is the counterpart of the `_matchers()` method.
210+
211+ Each matcher has to yield its value respecting the order
212+ of the `_matchers()`.
213+
214+ When a matcher does not correspond, the next matchers won't
215+ be evaluated so the ones which need the less computation
216+ have to be executed first.
217+
218+ If the `_matchers()` returns:
219+ (('partner_id', move_line['partner_id']),
220+ ('ref', move_line['ref']))
221+
222+ Here, you should yield :
223+ yield ('partner_id', move_line['partner_id'])
224+ yield ('ref', move_line['ref'])
225+
226+ Note that a matcher can contain multiple values, as instance,
227+ if for a move line, you want to search from its `ref` in the
228+ `ref` or `name` fields of the opposite move lines, you have to
229+ yield ('partner_id', move_line['partner_id'])
230+ yield ('ref', (move_line['ref'], move_line['name'])
231+
232+ An OR is used between the values for the same key.
233+ An AND is used between the differents keys.
234+
235+ :param dict move_line: values of the move_line
236+ :yield: matchers as tuple ('matcher key', value(s))
237+ """
238+ yield ('partner_id', move_line['partner_id'])
239+ yield ('ref', ((move_line['ref'] or '').lower().strip(),
240+ move_line['name'].lower().strip()))
241
242=== added file 'account_advanced_reconcile/base_advanced_reconciliation.py'
243--- account_advanced_reconcile/base_advanced_reconciliation.py 1970-01-01 00:00:00 +0000
244+++ account_advanced_reconcile/base_advanced_reconciliation.py 2014-03-27 09:24:37 +0000
245@@ -0,0 +1,272 @@
246+# -*- coding: utf-8 -*-
247+##############################################################################
248+#
249+# Author: Guewen Baconnier
250+# Copyright 2012 Camptocamp SA
251+#
252+# This program is free software: you can redistribute it and/or modify
253+# it under the terms of the GNU Affero General Public License as
254+# published by the Free Software Foundation, either version 3 of the
255+# License, or (at your option) any later version.
256+#
257+# This program is distributed in the hope that it will be useful,
258+# but WITHOUT ANY WARRANTY; without even the implied warranty of
259+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
260+# GNU Affero General Public License for more details.
261+#
262+# You should have received a copy of the GNU Affero General Public License
263+# along with this program. If not, see <http://www.gnu.org/licenses/>.
264+#
265+##############################################################################
266+
267+from itertools import product
268+from openerp.osv import orm
269+
270+
271+class easy_reconcile_advanced(orm.AbstractModel):
272+
273+ _name = 'easy.reconcile.advanced'
274+ _inherit = 'easy.reconcile.base'
275+
276+ def _query_debit(self, cr, uid, rec, context=None):
277+ """Select all move (debit>0) as candidate. """
278+ select = self._select(rec)
279+ sql_from = self._from(rec)
280+ where, params = self._where(rec)
281+ where += " AND account_move_line.debit > 0 "
282+
283+ where2, params2 = self._get_filter(cr, uid, rec, context=context)
284+
285+ query = ' '.join((select, sql_from, where, where2))
286+
287+ cr.execute(query, params + params2)
288+ return cr.dictfetchall()
289+
290+ def _query_credit(self, cr, uid, rec, context=None):
291+ """Select all move (credit>0) as candidate. """
292+ select = self._select(rec)
293+ sql_from = self._from(rec)
294+ where, params = self._where(rec)
295+ where += " AND account_move_line.credit > 0 "
296+
297+ where2, params2 = self._get_filter(cr, uid, rec, context=context)
298+
299+ query = ' '.join((select, sql_from, where, where2))
300+
301+ cr.execute(query, params + params2)
302+ return cr.dictfetchall()
303+
304+ def _matchers(self, cr, uid, rec, move_line, context=None):
305+ """
306+ Return the values used as matchers to find the opposite lines
307+
308+ All the matcher keys in the dict must have their equivalent in
309+ the `_opposite_matchers`.
310+
311+ The values of each matcher key will be searched in the
312+ one returned by the `_opposite_matchers`
313+
314+ Must be inherited to implement the matchers for one method
315+
316+ As instance, it can return:
317+ return ('ref', move_line['rec'])
318+
319+ or
320+ return (('partner_id', move_line['partner_id']),
321+ ('ref', "prefix_%s" % move_line['rec']))
322+
323+ All the matchers have to be found in the opposite lines
324+ to consider them as "opposite"
325+
326+ The matchers will be evaluated in the same order as declared
327+ vs the the opposite matchers, so you can gain performance by
328+ declaring first the partners with the less computation.
329+
330+ All matchers should match with their opposite to be considered
331+ as "matching".
332+ So with the previous example, partner_id and ref have to be
333+ equals on the opposite line matchers.
334+
335+ :return: tuple of tuples (key, value) where the keys are
336+ the matchers keys
337+ (must be the same than `_opposite_matchers` returns,
338+ and their values to match in the opposite lines.
339+ A matching key can have multiples values.
340+ """
341+ raise NotImplementedError
342+
343+ def _opposite_matchers(self, cr, uid, rec, move_line, context=None):
344+ """
345+ Return the values of the opposite line used as matchers
346+ so the line is matched
347+
348+ Must be inherited to implement the matchers for one method
349+ It can be inherited to apply some formatting of fields
350+ (strip(), lower() and so on)
351+
352+ This method is the counterpart of the `_matchers()` method.
353+
354+ Each matcher has to yield its value respecting the order
355+ of the `_matchers()`.
356+
357+ When a matcher does not correspond, the next matchers won't
358+ be evaluated so the ones which need the less computation
359+ have to be executed first.
360+
361+ If the `_matchers()` returns:
362+ (('partner_id', move_line['partner_id']),
363+ ('ref', move_line['ref']))
364+
365+ Here, you should yield :
366+ yield ('partner_id', move_line['partner_id'])
367+ yield ('ref', move_line['ref'])
368+
369+ Note that a matcher can contain multiple values, as instance,
370+ if for a move line, you want to search from its `ref` in the
371+ `ref` or `name` fields of the opposite move lines, you have to
372+ yield ('partner_id', move_line['partner_id'])
373+ yield ('ref', (move_line['ref'], move_line['name'])
374+
375+ An OR is used between the values for the same key.
376+ An AND is used between the differents keys.
377+
378+ :param dict move_line: values of the move_line
379+ :yield: matchers as tuple ('matcher key', value(s))
380+ """
381+ raise NotImplementedError
382+
383+ @staticmethod
384+ def _compare_values(key, value, opposite_value):
385+ """Can be inherited to modify the equality condition
386+ specifically according to the matcher key (maybe using
387+ a like operator instead of equality on 'ref' as instance)
388+ """
389+ # consider that empty vals are not valid matchers
390+ # it can still be inherited for some special cases
391+ # where it would be allowed
392+ if not (value and opposite_value):
393+ return False
394+
395+ if value == opposite_value:
396+ return True
397+ return False
398+
399+ @staticmethod
400+ def _compare_matcher_values(key, values, opposite_values):
401+ """ Compare every values from a matcher vs an opposite matcher
402+ and return True if it matches
403+ """
404+ for value, ovalue in product(values, opposite_values):
405+ # we do not need to compare all values, if one matches
406+ # we are done
407+ if easy_reconcile_advanced._compare_values(key, value, ovalue):
408+ return True
409+ return False
410+
411+ @staticmethod
412+ def _compare_matchers(matcher, opposite_matcher):
413+ """
414+ Prepare and check the matchers to compare
415+ """
416+ mkey, mvalue = matcher
417+ omkey, omvalue = opposite_matcher
418+ assert mkey == omkey, ("A matcher %s is compared with a matcher %s, "
419+ " the _matchers and _opposite_matchers are probably wrong" %
420+ (mkey, omkey))
421+ if not isinstance(mvalue, (list, tuple)):
422+ mvalue = mvalue,
423+ if not isinstance(omvalue, (list, tuple)):
424+ omvalue = omvalue,
425+ return easy_reconcile_advanced._compare_matcher_values(mkey, mvalue, omvalue)
426+
427+ def _compare_opposite(self, cr, uid, rec, move_line, opposite_move_line,
428+ matchers, context=None):
429+ """ Iterate over the matchers of the move lines vs opposite move lines
430+ and if they all match, return True.
431+
432+ If all the matchers match for a move line and an opposite move line,
433+ they are candidate for a reconciliation.
434+ """
435+ opp_matchers = self._opposite_matchers(cr, uid, rec, opposite_move_line,
436+ context=context)
437+ for matcher in matchers:
438+ try:
439+ opp_matcher = opp_matchers.next()
440+ except StopIteration:
441+ # if you fall here, you probably missed to put a `yield`
442+ # in `_opposite_matchers()`
443+ raise ValueError("Missing _opposite_matcher: %s" % matcher[0])
444+
445+ if not self._compare_matchers(matcher, opp_matcher):
446+ # if any of the matcher fails, the opposite line
447+ # is not a valid counterpart
448+ # directly returns so the next yield of _opposite_matchers
449+ # are not evaluated
450+ return False
451+
452+ return True
453+
454+ def _search_opposites(self, cr, uid, rec, move_line, opposite_move_lines, context=None):
455+ """
456+ Search the opposite move lines for a move line
457+
458+ :param dict move_line: the move line for which we search opposites
459+ :param list opposite_move_lines: list of dict of move lines values, the move
460+ lines we want to search for
461+ :return: list of matching lines
462+ """
463+ matchers = self._matchers(cr, uid, rec, move_line, context=context)
464+ return [op for op in opposite_move_lines if
465+ self._compare_opposite(
466+ cr, uid, rec, move_line, op, matchers, context=context)]
467+
468+ def _action_rec(self, cr, uid, rec, context=None):
469+ credit_lines = self._query_credit(cr, uid, rec, context=context)
470+ debit_lines = self._query_debit(cr, uid, rec, context=context)
471+ return self._rec_auto_lines_advanced(
472+ cr, uid, rec, credit_lines, debit_lines, context=context)
473+
474+ def _skip_line(self, cr, uid, rec, move_line, context=None):
475+ """
476+ When True is returned on some conditions, the credit move line
477+ will be skipped for reconciliation. Can be inherited to
478+ skip on some conditions. ie: ref or partner_id is empty.
479+ """
480+ return False
481+
482+ def _rec_auto_lines_advanced(self, cr, uid, rec, credit_lines, debit_lines, context=None):
483+ """ Advanced reconciliation main loop """
484+ reconciled_ids = []
485+ partial_reconciled_ids = []
486+ reconcile_groups = []
487+
488+ for credit_line in credit_lines:
489+ if self._skip_line(cr, uid, rec, credit_line, context=context):
490+ continue
491+
492+ opposite_lines = self._search_opposites(
493+ cr, uid, rec, credit_line, debit_lines, context=context)
494+
495+ if not opposite_lines:
496+ continue
497+
498+ opposite_ids = [l['id'] for l in opposite_lines]
499+ line_ids = opposite_ids + [credit_line['id']]
500+ for group in reconcile_groups:
501+ if any([lid in group for lid in opposite_ids]):
502+ group.update(line_ids)
503+ break
504+ else:
505+ reconcile_groups.append(set(line_ids))
506+
507+ lines_by_id = dict([(l['id'], l) for l in credit_lines + debit_lines])
508+ for reconcile_group_ids in reconcile_groups:
509+ group_lines = [lines_by_id[lid] for lid in reconcile_group_ids]
510+ reconciled, full = self._reconcile_lines(
511+ cr, uid, rec, group_lines, allow_partial=True, context=context)
512+ if reconciled and full:
513+ reconciled_ids += reconcile_group_ids
514+ elif reconciled:
515+ partial_reconciled_ids += reconcile_group_ids
516+
517+ return reconciled_ids, partial_reconciled_ids
518
519=== added file 'account_advanced_reconcile/easy_reconcile.py'
520--- account_advanced_reconcile/easy_reconcile.py 1970-01-01 00:00:00 +0000
521+++ account_advanced_reconcile/easy_reconcile.py 2014-03-27 09:24:37 +0000
522@@ -0,0 +1,36 @@
523+# -*- coding: utf-8 -*-
524+##############################################################################
525+#
526+# Author: Guewen Baconnier
527+# Copyright 2012 Camptocamp SA
528+#
529+# This program is free software: you can redistribute it and/or modify
530+# it under the terms of the GNU Affero General Public License as
531+# published by the Free Software Foundation, either version 3 of the
532+# License, or (at your option) any later version.
533+#
534+# This program is distributed in the hope that it will be useful,
535+# but WITHOUT ANY WARRANTY; without even the implied warranty of
536+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
537+# GNU Affero General Public License for more details.
538+#
539+# You should have received a copy of the GNU Affero General Public License
540+# along with this program. If not, see <http://www.gnu.org/licenses/>.
541+#
542+##############################################################################
543+
544+from openerp.osv import orm
545+
546+
547+class account_easy_reconcile_method(orm.Model):
548+
549+ _inherit = 'account.easy.reconcile.method'
550+
551+ def _get_all_rec_method(self, cr, uid, context=None):
552+ methods = super(account_easy_reconcile_method, self).\
553+ _get_all_rec_method(cr, uid, context=context)
554+ methods += [
555+ ('easy.reconcile.advanced.ref',
556+ 'Advanced. Partner and Ref.'),
557+ ]
558+ return methods
559
560=== added file 'account_advanced_reconcile/easy_reconcile_view.xml'
561--- account_advanced_reconcile/easy_reconcile_view.xml 1970-01-01 00:00:00 +0000
562+++ account_advanced_reconcile/easy_reconcile_view.xml 2014-03-27 09:24:37 +0000
563@@ -0,0 +1,19 @@
564+<?xml version="1.0" encoding="utf-8"?>
565+<openerp>
566+ <data noupdate="0">
567+ <record id="view_easy_reconcile_form" model="ir.ui.view">
568+ <field name="name">account.easy.reconcile.form</field>
569+ <field name="model">account.easy.reconcile</field>
570+ <field name="inherit_id" ref="account_easy_reconcile.account_easy_reconcile_form"/>
571+ <field name="arch" type="xml">
572+ <page name="information" position="inside">
573+ <group colspan="2" col="2">
574+ <separator colspan="4" string="Advanced. Partner and Ref"/>
575+ <label string="Match multiple debit vs multiple credit entries. Allow partial reconciliation.
576+The lines should have the partner, the credit entry ref. is matched vs the debit entry ref. or name." colspan="4"/>
577+ </group>
578+ </page>
579+ </field>
580+ </record>
581+ </data>
582+</openerp>
583
584=== added directory 'account_advanced_reconcile/i18n'
585=== added file 'account_advanced_reconcile/i18n/account_advanced_reconcile.pot'
586--- account_advanced_reconcile/i18n/account_advanced_reconcile.pot 1970-01-01 00:00:00 +0000
587+++ account_advanced_reconcile/i18n/account_advanced_reconcile.pot 2014-03-27 09:24:37 +0000
588@@ -0,0 +1,90 @@
589+# Translation of OpenERP Server.
590+# This file contains the translation of the following modules:
591+# * account_advanced_reconcile
592+#
593+msgid ""
594+msgstr ""
595+"Project-Id-Version: OpenERP Server 7.0\n"
596+"Report-Msgid-Bugs-To: \n"
597+"POT-Creation-Date: 2014-01-21 11:54+0000\n"
598+"PO-Revision-Date: 2014-01-21 11:54+0000\n"
599+"Last-Translator: <>\n"
600+"Language-Team: \n"
601+"MIME-Version: 1.0\n"
602+"Content-Type: text/plain; charset=UTF-8\n"
603+"Content-Transfer-Encoding: \n"
604+"Plural-Forms: \n"
605+
606+#. module: account_advanced_reconcile
607+#: field:easy.reconcile.advanced,partner_ids:0
608+#: field:easy.reconcile.advanced.ref,partner_ids:0
609+msgid "Restrict on partners"
610+msgstr ""
611+
612+#. module: account_advanced_reconcile
613+#: field:easy.reconcile.advanced,account_id:0
614+#: field:easy.reconcile.advanced.ref,account_id:0
615+msgid "Account"
616+msgstr ""
617+
618+#. module: account_advanced_reconcile
619+#: model:ir.model,name:account_advanced_reconcile.model_account_easy_reconcile_method
620+msgid "reconcile method for account_easy_reconcile"
621+msgstr ""
622+
623+#. module: account_advanced_reconcile
624+#: field:easy.reconcile.advanced,journal_id:0
625+#: field:easy.reconcile.advanced.ref,journal_id:0
626+msgid "Journal"
627+msgstr ""
628+
629+#. module: account_advanced_reconcile
630+#: field:easy.reconcile.advanced,account_profit_id:0
631+#: field:easy.reconcile.advanced.ref,account_profit_id:0
632+msgid "Account Profit"
633+msgstr ""
634+
635+#. module: account_advanced_reconcile
636+#: view:account.easy.reconcile:0
637+msgid "Match multiple debit vs multiple credit entries. Allow partial reconciliation. The lines should have the partner, the credit entry ref. is matched vs the debit entry ref. or name."
638+msgstr ""
639+
640+#. module: account_advanced_reconcile
641+#: field:easy.reconcile.advanced,filter:0
642+#: field:easy.reconcile.advanced.ref,filter:0
643+msgid "Filter"
644+msgstr ""
645+
646+#. module: account_advanced_reconcile
647+#: view:account.easy.reconcile:0
648+msgid "Advanced. Partner and Ref"
649+msgstr ""
650+
651+#. module: account_advanced_reconcile
652+#: field:easy.reconcile.advanced,date_base_on:0
653+#: field:easy.reconcile.advanced.ref,date_base_on:0
654+msgid "Date of reconciliation"
655+msgstr ""
656+
657+#. module: account_advanced_reconcile
658+#: model:ir.model,name:account_advanced_reconcile.model_easy_reconcile_advanced
659+msgid "easy.reconcile.advanced"
660+msgstr ""
661+
662+#. module: account_advanced_reconcile
663+#: field:easy.reconcile.advanced,account_lost_id:0
664+#: field:easy.reconcile.advanced.ref,account_lost_id:0
665+msgid "Account Lost"
666+msgstr ""
667+
668+#. module: account_advanced_reconcile
669+#: model:ir.model,name:account_advanced_reconcile.model_easy_reconcile_advanced_ref
670+msgid "easy.reconcile.advanced.ref"
671+msgstr ""
672+
673+#. module: account_advanced_reconcile
674+#: field:easy.reconcile.advanced,write_off:0
675+#: field:easy.reconcile.advanced.ref,write_off:0
676+msgid "Write off allowed"
677+msgstr ""
678+
679
680=== added file 'account_advanced_reconcile/i18n/fr.po'
681--- account_advanced_reconcile/i18n/fr.po 1970-01-01 00:00:00 +0000
682+++ account_advanced_reconcile/i18n/fr.po 2014-03-27 09:24:37 +0000
683@@ -0,0 +1,98 @@
684+# Translation of OpenERP Server.
685+# This file contains the translation of the following modules:
686+# * account_advanced_reconcile
687+#
688+msgid ""
689+msgstr ""
690+"Project-Id-Version: OpenERP Server 6.1\n"
691+"Report-Msgid-Bugs-To: \n"
692+"POT-Creation-Date: 2014-01-21 11:54+0000\n"
693+"PO-Revision-Date: 2014-03-21 15:24+0000\n"
694+"Last-Translator: Guewen Baconnier @ Camptocamp <Unknown>\n"
695+"Language-Team: \n"
696+"MIME-Version: 1.0\n"
697+"Content-Type: text/plain; charset=UTF-8\n"
698+"Content-Transfer-Encoding: 8bit\n"
699+"X-Launchpad-Export-Date: 2014-03-22 07:11+0000\n"
700+"X-Generator: Launchpad (build 16967)\n"
701+"Language: \n"
702+
703+#. module: account_advanced_reconcile
704+#: field:easy.reconcile.advanced,partner_ids:0
705+#: field:easy.reconcile.advanced.ref,partner_ids:0
706+msgid "Restrict on partners"
707+msgstr "Restriction sur les partenaires"
708+
709+#. module: account_advanced_reconcile
710+#: field:easy.reconcile.advanced,account_id:0
711+#: field:easy.reconcile.advanced.ref,account_id:0
712+msgid "Account"
713+msgstr "Compte"
714+
715+#. module: account_advanced_reconcile
716+#: model:ir.model,name:account_advanced_reconcile.model_account_easy_reconcile_method
717+msgid "reconcile method for account_easy_reconcile"
718+msgstr "Méthode de lettrage pour le module account_easy_reconcile"
719+
720+#. module: account_advanced_reconcile
721+#: field:easy.reconcile.advanced,journal_id:0
722+#: field:easy.reconcile.advanced.ref,journal_id:0
723+msgid "Journal"
724+msgstr "Journal"
725+
726+#. module: account_advanced_reconcile
727+#: field:easy.reconcile.advanced,account_profit_id:0
728+#: field:easy.reconcile.advanced.ref,account_profit_id:0
729+msgid "Account Profit"
730+msgstr "Compte de produit"
731+
732+#. module: account_advanced_reconcile
733+#: view:account.easy.reconcile:0
734+msgid ""
735+"Match multiple debit vs multiple credit entries. Allow partial "
736+"reconciliation. The lines should have the partner, the credit entry ref. is "
737+"matched vs the debit entry ref. or name."
738+msgstr ""
739+"Le Lettrage peut s'effectuer sur plusieurs écritures de débit et crédit. Le "
740+"Lettrage partiel est autorisé. Les écritures doivent avoir le même "
741+"partenaire et la référence sur les écritures de crédit doit se retrouver "
742+"dans la référence ou la description sur les écritures de débit."
743+
744+#. module: account_advanced_reconcile
745+#: field:easy.reconcile.advanced,filter:0
746+#: field:easy.reconcile.advanced.ref,filter:0
747+msgid "Filter"
748+msgstr "Filtre"
749+
750+#. module: account_advanced_reconcile
751+#: view:account.easy.reconcile:0
752+msgid "Advanced. Partner and Ref"
753+msgstr "Avancé. Partenaire et Réf."
754+
755+#. module: account_advanced_reconcile
756+#: field:easy.reconcile.advanced,date_base_on:0
757+#: field:easy.reconcile.advanced.ref,date_base_on:0
758+msgid "Date of reconciliation"
759+msgstr "Date de lettrage"
760+
761+#. module: account_advanced_reconcile
762+#: model:ir.model,name:account_advanced_reconcile.model_easy_reconcile_advanced
763+msgid "easy.reconcile.advanced"
764+msgstr "easy.reconcile.advanced"
765+
766+#. module: account_advanced_reconcile
767+#: field:easy.reconcile.advanced,account_lost_id:0
768+#: field:easy.reconcile.advanced.ref,account_lost_id:0
769+msgid "Account Lost"
770+msgstr "Compte de charge"
771+
772+#. module: account_advanced_reconcile
773+#: model:ir.model,name:account_advanced_reconcile.model_easy_reconcile_advanced_ref
774+msgid "easy.reconcile.advanced.ref"
775+msgstr "easy.reconcile.advanced.ref"
776+
777+#. module: account_advanced_reconcile
778+#: field:easy.reconcile.advanced,write_off:0
779+#: field:easy.reconcile.advanced.ref,write_off:0
780+msgid "Write off allowed"
781+msgstr "Écart autorisé"
782
783=== added directory 'account_advanced_reconcile_transaction_ref'
784=== added file 'account_advanced_reconcile_transaction_ref/__init__.py'
785--- account_advanced_reconcile_transaction_ref/__init__.py 1970-01-01 00:00:00 +0000
786+++ account_advanced_reconcile_transaction_ref/__init__.py 2014-03-27 09:24:37 +0000
787@@ -0,0 +1,24 @@
788+# -*- coding: utf-8 -*-
789+##############################################################################
790+#
791+# Author: Romain Deheele. Copyright Camptocamp SA
792+#
793+# This program is free software: you can redistribute it and/or modify
794+# it under the terms of the GNU Affero General Public License as
795+# published by the Free Software Foundation, either version 3 of the
796+# License, or (at your option) any later version.
797+#
798+# This program is distributed in the hope that it will be useful,
799+# but WITHOUT ANY WARRANTY; without even the implied warranty of
800+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
801+# GNU Affero General Public License for more details.
802+#
803+# You should have received a copy of the GNU Affero General Public License
804+# along with this program. If not, see <http://www.gnu.org/licenses/>.
805+#
806+##############################################################################
807+
808+from . import account
809+from . import easy_reconcile
810+from . import base_advanced_reconciliation
811+from . import advanced_reconciliation
812
813=== added file 'account_advanced_reconcile_transaction_ref/__openerp__.py'
814--- account_advanced_reconcile_transaction_ref/__openerp__.py 1970-01-01 00:00:00 +0000
815+++ account_advanced_reconcile_transaction_ref/__openerp__.py 2014-03-27 09:24:37 +0000
816@@ -0,0 +1,40 @@
817+# -*- coding: utf-8 -*-
818+##############################################################################
819+#
820+# Author: Romain Deheele. Copyright Camptocamp SA
821+#
822+# This program is free software: you can redistribute it and/or modify
823+# it under the terms of the GNU Affero General Public License as
824+# published by the Free Software Foundation, either version 3 of the
825+# License, or (at your option) any later version.
826+#
827+# This program is distributed in the hope that it will be useful,
828+# but WITHOUT ANY WARRANTY; without even the implied warranty of
829+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
830+# GNU Affero General Public License for more details.
831+#
832+# You should have received a copy of the GNU Affero General Public License
833+# along with this program. If not, see <http://www.gnu.org/licenses/>.
834+#
835+##############################################################################
836+
837+{'name': 'Advanced Reconcile Transaction Ref',
838+ 'description': """
839+Advanced reconciliation method for the module account_easy_reconcile
840+=================================================
841+Reconcile rules with transaction_ref
842+
843+""",
844+ 'version': '1.0.1',
845+ 'author': 'Camptocamp',
846+ 'category': 'Finance',
847+ 'website': 'http://www.camptocamp.com',
848+ 'depends': ['account_advanced_reconcile'],
849+ 'data': ['easy_reconcile_view.xml'],
850+ 'demo': [],
851+ 'test': [], # To be ported or migrate to unit tests or scenarios
852+ 'auto_install': False,
853+ 'installable': True,
854+ 'images': []
855+}
856+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
857
858=== added file 'account_advanced_reconcile_transaction_ref/account.py'
859--- account_advanced_reconcile_transaction_ref/account.py 1970-01-01 00:00:00 +0000
860+++ account_advanced_reconcile_transaction_ref/account.py 2014-03-27 09:24:37 +0000
861@@ -0,0 +1,54 @@
862+# -*- coding: utf-8 -*-
863+##############################################################################
864+#
865+# Author: Romain Deheele
866+# Copyright 2013 Camptocamp SA
867+#
868+# This program is free software: you can redistribute it and/or modify
869+# it under the terms of the GNU Affero General Public License as
870+# published by the Free Software Foundation, either version 3 of the
871+# License, or (at your option) any later version.
872+#
873+# This program is distributed in the hope that it will be useful,
874+# but WITHOUT ANY WARRANTY; without even the implied warranty of
875+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
876+# GNU Affero General Public License for more details.
877+#
878+# You should have received a copy of the GNU Affero General Public License
879+# along with this program. If not, see <http://www.gnu.org/licenses/>.
880+#
881+##############################################################################
882+
883+from openerp.osv.orm import Model, fields
884+
885+class AccountMoveLine(Model):
886+ """
887+ Inherit account.move.line class in order to add transaction_ref field
888+ """
889+ _inherit = "account.move.line"
890+ _columns = {
891+ 'transaction_ref': fields.char('Transaction Ref.', size=128),
892+ }
893+
894+class AccountBankStatement(Model):
895+ """
896+ Inherit account.bank.statement class in order to set transaction_ref info on account.move.line
897+ """
898+ _inherit = "account.bank.statement"
899+
900+ def _prepare_move_line_vals(
901+ self, cr, uid, st_line, move_id, debit, credit, currency_id=False,
902+ amount_currency=False, account_id=False, analytic_id=False,
903+ partner_id=False, context=None):
904+
905+ if context is None:
906+ context = {}
907+ res = super(AccountBankStatement, self)._prepare_move_line_vals(
908+ cr, uid, st_line, move_id, debit, credit,
909+ currency_id=currency_id,
910+ amount_currency=amount_currency,
911+ account_id=account_id,
912+ analytic_id=analytic_id,
913+ partner_id=partner_id, context=context)
914+ res.update({'transaction_ref': st_line.ref})
915+ return res
916
917=== added file 'account_advanced_reconcile_transaction_ref/advanced_reconciliation.py'
918--- account_advanced_reconcile_transaction_ref/advanced_reconciliation.py 1970-01-01 00:00:00 +0000
919+++ account_advanced_reconcile_transaction_ref/advanced_reconciliation.py 2014-03-27 09:24:37 +0000
920@@ -0,0 +1,43 @@
921+# -*- coding: utf-8 -*-
922+##############################################################################
923+#
924+# Author: Romain Deheele. Copyright Camptocamp SA
925+#
926+# This program is free software: you can redistribute it and/or modify
927+# it under the terms of the GNU Affero General Public License as
928+# published by the Free Software Foundation, either version 3 of the
929+# License, or (at your option) any later version.
930+#
931+# This program is distributed in the hope that it will be useful,
932+# but WITHOUT ANY WARRANTY; without even the implied warranty of
933+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
934+# GNU Affero General Public License for more details.
935+#
936+# You should have received a copy of the GNU Affero General Public License
937+# along with this program. If not, see <http://www.gnu.org/licenses/>.
938+#
939+##############################################################################
940+
941+from openerp.osv import orm
942+
943+
944+class easy_reconcile_advanced_transaction_ref(orm.TransientModel):
945+
946+ _name = 'easy.reconcile.advanced.transaction_ref'
947+ _inherit = 'easy.reconcile.advanced'
948+
949+ def _skip_line(self, cr, uid, rec, move_line, context=None):
950+ """
951+ When True is returned on some conditions, the credit move line
952+ will be skipped for reconciliation. Can be inherited to
953+ skip on some conditions. ie: ref or partner_id is empty.
954+ """
955+ return not (move_line.get('ref') and move_line.get('partner_id'))
956+
957+ def _matchers(self, cr, uid, rec, move_line, context=None):
958+ return (('partner_id', move_line['partner_id']),
959+ ('ref', move_line['transaction_ref'].lower().strip()))
960+
961+ def _opposite_matchers(self, cr, uid, rec, move_line, context=None):
962+ yield ('partner_id', move_line['partner_id'])
963+ yield ('ref', (move_line['transaction_ref'] or '').lower().strip())
964
965=== added file 'account_advanced_reconcile_transaction_ref/base_advanced_reconciliation.py'
966--- account_advanced_reconcile_transaction_ref/base_advanced_reconciliation.py 1970-01-01 00:00:00 +0000
967+++ account_advanced_reconcile_transaction_ref/base_advanced_reconciliation.py 2014-03-27 09:24:37 +0000
968@@ -0,0 +1,46 @@
969+# -*- coding: utf-8 -*-
970+##############################################################################
971+#
972+# Author: Romain Deheele
973+# Copyright 2013 Camptocamp SA
974+#
975+# This program is free software: you can redistribute it and/or modify
976+# it under the terms of the GNU Affero General Public License as
977+# published by the Free Software Foundation, either version 3 of the
978+# License, or (at your option) any later version.
979+#
980+# This program is distributed in the hope that it will be useful,
981+# but WITHOUT ANY WARRANTY; without even the implied warranty of
982+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
983+# GNU Affero General Public License for more details.
984+#
985+# You should have received a copy of the GNU Affero General Public License
986+# along with this program. If not, see <http://www.gnu.org/licenses/>.
987+#
988+##############################################################################
989+
990+from itertools import product
991+from openerp.osv import orm
992+
993+
994+class easy_reconcile_advanced(orm.AbstractModel):
995+
996+ _inherit = 'easy.reconcile.advanced'
997+
998+ def _base_columns(self, rec):
999+ """ Mandatory columns for move lines queries
1000+ An extra column aliased as ``key`` should be defined
1001+ in each query."""
1002+ aml_cols = (
1003+ 'id',
1004+ 'debit',
1005+ 'credit',
1006+ 'date',
1007+ 'period_id',
1008+ 'ref',
1009+ 'name',
1010+ 'partner_id',
1011+ 'account_id',
1012+ 'move_id',
1013+ 'transaction_ref')
1014+ return ["account_move_line.%s" % col for col in aml_cols]
1015
1016=== added file 'account_advanced_reconcile_transaction_ref/easy_reconcile.py'
1017--- account_advanced_reconcile_transaction_ref/easy_reconcile.py 1970-01-01 00:00:00 +0000
1018+++ account_advanced_reconcile_transaction_ref/easy_reconcile.py 2014-03-27 09:24:37 +0000
1019@@ -0,0 +1,37 @@
1020+# -*- coding: utf-8 -*-
1021+##############################################################################
1022+#
1023+# Author: Romain Deheele
1024+# Copyright 2013 Camptocamp SA
1025+#
1026+# This program is free software: you can redistribute it and/or modify
1027+# it under the terms of the GNU Affero General Public License as
1028+# published by the Free Software Foundation, either version 3 of the
1029+# License, or (at your option) any later version.
1030+#
1031+# This program is distributed in the hope that it will be useful,
1032+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1033+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1034+# GNU Affero General Public License for more details.
1035+#
1036+# You should have received a copy of the GNU Affero General Public License
1037+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1038+#
1039+##############################################################################
1040+
1041+from openerp.osv import orm
1042+
1043+
1044+class account_easy_reconcile_method(orm.Model):
1045+
1046+ _inherit = 'account.easy.reconcile.method'
1047+
1048+ def _get_all_rec_method(self, cr, uid, context=None):
1049+ methods = super(account_easy_reconcile_method, self).\
1050+ _get_all_rec_method(cr, uid, context=context)
1051+ methods += [
1052+ ('easy.reconcile.advanced.transaction_ref',
1053+ 'Advanced. Partner and Transaction Ref.'),
1054+ ]
1055+ return methods
1056+
1057
1058=== added file 'account_advanced_reconcile_transaction_ref/easy_reconcile_view.xml'
1059--- account_advanced_reconcile_transaction_ref/easy_reconcile_view.xml 1970-01-01 00:00:00 +0000
1060+++ account_advanced_reconcile_transaction_ref/easy_reconcile_view.xml 2014-03-27 09:24:37 +0000
1061@@ -0,0 +1,19 @@
1062+<?xml version="1.0" encoding="utf-8"?>
1063+<openerp>
1064+ <data noupdate="0">
1065+ <record id="view_easy_reconcile_form" model="ir.ui.view">
1066+ <field name="name">account.easy.reconcile.form</field>
1067+ <field name="model">account.easy.reconcile</field>
1068+ <field name="inherit_id" ref="account_easy_reconcile.account_easy_reconcile_form"/>
1069+ <field name="arch" type="xml">
1070+ <page name="information" position="inside">
1071+ <group colspan="2" col="2">
1072+ <separator colspan="4" string="Advanced. Partner and Transaction Ref"/>
1073+ <label string="Match multiple debit vs multiple credit entries. Allow partial reconciliation.
1074+The lines should have the partner, the credit entry transaction ref. is matched vs the debit entry transaction ref. or name." colspan="4"/>
1075+ </group>
1076+ </page>
1077+ </field>
1078+ </record>
1079+ </data>
1080+</openerp>
1081
1082=== added directory 'account_advanced_reconcile_transaction_ref/i18n'
1083=== added file 'account_advanced_reconcile_transaction_ref/i18n/account_advanced_reconcile_transaction_ref.pot'
1084--- account_advanced_reconcile_transaction_ref/i18n/account_advanced_reconcile_transaction_ref.pot 1970-01-01 00:00:00 +0000
1085+++ account_advanced_reconcile_transaction_ref/i18n/account_advanced_reconcile_transaction_ref.pot 2014-03-27 09:24:37 +0000
1086@@ -0,0 +1,97 @@
1087+# Translation of OpenERP Server.
1088+# This file contains the translation of the following modules:
1089+# * account_advanced_reconcile_transaction_ref
1090+#
1091+msgid ""
1092+msgstr ""
1093+"Project-Id-Version: OpenERP Server 7.0\n"
1094+"Report-Msgid-Bugs-To: \n"
1095+"POT-Creation-Date: 2014-01-21 11:55+0000\n"
1096+"PO-Revision-Date: 2014-01-21 11:55+0000\n"
1097+"Last-Translator: <>\n"
1098+"Language-Team: \n"
1099+"MIME-Version: 1.0\n"
1100+"Content-Type: text/plain; charset=UTF-8\n"
1101+"Content-Transfer-Encoding: \n"
1102+"Plural-Forms: \n"
1103+
1104+#. module: account_advanced_reconcile_transaction_ref
1105+#: field:easy.reconcile.advanced.transaction_ref,partner_ids:0
1106+msgid "Restrict on partners"
1107+msgstr ""
1108+
1109+#. module: account_advanced_reconcile_transaction_ref
1110+#: field:easy.reconcile.advanced.transaction_ref,account_id:0
1111+msgid "Account"
1112+msgstr ""
1113+
1114+#. module: account_advanced_reconcile_transaction_ref
1115+#: view:account.easy.reconcile:0
1116+msgid "Advanced. Partner and Transaction Ref"
1117+msgstr ""
1118+
1119+#. module: account_advanced_reconcile_transaction_ref
1120+#: view:account.easy.reconcile:0
1121+msgid "Match multiple debit vs multiple credit entries. Allow partial reconciliation. The lines should have the partner, the credit entry transaction ref. is matched vs the debit entry transaction ref. or name."
1122+msgstr ""
1123+
1124+#. module: account_advanced_reconcile_transaction_ref
1125+#: model:ir.model,name:account_advanced_reconcile_transaction_ref.model_easy_reconcile_advanced_transaction_ref
1126+msgid "easy.reconcile.advanced.transaction_ref"
1127+msgstr ""
1128+
1129+#. module: account_advanced_reconcile_transaction_ref
1130+#: field:account.move.line,transaction_ref:0
1131+msgid "Transaction Ref."
1132+msgstr ""
1133+
1134+#. module: account_advanced_reconcile_transaction_ref
1135+#: field:easy.reconcile.advanced.transaction_ref,journal_id:0
1136+msgid "Journal"
1137+msgstr ""
1138+
1139+#. module: account_advanced_reconcile_transaction_ref
1140+#: field:easy.reconcile.advanced.transaction_ref,account_profit_id:0
1141+msgid "Account Profit"
1142+msgstr ""
1143+
1144+#. module: account_advanced_reconcile_transaction_ref
1145+#: model:ir.model,name:account_advanced_reconcile_transaction_ref.model_account_bank_statement
1146+msgid "Bank Statement"
1147+msgstr ""
1148+
1149+#. module: account_advanced_reconcile_transaction_ref
1150+#: field:easy.reconcile.advanced.transaction_ref,filter:0
1151+msgid "Filter"
1152+msgstr ""
1153+
1154+#. module: account_advanced_reconcile_transaction_ref
1155+#: model:ir.model,name:account_advanced_reconcile_transaction_ref.model_account_easy_reconcile_method
1156+msgid "reconcile method for account_easy_reconcile"
1157+msgstr ""
1158+
1159+#. module: account_advanced_reconcile_transaction_ref
1160+#: field:easy.reconcile.advanced.transaction_ref,date_base_on:0
1161+msgid "Date of reconciliation"
1162+msgstr ""
1163+
1164+#. module: account_advanced_reconcile_transaction_ref
1165+#: model:ir.model,name:account_advanced_reconcile_transaction_ref.model_account_move_line
1166+msgid "Journal Items"
1167+msgstr ""
1168+
1169+#. module: account_advanced_reconcile_transaction_ref
1170+#: model:ir.model,name:account_advanced_reconcile_transaction_ref.model_easy_reconcile_advanced
1171+msgid "easy.reconcile.advanced"
1172+msgstr ""
1173+
1174+#. module: account_advanced_reconcile_transaction_ref
1175+#: field:easy.reconcile.advanced.transaction_ref,account_lost_id:0
1176+msgid "Account Lost"
1177+msgstr ""
1178+
1179+#. module: account_advanced_reconcile_transaction_ref
1180+#: field:easy.reconcile.advanced.transaction_ref,write_off:0
1181+msgid "Write off allowed"
1182+msgstr ""
1183+
1184
1185=== added file 'account_advanced_reconcile_transaction_ref/i18n/fr.po'
1186--- account_advanced_reconcile_transaction_ref/i18n/fr.po 1970-01-01 00:00:00 +0000
1187+++ account_advanced_reconcile_transaction_ref/i18n/fr.po 2014-03-27 09:24:37 +0000
1188@@ -0,0 +1,106 @@
1189+# Translation of OpenERP Server.
1190+# This file contains the translation of the following modules:
1191+# * account_advanced_reconcile_transaction_ref
1192+#
1193+msgid ""
1194+msgstr ""
1195+"Project-Id-Version: OpenERP Server 7.0\n"
1196+"Report-Msgid-Bugs-To: \n"
1197+"POT-Creation-Date: 2014-01-21 11:55+0000\n"
1198+"PO-Revision-Date: 2014-03-21 15:25+0000\n"
1199+"Last-Translator: Vincent Renaville@camptocamp "
1200+"<vincent.renaville@camptocamp.com>\n"
1201+"Language-Team: \n"
1202+"MIME-Version: 1.0\n"
1203+"Content-Type: text/plain; charset=UTF-8\n"
1204+"Content-Transfer-Encoding: 8bit\n"
1205+"X-Launchpad-Export-Date: 2014-03-22 07:11+0000\n"
1206+"X-Generator: Launchpad (build 16967)\n"
1207+
1208+#. module: account_advanced_reconcile_transaction_ref
1209+#: field:easy.reconcile.advanced.transaction_ref,partner_ids:0
1210+msgid "Restrict on partners"
1211+msgstr "Restriction sur les partenaires"
1212+
1213+#. module: account_advanced_reconcile_transaction_ref
1214+#: field:easy.reconcile.advanced.transaction_ref,account_id:0
1215+msgid "Account"
1216+msgstr "Compte"
1217+
1218+#. module: account_advanced_reconcile_transaction_ref
1219+#: view:account.easy.reconcile:0
1220+msgid "Advanced. Partner and Transaction Ref"
1221+msgstr "Avancé. Partenaire et Référence de transaction"
1222+
1223+#. module: account_advanced_reconcile_transaction_ref
1224+#: view:account.easy.reconcile:0
1225+msgid ""
1226+"Match multiple debit vs multiple credit entries. Allow partial "
1227+"reconciliation. The lines should have the partner, the credit entry "
1228+"transaction ref. is matched vs the debit entry transaction ref. or name."
1229+msgstr ""
1230+"Le lettrage peut s'effectuer sur plusieurs écritures de débit et crédit. Le "
1231+"Lettrage partiel est autorisé. Les écritures doivent avoir le même "
1232+"partenaire et la même référence de transaction sur les écritures de crédit "
1233+"doit se retrouver dans la référence de transaction ou la description sur les "
1234+"écritures de débit."
1235+
1236+#. module: account_advanced_reconcile_transaction_ref
1237+#: model:ir.model,name:account_advanced_reconcile_transaction_ref.model_easy_reconcile_advanced_transaction_ref
1238+msgid "easy.reconcile.advanced.transaction_ref"
1239+msgstr "easy.reconcile.advanced.transaction_ref"
1240+
1241+#. module: account_advanced_reconcile_transaction_ref
1242+#: field:account.move.line,transaction_ref:0
1243+msgid "Transaction Ref."
1244+msgstr "Réf. de transaction"
1245+
1246+#. module: account_advanced_reconcile_transaction_ref
1247+#: field:easy.reconcile.advanced.transaction_ref,journal_id:0
1248+msgid "Journal"
1249+msgstr "Journal"
1250+
1251+#. module: account_advanced_reconcile_transaction_ref
1252+#: field:easy.reconcile.advanced.transaction_ref,account_profit_id:0
1253+msgid "Account Profit"
1254+msgstr "Compte de produit"
1255+
1256+#. module: account_advanced_reconcile_transaction_ref
1257+#: model:ir.model,name:account_advanced_reconcile_transaction_ref.model_account_bank_statement
1258+msgid "Bank Statement"
1259+msgstr "Relevé bancaire"
1260+
1261+#. module: account_advanced_reconcile_transaction_ref
1262+#: field:easy.reconcile.advanced.transaction_ref,filter:0
1263+msgid "Filter"
1264+msgstr "Filtre"
1265+
1266+#. module: account_advanced_reconcile_transaction_ref
1267+#: model:ir.model,name:account_advanced_reconcile_transaction_ref.model_account_easy_reconcile_method
1268+msgid "reconcile method for account_easy_reconcile"
1269+msgstr "Méthode de lettrage pour le module account_easy_reconcile"
1270+
1271+#. module: account_advanced_reconcile_transaction_ref
1272+#: field:easy.reconcile.advanced.transaction_ref,date_base_on:0
1273+msgid "Date of reconciliation"
1274+msgstr "Date de lettrage"
1275+
1276+#. module: account_advanced_reconcile_transaction_ref
1277+#: model:ir.model,name:account_advanced_reconcile_transaction_ref.model_account_move_line
1278+msgid "Journal Items"
1279+msgstr "Écritures comptables"
1280+
1281+#. module: account_advanced_reconcile_transaction_ref
1282+#: model:ir.model,name:account_advanced_reconcile_transaction_ref.model_easy_reconcile_advanced
1283+msgid "easy.reconcile.advanced"
1284+msgstr "easy.reconcile.advanced"
1285+
1286+#. module: account_advanced_reconcile_transaction_ref
1287+#: field:easy.reconcile.advanced.transaction_ref,account_lost_id:0
1288+msgid "Account Lost"
1289+msgstr "Compte de charge"
1290+
1291+#. module: account_advanced_reconcile_transaction_ref
1292+#: field:easy.reconcile.advanced.transaction_ref,write_off:0
1293+msgid "Write off allowed"
1294+msgstr "Ecart autorisé"
1295
1296=== added directory 'account_easy_reconcile'
1297=== added file 'account_easy_reconcile/__init__.py'
1298--- account_easy_reconcile/__init__.py 1970-01-01 00:00:00 +0000
1299+++ account_easy_reconcile/__init__.py 2014-03-27 09:24:37 +0000
1300@@ -0,0 +1,25 @@
1301+# -*- coding: utf-8 -*-
1302+##############################################################################
1303+#
1304+# Copyright 2012 Camptocamp SA (Guewen Baconnier)
1305+# Copyright (C) 2010 Sébastien Beau
1306+#
1307+# This program is free software: you can redistribute it and/or modify
1308+# it under the terms of the GNU Affero General Public License as
1309+# published by the Free Software Foundation, either version 3 of the
1310+# License, or (at your option) any later version.
1311+#
1312+# This program is distributed in the hope that it will be useful,
1313+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1314+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1315+# GNU Affero General Public License for more details.
1316+#
1317+# You should have received a copy of the GNU Affero General Public License
1318+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1319+#
1320+##############################################################################
1321+
1322+import easy_reconcile
1323+import base_reconciliation
1324+import simple_reconciliation
1325+import easy_reconcile_history
1326
1327=== added file 'account_easy_reconcile/__openerp__.py'
1328--- account_easy_reconcile/__openerp__.py 1970-01-01 00:00:00 +0000
1329+++ account_easy_reconcile/__openerp__.py 2014-03-27 09:24:37 +0000
1330@@ -0,0 +1,66 @@
1331+# -*- coding: utf-8 -*-
1332+##############################################################################
1333+#
1334+# Copyright 2012 Camptocamp SA (Guewen Baconnier)
1335+# Copyright (C) 2010 Sébastien Beau
1336+#
1337+# This program is free software: you can redistribute it and/or modify
1338+# it under the terms of the GNU Affero General Public License as
1339+# published by the Free Software Foundation, either version 3 of the
1340+# License, or (at your option) any later version.
1341+#
1342+# This program is distributed in the hope that it will be useful,
1343+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1344+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1345+# GNU Affero General Public License for more details.
1346+#
1347+# You should have received a copy of the GNU Affero General Public License
1348+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1349+#
1350+##############################################################################
1351+
1352+{
1353+ "name": "Easy Reconcile",
1354+ "version": "1.3.0",
1355+ "depends": ["account"],
1356+ "author": "Akretion,Camptocamp",
1357+ "description": """
1358+Easy Reconcile
1359+==============
1360+
1361+This is a shared work between Akretion and Camptocamp
1362+in order to provide:
1363+ - reconciliation facilities for big volume of transactions
1364+ - setup different profiles of reconciliation by account
1365+ - each profile can use many methods of reconciliation
1366+ - this module is also a base to create others
1367+ reconciliation methods which can plug in the profiles
1368+ - a profile a reconciliation can be run manually
1369+ or by a cron
1370+ - monitoring of reconciliation runs with an history
1371+ which keep track of the reconciled Journal items
1372+
1373+2 simple reconciliation methods are integrated
1374+in this module, the simple reconciliations works
1375+on 2 lines (1 debit / 1 credit) and do not allow
1376+partial reconcilation, they also match on 1 key,
1377+partner or Journal item name.
1378+
1379+You may be interested to install also the
1380+``account_advanced_reconciliation`` module.
1381+This latter add more complex reconciliations,
1382+allows multiple lines and partial.
1383+
1384+""",
1385+ "website": "http://www.akretion.com/",
1386+ "category": "Finance",
1387+ "demo_xml": [],
1388+ "data": ["easy_reconcile.xml",
1389+ "easy_reconcile_history_view.xml",
1390+ "security/ir_rule.xml",
1391+ "security/ir.model.access.csv"],
1392+ 'license': 'AGPL-3',
1393+ "auto_install": False,
1394+ "installable": True,
1395+
1396+}
1397
1398=== added file 'account_easy_reconcile/base_reconciliation.py'
1399--- account_easy_reconcile/base_reconciliation.py 1970-01-01 00:00:00 +0000
1400+++ account_easy_reconcile/base_reconciliation.py 2014-03-27 09:24:37 +0000
1401@@ -0,0 +1,211 @@
1402+# -*- coding: utf-8 -*-
1403+##############################################################################
1404+#
1405+# Copyright 2012-2013 Camptocamp SA (Guewen Baconnier)
1406+# Copyright (C) 2010 Sébastien Beau
1407+#
1408+# This program is free software: you can redistribute it and/or modify
1409+# it under the terms of the GNU Affero General Public License as
1410+# published by the Free Software Foundation, either version 3 of the
1411+# License, or (at your option) any later version.
1412+#
1413+# This program is distributed in the hope that it will be useful,
1414+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1415+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1416+# GNU Affero General Public License for more details.
1417+#
1418+# You should have received a copy of the GNU Affero General Public License
1419+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1420+#
1421+##############################################################################
1422+
1423+from openerp.osv import fields, orm
1424+from operator import itemgetter, attrgetter
1425+
1426+
1427+class easy_reconcile_base(orm.AbstractModel):
1428+ """Abstract Model for reconciliation methods"""
1429+
1430+ _name = 'easy.reconcile.base'
1431+
1432+ _inherit = 'easy.reconcile.options'
1433+
1434+ _columns = {
1435+ 'account_id': fields.many2one(
1436+ 'account.account', 'Account', required=True),
1437+ 'partner_ids': fields.many2many(
1438+ 'res.partner', string="Restrict on partners"),
1439+ # other columns are inherited from easy.reconcile.options
1440+ }
1441+
1442+ def automatic_reconcile(self, cr, uid, ids, context=None):
1443+ """ Reconciliation method called from the view.
1444+
1445+ :return: list of reconciled ids, list of partially reconciled items
1446+ """
1447+ if isinstance(ids, (int, long)):
1448+ ids = [ids]
1449+ assert len(ids) == 1, "Has to be called on one id"
1450+ rec = self.browse(cr, uid, ids[0], context=context)
1451+ return self._action_rec(cr, uid, rec, context=context)
1452+
1453+ def _action_rec(self, cr, uid, rec, context=None):
1454+ """ Must be inherited to implement the reconciliation
1455+
1456+ :return: list of reconciled ids
1457+ """
1458+ raise NotImplementedError
1459+
1460+ def _base_columns(self, rec):
1461+ """ Mandatory columns for move lines queries
1462+ An extra column aliased as ``key`` should be defined
1463+ in each query."""
1464+ aml_cols = (
1465+ 'id',
1466+ 'debit',
1467+ 'credit',
1468+ 'date',
1469+ 'period_id',
1470+ 'ref',
1471+ 'name',
1472+ 'partner_id',
1473+ 'account_id',
1474+ 'move_id')
1475+ return ["account_move_line.%s" % col for col in aml_cols]
1476+
1477+ def _select(self, rec, *args, **kwargs):
1478+ return "SELECT %s" % ', '.join(self._base_columns(rec))
1479+
1480+ def _from(self, rec, *args, **kwargs):
1481+ return "FROM account_move_line"
1482+
1483+ def _where(self, rec, *args, **kwargs):
1484+ where = ("WHERE account_move_line.account_id = %s "
1485+ "AND account_move_line.reconcile_id IS NULL ")
1486+ # it would be great to use dict for params
1487+ # but as we use _where_calc in _get_filter
1488+ # which returns a list, we have to
1489+ # accomodate with that
1490+ params = [rec.account_id.id]
1491+
1492+ if rec.partner_ids:
1493+ where += " AND account_move_line.partner_id IN %s"
1494+ params.append(tuple([l.id for l in rec.partner_ids]))
1495+ return where, params
1496+
1497+ def _get_filter(self, cr, uid, rec, context):
1498+ ml_obj = self.pool.get('account.move.line')
1499+ where = ''
1500+ params = []
1501+ if rec.filter:
1502+ dummy, where, params = ml_obj._where_calc(
1503+ cr, uid, eval(rec.filter), context=context).get_sql()
1504+ if where:
1505+ where = " AND %s" % where
1506+ return where, params
1507+
1508+ def _below_writeoff_limit(self, cr, uid, rec, lines,
1509+ writeoff_limit, context=None):
1510+ precision = self.pool.get('decimal.precision').precision_get(
1511+ cr, uid, 'Account')
1512+ keys = ('debit', 'credit')
1513+ sums = reduce(
1514+ lambda line, memo:
1515+ dict((key, value + memo[key])
1516+ for key, value
1517+ in line.iteritems()
1518+ if key in keys), lines)
1519+
1520+ debit, credit = sums['debit'], sums['credit']
1521+ writeoff_amount = round(debit - credit, precision)
1522+ return bool(writeoff_limit >= abs(writeoff_amount)), debit, credit
1523+
1524+ def _get_rec_date(self, cr, uid, rec, lines,
1525+ based_on='end_period_last_credit', context=None):
1526+ period_obj = self.pool.get('account.period')
1527+
1528+ def last_period(mlines):
1529+ period_ids = [ml['period_id'] for ml in mlines]
1530+ periods = period_obj.browse(
1531+ cr, uid, period_ids, context=context)
1532+ return max(periods, key=attrgetter('date_stop'))
1533+
1534+ def last_date(mlines):
1535+ return max(mlines, key=itemgetter('date'))
1536+
1537+ def credit(mlines):
1538+ return [l for l in mlines if l['credit'] > 0]
1539+
1540+ def debit(mlines):
1541+ return [l for l in mlines if l['debit'] > 0]
1542+
1543+ if based_on == 'end_period_last_credit':
1544+ return last_period(credit(lines)).date_stop
1545+ if based_on == 'end_period':
1546+ return last_period(lines).date_stop
1547+ elif based_on == 'newest':
1548+ return last_date(lines)['date']
1549+ elif based_on == 'newest_credit':
1550+ return last_date(credit(lines))['date']
1551+ elif based_on == 'newest_debit':
1552+ return last_date(debit(lines))['date']
1553+ # reconcilation date will be today
1554+ # when date is None
1555+ return None
1556+
1557+ def _reconcile_lines(self, cr, uid, rec, lines, allow_partial=False, context=None):
1558+ """ Try to reconcile given lines
1559+
1560+ :param list lines: list of dict of move lines, they must at least
1561+ contain values for : id, debit, credit
1562+ :param boolean allow_partial: if True, partial reconciliation will be
1563+ created, otherwise only Full
1564+ reconciliation will be created
1565+ :return: tuple of boolean values, first item is wether the items
1566+ have been reconciled or not,
1567+ the second is wether the reconciliation is full (True)
1568+ or partial (False)
1569+ """
1570+ if context is None:
1571+ context = {}
1572+
1573+ ml_obj = self.pool.get('account.move.line')
1574+ writeoff = rec.write_off
1575+
1576+ line_ids = [l['id'] for l in lines]
1577+ below_writeoff, sum_debit, sum_credit = self._below_writeoff_limit(
1578+ cr, uid, rec, lines, writeoff, context=context)
1579+ date = self._get_rec_date(
1580+ cr, uid, rec, lines, rec.date_base_on, context=context)
1581+
1582+ rec_ctx = dict(context, date_p=date)
1583+ if below_writeoff:
1584+ if sum_credit < sum_debit:
1585+ writeoff_account_id = rec.account_profit_id.id
1586+ else:
1587+ writeoff_account_id = rec.account_lost_id.id
1588+
1589+ period_id = self.pool.get('account.period').find(
1590+ cr, uid, dt=date, context=context)[0]
1591+
1592+ if rec.analytic_account_id:
1593+ rec_ctx['analytic_id'] = rec.analytic_account_id.id
1594+
1595+ ml_obj.reconcile(
1596+ cr, uid,
1597+ line_ids,
1598+ type='auto',
1599+ writeoff_acc_id=writeoff_account_id,
1600+ writeoff_period_id=period_id,
1601+ writeoff_journal_id=rec.journal_id.id,
1602+ context=rec_ctx)
1603+ return True, True
1604+ elif allow_partial:
1605+ ml_obj.reconcile_partial(
1606+ cr, uid,
1607+ line_ids,
1608+ type='manual',
1609+ context=rec_ctx)
1610+ return True, False
1611+
1612+ return False, False
1613
1614=== added file 'account_easy_reconcile/easy_reconcile.py'
1615--- account_easy_reconcile/easy_reconcile.py 1970-01-01 00:00:00 +0000
1616+++ account_easy_reconcile/easy_reconcile.py 2014-03-27 09:24:37 +0000
1617@@ -0,0 +1,290 @@
1618+# -*- coding: utf-8 -*-
1619+##############################################################################
1620+#
1621+# Copyright 2012-2013 Camptocamp SA (Guewen Baconnier)
1622+# Copyright (C) 2010 Sébastien Beau
1623+#
1624+# This program is free software: you can redistribute it and/or modify
1625+# it under the terms of the GNU Affero General Public License as
1626+# published by the Free Software Foundation, either version 3 of the
1627+# License, or (at your option) any later version.
1628+#
1629+# This program is distributed in the hope that it will be useful,
1630+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1631+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1632+# GNU Affero General Public License for more details.
1633+#
1634+# You should have received a copy of the GNU Affero General Public License
1635+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1636+#
1637+##############################################################################
1638+
1639+from openerp.osv import fields, osv, orm
1640+from openerp.tools.translate import _
1641+from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
1642+
1643+
1644+class easy_reconcile_options(orm.AbstractModel):
1645+ """Options of a reconciliation profile
1646+
1647+ Columns shared by the configuration of methods
1648+ and by the reconciliation wizards.
1649+ This allows decoupling of the methods and the
1650+ wizards and allows to launch the wizards alone
1651+ """
1652+
1653+ _name = 'easy.reconcile.options'
1654+
1655+ def _get_rec_base_date(self, cr, uid, context=None):
1656+ return [('end_period_last_credit', 'End of period of most recent credit'),
1657+ ('newest', 'Most recent move line'),
1658+ ('actual', 'Today'),
1659+ ('end_period', 'End of period of most recent move line'),
1660+ ('newest_credit', 'Date of most recent credit'),
1661+ ('newest_debit', 'Date of most recent debit')]
1662+
1663+ _columns = {
1664+ 'write_off': fields.float('Write off allowed'),
1665+ 'account_lost_id': fields.many2one(
1666+ 'account.account', 'Account Lost'),
1667+ 'account_profit_id': fields.many2one(
1668+ 'account.account', 'Account Profit'),
1669+ 'journal_id': fields.many2one(
1670+ 'account.journal', 'Journal'),
1671+ 'date_base_on': fields.selection(
1672+ _get_rec_base_date,
1673+ required=True,
1674+ string='Date of reconciliation'),
1675+ 'filter': fields.char('Filter', size=128),
1676+ 'analytic_account_id': fields.many2one(
1677+ 'account.analytic.account', 'Analytic Account',
1678+ help="Analytic account for the write-off"),
1679+ }
1680+
1681+ _defaults = {
1682+ 'write_off': 0.,
1683+ 'date_base_on': 'end_period_last_credit',
1684+ }
1685+
1686+
1687+class account_easy_reconcile_method(orm.Model):
1688+
1689+ _name = 'account.easy.reconcile.method'
1690+ _description = 'reconcile method for account_easy_reconcile'
1691+
1692+ _inherit = 'easy.reconcile.options'
1693+
1694+ _order = 'sequence'
1695+
1696+ def _get_all_rec_method(self, cr, uid, context=None):
1697+ return [
1698+ ('easy.reconcile.simple.name', 'Simple. Amount and Name'),
1699+ ('easy.reconcile.simple.partner', 'Simple. Amount and Partner'),
1700+ ('easy.reconcile.simple.reference', 'Simple. Amount and Reference'),
1701+ ]
1702+
1703+ def _get_rec_method(self, cr, uid, context=None):
1704+ return self._get_all_rec_method(cr, uid, context=None)
1705+
1706+ _columns = {
1707+ 'name': fields.selection(
1708+ _get_rec_method, 'Type', required=True),
1709+ 'sequence': fields.integer(
1710+ 'Sequence',
1711+ required=True,
1712+ help="The sequence field is used to order "
1713+ "the reconcile method"),
1714+ 'task_id': fields.many2one(
1715+ 'account.easy.reconcile',
1716+ string='Task',
1717+ required=True,
1718+ ondelete='cascade'),
1719+ 'company_id': fields.related('task_id','company_id',
1720+ relation='res.company',
1721+ type='many2one',
1722+ string='Company',
1723+ store=True,
1724+ readonly=True),
1725+ }
1726+
1727+ _defaults = {
1728+ 'sequence': 1,
1729+ }
1730+
1731+ def init(self, cr):
1732+ """ Migration stuff
1733+
1734+ Name is not anymore methods names but the name
1735+ of the model which does the reconciliation
1736+ """
1737+ cr.execute("""
1738+ UPDATE account_easy_reconcile_method
1739+ SET name = 'easy.reconcile.simple.partner'
1740+ WHERE name = 'action_rec_auto_partner'
1741+ """)
1742+ cr.execute("""
1743+ UPDATE account_easy_reconcile_method
1744+ SET name = 'easy.reconcile.simple.name'
1745+ WHERE name = 'action_rec_auto_name'
1746+ """)
1747+
1748+
1749+class account_easy_reconcile(orm.Model):
1750+
1751+ _name = 'account.easy.reconcile'
1752+ _description = 'account easy reconcile'
1753+
1754+ def _get_total_unrec(self, cr, uid, ids, name, arg, context=None):
1755+ obj_move_line = self.pool.get('account.move.line')
1756+ res = {}
1757+ for task in self.browse(cr, uid, ids, context=context):
1758+ res[task.id] = len(obj_move_line.search(
1759+ cr, uid,
1760+ [('account_id', '=', task.account.id),
1761+ ('reconcile_id', '=', False),
1762+ ('reconcile_partial_id', '=', False)],
1763+ context=context))
1764+ return res
1765+
1766+ def _get_partial_rec(self, cr, uid, ids, name, arg, context=None):
1767+ obj_move_line = self.pool.get('account.move.line')
1768+ res = {}
1769+ for task in self.browse(cr, uid, ids, context=context):
1770+ res[task.id] = len(obj_move_line.search(
1771+ cr, uid,
1772+ [('account_id', '=', task.account.id),
1773+ ('reconcile_id', '=', False),
1774+ ('reconcile_partial_id', '!=', False)],
1775+ context=context))
1776+ return res
1777+
1778+ def _last_history(self, cr, uid, ids, name, args, context=None):
1779+ result = {}
1780+ for history in self.browse(cr, uid, ids, context=context):
1781+ result[history.id] = False
1782+ if history.history_ids:
1783+ # history is sorted by date desc
1784+ result[history.id] = history.history_ids[0].id
1785+ return result
1786+
1787+ _columns = {
1788+ 'name': fields.char('Name', required=True),
1789+ 'account': fields.many2one(
1790+ 'account.account', 'Account', required=True),
1791+ 'reconcile_method': fields.one2many(
1792+ 'account.easy.reconcile.method', 'task_id', 'Method'),
1793+ 'unreconciled_count': fields.function(
1794+ _get_total_unrec, type='integer', string='Unreconciled Items'),
1795+ 'reconciled_partial_count': fields.function(
1796+ _get_partial_rec,
1797+ type='integer',
1798+ string='Partially Reconciled Items'),
1799+ 'history_ids': fields.one2many(
1800+ 'easy.reconcile.history',
1801+ 'easy_reconcile_id',
1802+ string='History',
1803+ readonly=True),
1804+ 'last_history':
1805+ fields.function(
1806+ _last_history,
1807+ string='Last History',
1808+ type='many2one',
1809+ relation='easy.reconcile.history',
1810+ readonly=True),
1811+ 'company_id': fields.many2one('res.company', 'Company'),
1812+ }
1813+
1814+ def _prepare_run_transient(self, cr, uid, rec_method, context=None):
1815+ return {'account_id': rec_method.task_id.account.id,
1816+ 'write_off': rec_method.write_off,
1817+ 'account_lost_id': (rec_method.account_lost_id and
1818+ rec_method.account_lost_id.id),
1819+ 'account_profit_id': (rec_method.account_profit_id and
1820+ rec_method.account_profit_id.id),
1821+ 'analytic_account_id': (rec_method.analytic_account_id and
1822+ rec_method.analytic_account_id.id),
1823+ 'journal_id': (rec_method.journal_id and
1824+ rec_method.journal_id.id),
1825+ 'date_base_on': rec_method.date_base_on,
1826+ 'filter': rec_method.filter}
1827+
1828+ def run_reconcile(self, cr, uid, ids, context=None):
1829+ def find_reconcile_ids(fieldname, move_line_ids):
1830+ if not move_line_ids:
1831+ return []
1832+ sql = ("SELECT DISTINCT " + fieldname +
1833+ " FROM account_move_line "
1834+ " WHERE id in %s "
1835+ " AND " + fieldname + " IS NOT NULL")
1836+ cr.execute(sql, (tuple(move_line_ids),))
1837+ res = cr.fetchall()
1838+ return [row[0] for row in res]
1839+
1840+ for rec in self.browse(cr, uid, ids, context=context):
1841+ all_ml_rec_ids = []
1842+ all_ml_partial_ids = []
1843+
1844+ for method in rec.reconcile_method:
1845+ rec_model = self.pool.get(method.name)
1846+ auto_rec_id = rec_model.create(
1847+ cr, uid,
1848+ self._prepare_run_transient(
1849+ cr, uid, method, context=context),
1850+ context=context)
1851+
1852+ ml_rec_ids, ml_partial_ids = rec_model.automatic_reconcile(
1853+ cr, uid, auto_rec_id, context=context)
1854+
1855+ all_ml_rec_ids += ml_rec_ids
1856+ all_ml_partial_ids += ml_partial_ids
1857+
1858+ reconcile_ids = find_reconcile_ids(
1859+ 'reconcile_id', all_ml_rec_ids)
1860+ partial_ids = find_reconcile_ids(
1861+ 'reconcile_partial_id', all_ml_partial_ids)
1862+
1863+ self.pool.get('easy.reconcile.history').create(
1864+ cr,
1865+ uid,
1866+ {'easy_reconcile_id': rec.id,
1867+ 'date': fields.datetime.now(),
1868+ 'reconcile_ids': [(4, rid) for rid in reconcile_ids],
1869+ 'reconcile_partial_ids': [(4, rid) for rid in partial_ids]},
1870+ context=context)
1871+ return True
1872+
1873+ def _no_history(self, cr, uid, rec, context=None):
1874+ """ Raise an `osv.except_osv` error, supposed to
1875+ be called when there is no history on the reconciliation
1876+ task.
1877+ """
1878+ raise osv.except_osv(
1879+ _('Error'),
1880+ _('There is no history of reconciled '
1881+ 'items on the task: %s.') % rec.name)
1882+
1883+ def last_history_reconcile(self, cr, uid, rec_id, context=None):
1884+ """ Get the last history record for this reconciliation profile
1885+ and return the action which opens move lines reconciled
1886+ """
1887+ if isinstance(rec_id, (tuple, list)):
1888+ assert len(rec_id) == 1, \
1889+ "Only 1 id expected"
1890+ rec_id = rec_id[0]
1891+ rec = self.browse(cr, uid, rec_id, context=context)
1892+ if not rec.last_history:
1893+ self._no_history(cr, uid, rec, context=context)
1894+ return rec.last_history.open_reconcile()
1895+
1896+ def last_history_partial(self, cr, uid, rec_id, context=None):
1897+ """ Get the last history record for this reconciliation profile
1898+ and return the action which opens move lines reconciled
1899+ """
1900+ if isinstance(rec_id, (tuple, list)):
1901+ assert len(rec_id) == 1, \
1902+ "Only 1 id expected"
1903+ rec_id = rec_id[0]
1904+ rec = self.browse(cr, uid, rec_id, context=context)
1905+ if not rec.last_history:
1906+ self._no_history(cr, uid, rec, context=context)
1907+ return rec.last_history.open_partial()
1908
1909=== added file 'account_easy_reconcile/easy_reconcile.xml'
1910--- account_easy_reconcile/easy_reconcile.xml 1970-01-01 00:00:00 +0000
1911+++ account_easy_reconcile/easy_reconcile.xml 2014-03-27 09:24:37 +0000
1912@@ -0,0 +1,158 @@
1913+<?xml version="1.0" encoding="UTF-8"?>
1914+<openerp>
1915+<data>
1916+
1917+ <!-- account.easy.reconcile view -->
1918+ <record id="account_easy_reconcile_form" model="ir.ui.view">
1919+ <field name="name">account.easy.reconcile.form</field>
1920+ <field name="priority">20</field>
1921+ <field name="model">account.easy.reconcile</field>
1922+ <field name="arch" type="xml">
1923+ <form string="Automatic Easy Reconcile" version="7.0">
1924+ <header>
1925+ <button name="run_reconcile" class="oe_highlight"
1926+ string="Start Auto Reconciliation" type="object"/>
1927+ <button icon="STOCK_JUMP_TO" name="last_history_reconcile"
1928+ class="oe_highlight"
1929+ string="Display items reconciled on the last run"
1930+ type="object"/>
1931+ <button icon="STOCK_JUMP_TO" name="last_history_partial"
1932+ class="oe_highlight"
1933+ string="Display items partially reconciled on the last run"
1934+ type="object"/>
1935+ </header>
1936+ <sheet>
1937+ <separator colspan="4" string="Profile Information" />
1938+ <group>
1939+ <group>
1940+ <field name="name" select="1"/>
1941+ <field name="account"/>
1942+ <field name="company_id" groups="base.group_multi_company"/>
1943+ </group>
1944+ <group>
1945+ <field name="unreconciled_count"/>
1946+ <field name="reconciled_partial_count"/>
1947+ </group>
1948+ </group>
1949+ <notebook colspan="4">
1950+ <page name="methods" string="Configuration">
1951+ <field name="reconcile_method" colspan = "4" nolabel="1"/>
1952+ </page>
1953+ <page name="history" string="History">
1954+ <field name="history_ids" nolabel="1">
1955+ <tree string="Automatic Easy Reconcile History">
1956+ <field name="date"/>
1957+ <button icon="STOCK_JUMP_TO" name="open_reconcile"
1958+ string="Go to reconciled items" type="object"/>
1959+ <button icon="STOCK_JUMP_TO" name="open_partial"
1960+ string="Go to partially reconciled items" type="object"/>
1961+ </tree>
1962+ </field>
1963+ </page>
1964+ <page name="information" string="Information">
1965+ <separator colspan="4" string="Simple. Amount and Name"/>
1966+ <label string="Match one debit line vs one credit line. Do not allow partial reconciliation.
1967+The lines should have the same amount (with the write-off) and the same name to be reconciled." colspan="4"/>
1968+
1969+ <separator colspan="4" string="Simple. Amount and Partner"/>
1970+ <label string="Match one debit line vs one credit line. Do not allow partial reconciliation.
1971+The lines should have the same amount (with the write-off) and the same partner to be reconciled." colspan="4"/>
1972+
1973+ <separator colspan="4" string="Simple. Amount and Reference"/>
1974+ <label string="Match one debit line vs one credit line. Do not allow partial reconciliation.
1975+The lines should have the same amount (with the write-off) and the same reference to be reconciled." colspan="4"/>
1976+
1977+ </page>
1978+ </notebook>
1979+ </sheet>
1980+ </form>
1981+ </field>
1982+ </record>
1983+
1984+ <record id="account_easy_reconcile_tree" model="ir.ui.view">
1985+ <field name="name">account.easy.reconcile.tree</field>
1986+ <field name="priority">20</field>
1987+ <field name="model">account.easy.reconcile</field>
1988+ <field name="arch" type="xml">
1989+ <tree string="Automatic Easy Reconcile">
1990+ <field name="name"/>
1991+ <field name="account"/>
1992+ <field name="company_id" groups="base.group_multi_company"/>
1993+ <field name="unreconciled_count"/>
1994+ <field name="reconciled_partial_count"/>
1995+ <button icon="gtk-ok" name="run_reconcile" colspan="4"
1996+ string="Start Auto Reconcilation" type="object"/>
1997+ <button icon="STOCK_JUMP_TO" name="last_history_reconcile" colspan="2"
1998+ string="Display items reconciled on the last run" type="object"/>
1999+ <button icon="STOCK_JUMP_TO" name="last_history_partial" colspan="2"
2000+ string="Display items partially reconciled on the last run"
2001+ type="object"/>
2002+ </tree>
2003+ </field>
2004+ </record>
2005+
2006+ <record id="action_account_easy_reconcile" model="ir.actions.act_window">
2007+ <field name="name">Easy Automatic Reconcile</field>
2008+ <field name="type">ir.actions.act_window</field>
2009+ <field name="res_model">account.easy.reconcile</field>
2010+ <field name="view_type">form</field>
2011+ <field name="view_mode">tree,form</field>
2012+ <field name="help" type="html">
2013+ <p class="oe_view_nocontent_create">
2014+ Click to add a reconciliation profile.
2015+ </p><p>
2016+ A reconciliation profile specifies, for one account, how
2017+ the entries should be reconciled.
2018+ You can select one or many reconciliation methods which will
2019+ be run sequentially to match the entries between them.
2020+ </p>
2021+ </field>
2022+ </record>
2023+
2024+
2025+ <!-- account.easy.reconcile.method view -->
2026+
2027+ <record id="account_easy_reconcile_method_form" model="ir.ui.view">
2028+ <field name="name">account.easy.reconcile.method.form</field>
2029+ <field name="priority">20</field>
2030+ <field name="model">account.easy.reconcile.method</field>
2031+ <field name="arch" type="xml">
2032+ <form string="Automatic Easy Reconcile Method">
2033+ <field name="sequence"/>
2034+ <field name="name"/>
2035+ <field name="write_off"/>
2036+ <field name="account_lost_id" attrs="{'required':[('write_off','>',0)]}"/>
2037+ <field name="account_profit_id" attrs="{'required':[('write_off','>',0)]}"/>
2038+ <field name="journal_id" attrs="{'required':[('write_off','>',0)]}"/>
2039+ <field name="analytic_account_id" groups="analytic.group_analytic_accounting"/>
2040+ <field name="date_base_on"/>
2041+ </form>
2042+ </field>
2043+ </record>
2044+
2045+ <record id="account_easy_reconcile_method_tree" model="ir.ui.view">
2046+ <field name="name">account.easy.reconcile.method.tree</field>
2047+ <field name="priority">20</field>
2048+ <field name="model">account.easy.reconcile.method</field>
2049+ <field name="arch" type="xml">
2050+ <tree editable="top" string="Automatic Easy Reconcile Method">
2051+ <field name="sequence"/>
2052+ <field name="name"/>
2053+ <field name="write_off"/>
2054+ <field name="account_lost_id" attrs="{'required':[('write_off','>',0)]}"/>
2055+ <field name="account_profit_id" attrs="{'required':[('write_off','>',0)]}"/>
2056+ <field name="journal_id" attrs="{'required':[('write_off','>',0)]}"/>
2057+ <field name="analytic_account_id" groups="analytic.group_analytic_accounting"/>
2058+ <field name="date_base_on"/>
2059+ </tree>
2060+ </field>
2061+ </record>
2062+
2063+ <!-- menu item -->
2064+
2065+ <menuitem action="action_account_easy_reconcile"
2066+ id="menu_easy_reconcile"
2067+ parent="account.periodical_processing_reconciliation"/>
2068+
2069+</data>
2070+</openerp>
2071
2072=== added file 'account_easy_reconcile/easy_reconcile_history.py'
2073--- account_easy_reconcile/easy_reconcile_history.py 1970-01-01 00:00:00 +0000
2074+++ account_easy_reconcile/easy_reconcile_history.py 2014-03-27 09:24:37 +0000
2075@@ -0,0 +1,153 @@
2076+# -*- coding: utf-8 -*-
2077+##############################################################################
2078+#
2079+# Author: Guewen Baconnier
2080+# Copyright 2012 Camptocamp SA
2081+#
2082+# This program is free software: you can redistribute it and/or modify
2083+# it under the terms of the GNU Affero General Public License as
2084+# published by the Free Software Foundation, either version 3 of the
2085+# License, or (at your option) any later version.
2086+#
2087+# This program is distributed in the hope that it will be useful,
2088+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2089+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2090+# GNU Affero General Public License for more details.
2091+#
2092+# You should have received a copy of the GNU Affero General Public License
2093+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2094+#
2095+##############################################################################
2096+
2097+from openerp.osv import orm, fields
2098+from openerp.tools.translate import _
2099+
2100+
2101+class easy_reconcile_history(orm.Model):
2102+ """ Store an history of the runs per profile
2103+ Each history stores the list of reconciliations done"""
2104+
2105+ _name = 'easy.reconcile.history'
2106+ _rec_name = 'easy_reconcile_id'
2107+ _order = 'date DESC'
2108+
2109+ def _reconcile_line_ids(self, cr, uid, ids, name, args, context=None):
2110+ result = {}
2111+
2112+ for history in self.browse(cr, uid, ids, context=context):
2113+ result[history.id] = {}
2114+
2115+ move_line_ids = []
2116+ for reconcile in history.reconcile_ids:
2117+ move_line_ids += [line.id
2118+ for line
2119+ in reconcile.line_id]
2120+ result[history.id]['reconcile_line_ids'] = move_line_ids
2121+
2122+ move_line_ids = []
2123+ for reconcile in history.reconcile_partial_ids:
2124+ move_line_ids += [line.id
2125+ for line
2126+ in reconcile.line_partial_ids]
2127+ result[history.id]['partial_line_ids'] = move_line_ids
2128+
2129+ return result
2130+
2131+ _columns = {
2132+ 'easy_reconcile_id': fields.many2one(
2133+ 'account.easy.reconcile', 'Reconcile Profile', readonly=True),
2134+ 'date': fields.datetime('Run date', readonly=True),
2135+ 'reconcile_ids': fields.many2many(
2136+ 'account.move.reconcile',
2137+ 'account_move_reconcile_history_rel',
2138+ string='Reconciliations', readonly=True),
2139+ 'reconcile_partial_ids': fields.many2many(
2140+ 'account.move.reconcile',
2141+ 'account_move_reconcile_history_partial_rel',
2142+ string='Partial Reconciliations', readonly=True),
2143+ 'reconcile_line_ids':
2144+ fields.function(
2145+ _reconcile_line_ids,
2146+ string='Reconciled Items',
2147+ type='many2many',
2148+ relation='account.move.line',
2149+ readonly=True,
2150+ multi='lines'),
2151+ 'partial_line_ids':
2152+ fields.function(
2153+ _reconcile_line_ids,
2154+ string='Partially Reconciled Items',
2155+ type='many2many',
2156+ relation='account.move.line',
2157+ readonly=True,
2158+ multi='lines'),
2159+ 'company_id': fields.related('easy_reconcile_id','company_id',
2160+ relation='res.company',
2161+ type='many2one',
2162+ string='Company',
2163+ store=True,
2164+ readonly=True),
2165+
2166+ }
2167+
2168+ def _open_move_lines(self, cr, uid, history_id, rec_type='full', context=None):
2169+ """ For an history record, open the view of move line with
2170+ the reconciled or partially reconciled move lines
2171+
2172+ :param history_id: id of the history
2173+ :param rec_type: 'full' or 'partial'
2174+ :return: action to open the move lines
2175+ """
2176+ assert rec_type in ('full', 'partial'), \
2177+ "rec_type must be 'full' or 'partial'"
2178+
2179+ history = self.browse(cr, uid, history_id, context=context)
2180+
2181+ if rec_type == 'full':
2182+ field = 'reconcile_line_ids'
2183+ name = _('Reconciliations')
2184+ else:
2185+ field = 'partial_line_ids'
2186+ name = _('Partial Reconciliations')
2187+
2188+ move_line_ids = [line.id for line in getattr(history, field)]
2189+
2190+ return {
2191+ 'name': name,
2192+ 'view_mode': 'tree,form',
2193+ 'view_id': False,
2194+ 'view_type': 'form',
2195+ 'res_model': 'account.move.line',
2196+ 'type': 'ir.actions.act_window',
2197+ 'nodestroy': True,
2198+ 'target': 'current',
2199+ 'domain': unicode([('id', 'in', move_line_ids)]),
2200+ }
2201+
2202+ def open_reconcile(self, cr, uid, history_ids, context=None):
2203+ """ For an history record, open the view of move line
2204+ with the reconciled move lines
2205+
2206+ :param history_ids: id of the record as int or long
2207+ Accept a list with 1 id too to be
2208+ used from the client.
2209+ """
2210+ if isinstance(history_ids, (tuple, list)):
2211+ assert len(history_ids) == 1, "only 1 ID is accepted"
2212+ history_ids = history_ids[0]
2213+ return self._open_move_lines(
2214+ cr, uid, history_ids, rec_type='full', context=None)
2215+
2216+ def open_partial(self, cr, uid, history_ids, context=None):
2217+ """ For an history record, open the view of move line
2218+ with the partially reconciled move lines
2219+
2220+ :param history_ids: id of the record as int or long
2221+ Accept a list with 1 id too to be
2222+ used from the client.
2223+ """
2224+ if isinstance(history_ids, (tuple, list)):
2225+ assert len(history_ids) == 1, "only 1 ID is accepted"
2226+ history_ids = history_ids[0]
2227+ return self._open_move_lines(
2228+ cr, uid, history_ids, rec_type='partial', context=None)
2229
2230=== added file 'account_easy_reconcile/easy_reconcile_history_view.xml'
2231--- account_easy_reconcile/easy_reconcile_history_view.xml 1970-01-01 00:00:00 +0000
2232+++ account_easy_reconcile/easy_reconcile_history_view.xml 2014-03-27 09:24:37 +0000
2233@@ -0,0 +1,98 @@
2234+<?xml version="1.0" encoding="utf-8"?>
2235+<openerp>
2236+ <data noupdate="0">
2237+
2238+ <record id="view_easy_reconcile_history_search" model="ir.ui.view">
2239+ <field name="name">easy.reconcile.history.search</field>
2240+ <field name="model">easy.reconcile.history</field>
2241+ <field name="arch" type="xml">
2242+ <search string="Automatic Easy Reconcile History">
2243+ <filter icon="terp-go-today" string="Today"
2244+ domain="[('date','&lt;', time.strftime('%%Y-%%m-%%d 23:59:59')), ('date','&gt;=', time.strftime('%%Y-%%m-%%d 00:00:00'))]"
2245+ help="Todays' Reconcilations" />
2246+ <filter icon="terp-go-week" string="7 Days"
2247+ help="Reconciliations of last 7 days"
2248+ domain="[('date','&lt;', time.strftime('%%Y-%%m-%%d 23:59:59')),('date','&gt;=',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d 00:00:00'))]"
2249+ />
2250+
2251+ <separator orientation="vertical"/>
2252+ <field name="easy_reconcile_id"/>
2253+ <field name="date"/>
2254+
2255+ <newline/>
2256+ <group expand="0" string="Group By...">
2257+ <filter string="Reconciliation Profile"
2258+ icon="terp-stock_effects-object-colorize"
2259+ domain="[]" context="{'group_by': 'easy_reconcile_id'}"/>
2260+ <filter string="Date" icon="terp-go-month" domain="[]"
2261+ context="{'group_by': 'date'}"/>
2262+ </group>
2263+ </search>
2264+ </field>
2265+ </record>
2266+
2267+ <record id="easy_reconcile_history_form" model="ir.ui.view">
2268+ <field name="name">easy.reconcile.history.form</field>
2269+ <field name="model">easy.reconcile.history</field>
2270+ <field name="arch" type="xml">
2271+ <form string="Automatic Easy Reconcile History" version="7.0">
2272+ <header>
2273+ <button name="open_reconcile"
2274+ string="Go to reconciled items"
2275+ icon="STOCK_JUMP_TO" type="object"/>
2276+ <button name="open_partial"
2277+ string="Go to partially reconciled items"
2278+ icon="STOCK_JUMP_TO" type="object"/>
2279+ </header>
2280+ <sheet>
2281+ <group>
2282+ <field name="easy_reconcile_id"/>
2283+ <field name="date"/>
2284+ <field name="company_id" groups="base.group_multi_company"/>
2285+ </group>
2286+ <group col="2">
2287+ <separator colspan="2" string="Reconciliations"/>
2288+ <field name="reconcile_ids" nolabel="1"/>
2289+ </group>
2290+ <group col="2">
2291+ <separator colspan="2" string="Partial Reconciliations"/>
2292+ <field name="reconcile_partial_ids" nolabel="1"/>
2293+ </group>
2294+ </sheet>
2295+ </form>
2296+ </field>
2297+ </record>
2298+
2299+ <record id="easy_reconcile_history_tree" model="ir.ui.view">
2300+ <field name="name">easy.reconcile.history.tree</field>
2301+ <field name="model">easy.reconcile.history</field>
2302+ <field name="arch" type="xml">
2303+ <tree string="Automatic Easy Reconcile History">
2304+ <field name="easy_reconcile_id"/>
2305+ <field name="date"/>
2306+ <button icon="STOCK_JUMP_TO" name="open_reconcile"
2307+ string="Go to reconciled items" type="object"/>
2308+ <button icon="STOCK_JUMP_TO" name="open_partial"
2309+ string="Go to partially reconciled items" type="object"/>
2310+ </tree>
2311+ </field>
2312+ </record>
2313+
2314+ <record id="action_easy_reconcile_history" model="ir.actions.act_window">
2315+ <field name="name">Easy Automatic Reconcile History</field>
2316+ <field name="type">ir.actions.act_window</field>
2317+ <field name="res_model">easy.reconcile.history</field>
2318+ <field name="view_type">form</field>
2319+ <field name="view_mode">tree,form</field>
2320+ </record>
2321+
2322+ <act_window
2323+ context="{'search_default_easy_reconcile_id': [active_id], 'default_easy_reconcile_id': active_id}"
2324+ id="act_easy_reconcile_to_history"
2325+ name="History Details"
2326+ groups=""
2327+ res_model="easy.reconcile.history"
2328+ src_model="account.easy.reconcile"/>
2329+
2330+ </data>
2331+</openerp>
2332
2333=== added directory 'account_easy_reconcile/i18n'
2334=== added file 'account_easy_reconcile/i18n/account_easy_reconcile.pot'
2335--- account_easy_reconcile/i18n/account_easy_reconcile.pot 1970-01-01 00:00:00 +0000
2336+++ account_easy_reconcile/i18n/account_easy_reconcile.pot 2014-03-27 09:24:37 +0000
2337@@ -0,0 +1,406 @@
2338+# Translation of OpenERP Server.
2339+# This file contains the translation of the following modules:
2340+# * account_easy_reconcile
2341+#
2342+msgid ""
2343+msgstr ""
2344+"Project-Id-Version: OpenERP Server 7.0\n"
2345+"Report-Msgid-Bugs-To: \n"
2346+"POT-Creation-Date: 2014-01-21 11:55+0000\n"
2347+"PO-Revision-Date: 2014-01-21 11:55+0000\n"
2348+"Last-Translator: <>\n"
2349+"Language-Team: \n"
2350+"MIME-Version: 1.0\n"
2351+"Content-Type: text/plain; charset=UTF-8\n"
2352+"Content-Transfer-Encoding: \n"
2353+"Plural-Forms: \n"
2354+
2355+#. module: account_easy_reconcile
2356+#: code:addons/account_easy_reconcile/easy_reconcile_history.py:108
2357+#: view:easy.reconcile.history:0
2358+#: field:easy.reconcile.history,reconcile_ids:0
2359+#, python-format
2360+msgid "Reconciliations"
2361+msgstr ""
2362+
2363+#. module: account_easy_reconcile
2364+#: view:account.easy.reconcile:0
2365+#: view:easy.reconcile.history:0
2366+msgid "Automatic Easy Reconcile History"
2367+msgstr ""
2368+
2369+#. module: account_easy_reconcile
2370+#: view:account.easy.reconcile:0
2371+msgid "Information"
2372+msgstr ""
2373+
2374+#. module: account_easy_reconcile
2375+#: view:account.easy.reconcile:0
2376+#: view:easy.reconcile.history:0
2377+msgid "Go to partially reconciled items"
2378+msgstr ""
2379+
2380+#. module: account_easy_reconcile
2381+#: help:account.easy.reconcile.method,sequence:0
2382+msgid "The sequence field is used to order the reconcile method"
2383+msgstr ""
2384+
2385+#. module: account_easy_reconcile
2386+#: model:ir.model,name:account_easy_reconcile.model_easy_reconcile_history
2387+msgid "easy.reconcile.history"
2388+msgstr ""
2389+
2390+#. module: account_easy_reconcile
2391+#: model:ir.actions.act_window,help:account_easy_reconcile.action_account_easy_reconcile
2392+msgid "<p class=\"oe_view_nocontent_create\">\n"
2393+" Click to add a reconciliation profile.\n"
2394+" </p><p>\n"
2395+" A reconciliation profile specifies, for one account, how\n"
2396+" the entries should be reconciled.\n"
2397+" You can select one or many reconciliation methods which will\n"
2398+" be run sequentially to match the entries between them.\n"
2399+" </p>\n"
2400+" "
2401+msgstr ""
2402+
2403+#. module: account_easy_reconcile
2404+#: model:ir.model,name:account_easy_reconcile.model_easy_reconcile_options
2405+msgid "easy.reconcile.options"
2406+msgstr ""
2407+
2408+#. module: account_easy_reconcile
2409+#: view:easy.reconcile.history:0
2410+msgid "Group By..."
2411+msgstr ""
2412+
2413+#. module: account_easy_reconcile
2414+#: field:account.easy.reconcile,unreconciled_count:0
2415+msgid "Unreconciled Items"
2416+msgstr ""
2417+
2418+#. module: account_easy_reconcile
2419+#: model:ir.model,name:account_easy_reconcile.model_easy_reconcile_base
2420+msgid "easy.reconcile.base"
2421+msgstr ""
2422+
2423+#. module: account_easy_reconcile
2424+#: field:easy.reconcile.history,reconcile_line_ids:0
2425+msgid "Reconciled Items"
2426+msgstr ""
2427+
2428+#. module: account_easy_reconcile
2429+#: field:account.easy.reconcile,reconcile_method:0
2430+msgid "Method"
2431+msgstr ""
2432+
2433+#. module: account_easy_reconcile
2434+#: view:easy.reconcile.history:0
2435+msgid "7 Days"
2436+msgstr ""
2437+
2438+#. module: account_easy_reconcile
2439+#: model:ir.actions.act_window,name:account_easy_reconcile.action_easy_reconcile_history
2440+msgid "Easy Automatic Reconcile History"
2441+msgstr ""
2442+
2443+#. module: account_easy_reconcile
2444+#: field:easy.reconcile.history,date:0
2445+msgid "Run date"
2446+msgstr ""
2447+
2448+#. module: account_easy_reconcile
2449+#: view:account.easy.reconcile:0
2450+msgid "Match one debit line vs one credit line. Do not allow partial reconciliation. The lines should have the same amount (with the write-off) and the same reference to be reconciled."
2451+msgstr ""
2452+
2453+#. module: account_easy_reconcile
2454+#: model:ir.actions.act_window,name:account_easy_reconcile.act_easy_reconcile_to_history
2455+msgid "History Details"
2456+msgstr ""
2457+
2458+#. module: account_easy_reconcile
2459+#: view:account.easy.reconcile:0
2460+msgid "Display items reconciled on the last run"
2461+msgstr ""
2462+
2463+#. module: account_easy_reconcile
2464+#: field:account.easy.reconcile.method,name:0
2465+msgid "Type"
2466+msgstr ""
2467+
2468+#. module: account_easy_reconcile
2469+#: field:account.easy.reconcile,company_id:0
2470+#: field:account.easy.reconcile.method,company_id:0
2471+#: field:easy.reconcile.history,company_id:0
2472+msgid "Company"
2473+msgstr ""
2474+
2475+#. module: account_easy_reconcile
2476+#: field:account.easy.reconcile.method,account_profit_id:0
2477+#: field:easy.reconcile.base,account_profit_id:0
2478+#: field:easy.reconcile.options,account_profit_id:0
2479+#: field:easy.reconcile.simple,account_profit_id:0
2480+#: field:easy.reconcile.simple.name,account_profit_id:0
2481+#: field:easy.reconcile.simple.partner,account_profit_id:0
2482+#: field:easy.reconcile.simple.reference,account_profit_id:0
2483+msgid "Account Profit"
2484+msgstr ""
2485+
2486+#. module: account_easy_reconcile
2487+#: view:easy.reconcile.history:0
2488+msgid "Todays' Reconcilations"
2489+msgstr ""
2490+
2491+#. module: account_easy_reconcile
2492+#: view:account.easy.reconcile:0
2493+msgid "Simple. Amount and Name"
2494+msgstr ""
2495+
2496+#. module: account_easy_reconcile
2497+#: field:easy.reconcile.base,partner_ids:0
2498+#: field:easy.reconcile.simple,partner_ids:0
2499+#: field:easy.reconcile.simple.name,partner_ids:0
2500+#: field:easy.reconcile.simple.partner,partner_ids:0
2501+#: field:easy.reconcile.simple.reference,partner_ids:0
2502+msgid "Restrict on partners"
2503+msgstr ""
2504+
2505+#. module: account_easy_reconcile
2506+#: model:ir.actions.act_window,name:account_easy_reconcile.action_account_easy_reconcile
2507+#: model:ir.ui.menu,name:account_easy_reconcile.menu_easy_reconcile
2508+msgid "Easy Automatic Reconcile"
2509+msgstr ""
2510+
2511+#. module: account_easy_reconcile
2512+#: view:easy.reconcile.history:0
2513+msgid "Today"
2514+msgstr ""
2515+
2516+#. module: account_easy_reconcile
2517+#: view:easy.reconcile.history:0
2518+msgid "Date"
2519+msgstr ""
2520+
2521+#. module: account_easy_reconcile
2522+#: field:account.easy.reconcile,last_history:0
2523+msgid "Last History"
2524+msgstr ""
2525+
2526+#. module: account_easy_reconcile
2527+#: view:account.easy.reconcile:0
2528+msgid "Configuration"
2529+msgstr ""
2530+
2531+#. module: account_easy_reconcile
2532+#: field:account.easy.reconcile,reconciled_partial_count:0
2533+#: field:easy.reconcile.history,partial_line_ids:0
2534+msgid "Partially Reconciled Items"
2535+msgstr ""
2536+
2537+#. module: account_easy_reconcile
2538+#: model:ir.model,name:account_easy_reconcile.model_easy_reconcile_simple_partner
2539+msgid "easy.reconcile.simple.partner"
2540+msgstr ""
2541+
2542+#. module: account_easy_reconcile
2543+#: field:account.easy.reconcile.method,write_off:0
2544+#: field:easy.reconcile.base,write_off:0
2545+#: field:easy.reconcile.options,write_off:0
2546+#: field:easy.reconcile.simple,write_off:0
2547+#: field:easy.reconcile.simple.name,write_off:0
2548+#: field:easy.reconcile.simple.partner,write_off:0
2549+#: field:easy.reconcile.simple.reference,write_off:0
2550+msgid "Write off allowed"
2551+msgstr ""
2552+
2553+#. module: account_easy_reconcile
2554+#: view:account.easy.reconcile:0
2555+msgid "Automatic Easy Reconcile"
2556+msgstr ""
2557+
2558+#. module: account_easy_reconcile
2559+#: field:account.easy.reconcile,account:0
2560+#: field:easy.reconcile.base,account_id:0
2561+#: field:easy.reconcile.simple,account_id:0
2562+#: field:easy.reconcile.simple.name,account_id:0
2563+#: field:easy.reconcile.simple.partner,account_id:0
2564+#: field:easy.reconcile.simple.reference,account_id:0
2565+msgid "Account"
2566+msgstr ""
2567+
2568+#. module: account_easy_reconcile
2569+#: field:account.easy.reconcile.method,task_id:0
2570+msgid "Task"
2571+msgstr ""
2572+
2573+#. module: account_easy_reconcile
2574+#: field:account.easy.reconcile,name:0
2575+msgid "Name"
2576+msgstr ""
2577+
2578+#. module: account_easy_reconcile
2579+#: view:account.easy.reconcile:0
2580+msgid "Simple. Amount and Partner"
2581+msgstr ""
2582+
2583+#. module: account_easy_reconcile
2584+#: view:account.easy.reconcile:0
2585+msgid "Start Auto Reconcilation"
2586+msgstr ""
2587+
2588+#. module: account_easy_reconcile
2589+#: model:ir.model,name:account_easy_reconcile.model_easy_reconcile_simple_name
2590+msgid "easy.reconcile.simple.name"
2591+msgstr ""
2592+
2593+#. module: account_easy_reconcile
2594+#: field:account.easy.reconcile.method,filter:0
2595+#: field:easy.reconcile.base,filter:0
2596+#: field:easy.reconcile.options,filter:0
2597+#: field:easy.reconcile.simple,filter:0
2598+#: field:easy.reconcile.simple.name,filter:0
2599+#: field:easy.reconcile.simple.partner,filter:0
2600+#: field:easy.reconcile.simple.reference,filter:0
2601+msgid "Filter"
2602+msgstr ""
2603+
2604+#. module: account_easy_reconcile
2605+#: view:account.easy.reconcile:0
2606+msgid "Match one debit line vs one credit line. Do not allow partial reconciliation. The lines should have the same amount (with the write-off) and the same partner to be reconciled."
2607+msgstr ""
2608+
2609+#. module: account_easy_reconcile
2610+#: field:easy.reconcile.history,easy_reconcile_id:0
2611+msgid "Reconcile Profile"
2612+msgstr ""
2613+
2614+#. module: account_easy_reconcile
2615+#: model:ir.model,name:account_easy_reconcile.model_account_easy_reconcile_method
2616+msgid "reconcile method for account_easy_reconcile"
2617+msgstr ""
2618+
2619+#. module: account_easy_reconcile
2620+#: view:account.easy.reconcile:0
2621+msgid "Start Auto Reconciliation"
2622+msgstr ""
2623+
2624+#. module: account_easy_reconcile
2625+#: code:addons/account_easy_reconcile/easy_reconcile.py:257
2626+#, python-format
2627+msgid "Error"
2628+msgstr ""
2629+
2630+#. module: account_easy_reconcile
2631+#: code:addons/account_easy_reconcile/easy_reconcile.py:258
2632+#, python-format
2633+msgid "There is no history of reconciled items on the task: %s."
2634+msgstr ""
2635+
2636+#. module: account_easy_reconcile
2637+#: view:account.easy.reconcile:0
2638+msgid "Match one debit line vs one credit line. Do not allow partial reconciliation. The lines should have the same amount (with the write-off) and the same name to be reconciled."
2639+msgstr ""
2640+
2641+#. module: account_easy_reconcile
2642+#: field:account.easy.reconcile.method,account_lost_id:0
2643+#: field:easy.reconcile.base,account_lost_id:0
2644+#: field:easy.reconcile.options,account_lost_id:0
2645+#: field:easy.reconcile.simple,account_lost_id:0
2646+#: field:easy.reconcile.simple.name,account_lost_id:0
2647+#: field:easy.reconcile.simple.partner,account_lost_id:0
2648+#: field:easy.reconcile.simple.reference,account_lost_id:0
2649+msgid "Account Lost"
2650+msgstr ""
2651+
2652+#. module: account_easy_reconcile
2653+#: view:easy.reconcile.history:0
2654+msgid "Reconciliation Profile"
2655+msgstr ""
2656+
2657+#. module: account_easy_reconcile
2658+#: view:account.easy.reconcile:0
2659+#: field:account.easy.reconcile,history_ids:0
2660+msgid "History"
2661+msgstr ""
2662+
2663+#. module: account_easy_reconcile
2664+#: view:account.easy.reconcile:0
2665+#: view:easy.reconcile.history:0
2666+msgid "Go to reconciled items"
2667+msgstr ""
2668+
2669+#. module: account_easy_reconcile
2670+#: view:account.easy.reconcile:0
2671+msgid "Profile Information"
2672+msgstr ""
2673+
2674+#. module: account_easy_reconcile
2675+#: view:account.easy.reconcile.method:0
2676+msgid "Automatic Easy Reconcile Method"
2677+msgstr ""
2678+
2679+#. module: account_easy_reconcile
2680+#: view:account.easy.reconcile:0
2681+msgid "Simple. Amount and Reference"
2682+msgstr ""
2683+
2684+#. module: account_easy_reconcile
2685+#: view:account.easy.reconcile:0
2686+msgid "Display items partially reconciled on the last run"
2687+msgstr ""
2688+
2689+#. module: account_easy_reconcile
2690+#: field:account.easy.reconcile.method,sequence:0
2691+msgid "Sequence"
2692+msgstr ""
2693+
2694+#. module: account_easy_reconcile
2695+#: model:ir.model,name:account_easy_reconcile.model_easy_reconcile_simple
2696+msgid "easy.reconcile.simple"
2697+msgstr ""
2698+
2699+#. module: account_easy_reconcile
2700+#: view:easy.reconcile.history:0
2701+msgid "Reconciliations of last 7 days"
2702+msgstr ""
2703+
2704+#. module: account_easy_reconcile
2705+#: field:account.easy.reconcile.method,date_base_on:0
2706+#: field:easy.reconcile.base,date_base_on:0
2707+#: field:easy.reconcile.options,date_base_on:0
2708+#: field:easy.reconcile.simple,date_base_on:0
2709+#: field:easy.reconcile.simple.name,date_base_on:0
2710+#: field:easy.reconcile.simple.partner,date_base_on:0
2711+#: field:easy.reconcile.simple.reference,date_base_on:0
2712+msgid "Date of reconciliation"
2713+msgstr ""
2714+
2715+#. module: account_easy_reconcile
2716+#: code:addons/account_easy_reconcile/easy_reconcile_history.py:111
2717+#: view:easy.reconcile.history:0
2718+#: field:easy.reconcile.history,reconcile_partial_ids:0
2719+#, python-format
2720+msgid "Partial Reconciliations"
2721+msgstr ""
2722+
2723+#. module: account_easy_reconcile
2724+#: field:account.easy.reconcile.method,journal_id:0
2725+#: field:easy.reconcile.base,journal_id:0
2726+#: field:easy.reconcile.options,journal_id:0
2727+#: field:easy.reconcile.simple,journal_id:0
2728+#: field:easy.reconcile.simple.name,journal_id:0
2729+#: field:easy.reconcile.simple.partner,journal_id:0
2730+#: field:easy.reconcile.simple.reference,journal_id:0
2731+msgid "Journal"
2732+msgstr ""
2733+
2734+#. module: account_easy_reconcile
2735+#: model:ir.model,name:account_easy_reconcile.model_easy_reconcile_simple_reference
2736+msgid "easy.reconcile.simple.reference"
2737+msgstr ""
2738+
2739+#. module: account_easy_reconcile
2740+#: model:ir.model,name:account_easy_reconcile.model_account_easy_reconcile
2741+msgid "account easy reconcile"
2742+msgstr ""
2743+
2744
2745=== added file 'account_easy_reconcile/i18n/fr.po'
2746--- account_easy_reconcile/i18n/fr.po 1970-01-01 00:00:00 +0000
2747+++ account_easy_reconcile/i18n/fr.po 2014-03-27 09:24:37 +0000
2748@@ -0,0 +1,432 @@
2749+# Translation of OpenERP Server.
2750+# This file contains the translation of the following modules:
2751+# * account_easy_reconcile
2752+#
2753+msgid ""
2754+msgstr ""
2755+"Project-Id-Version: OpenERP Server 6.1\n"
2756+"Report-Msgid-Bugs-To: \n"
2757+"POT-Creation-Date: 2014-01-21 11:55+0000\n"
2758+"PO-Revision-Date: 2014-03-21 15:25+0000\n"
2759+"Last-Translator: Guewen Baconnier @ Camptocamp <Unknown>\n"
2760+"Language-Team: \n"
2761+"MIME-Version: 1.0\n"
2762+"Content-Type: text/plain; charset=UTF-8\n"
2763+"Content-Transfer-Encoding: 8bit\n"
2764+"X-Launchpad-Export-Date: 2014-03-22 07:11+0000\n"
2765+"X-Generator: Launchpad (build 16967)\n"
2766+"Language: \n"
2767+
2768+#. module: account_easy_reconcile
2769+#: code:addons/account_easy_reconcile/easy_reconcile_history.py:108
2770+#: view:easy.reconcile.history:0
2771+#: field:easy.reconcile.history,reconcile_ids:0
2772+#, python-format
2773+msgid "Reconciliations"
2774+msgstr "Lettrages"
2775+
2776+#. module: account_easy_reconcile
2777+#: view:account.easy.reconcile:0
2778+#: view:easy.reconcile.history:0
2779+msgid "Automatic Easy Reconcile History"
2780+msgstr "Historique des lettrages automatisés"
2781+
2782+#. module: account_easy_reconcile
2783+#: view:account.easy.reconcile:0
2784+msgid "Information"
2785+msgstr "Information"
2786+
2787+#. module: account_easy_reconcile
2788+#: view:account.easy.reconcile:0
2789+#: view:easy.reconcile.history:0
2790+msgid "Go to partially reconciled items"
2791+msgstr "Voir les entrées partiellement lettrées"
2792+
2793+#. module: account_easy_reconcile
2794+#: help:account.easy.reconcile.method,sequence:0
2795+msgid "The sequence field is used to order the reconcile method"
2796+msgstr "La séquence détermine l'ordre des méthodes de lettrage"
2797+
2798+#. module: account_easy_reconcile
2799+#: model:ir.model,name:account_easy_reconcile.model_easy_reconcile_history
2800+msgid "easy.reconcile.history"
2801+msgstr "easy.reconcile.history"
2802+
2803+#. module: account_easy_reconcile
2804+#: model:ir.actions.act_window,help:account_easy_reconcile.action_account_easy_reconcile
2805+msgid ""
2806+"<p class=\"oe_view_nocontent_create\">\n"
2807+" Click to add a reconciliation profile.\n"
2808+" </p><p>\n"
2809+" A reconciliation profile specifies, for one account, how\n"
2810+" the entries should be reconciled.\n"
2811+" You can select one or many reconciliation methods which will\n"
2812+" be run sequentially to match the entries between them.\n"
2813+" </p>\n"
2814+" "
2815+msgstr ""
2816+"<p class=\"oe_view_nocontent_create\">\n"
2817+" Cliquez pour ajouter un profil de lettrage.\n"
2818+" </p><p>\n"
2819+" Un profil de lettrage spécifie, pour un compte, comment\n"
2820+" les écritures doivent être lettrées.\n"
2821+" Vous pouvez sélectionner une ou plusieurs méthodes de lettrage\n"
2822+" qui seront lancées successivement pour identifier les écritures\n"
2823+" devant être lettrées. </p>\n"
2824+" "
2825+
2826+#. module: account_easy_reconcile
2827+#: model:ir.model,name:account_easy_reconcile.model_easy_reconcile_options
2828+msgid "easy.reconcile.options"
2829+msgstr "easy.reconcile.options"
2830+
2831+#. module: account_easy_reconcile
2832+#: view:easy.reconcile.history:0
2833+msgid "Group By..."
2834+msgstr "Grouper par..."
2835+
2836+#. module: account_easy_reconcile
2837+#: field:account.easy.reconcile,unreconciled_count:0
2838+msgid "Unreconciled Items"
2839+msgstr "Écritures non lettrées"
2840+
2841+#. module: account_easy_reconcile
2842+#: model:ir.model,name:account_easy_reconcile.model_easy_reconcile_base
2843+msgid "easy.reconcile.base"
2844+msgstr "easy.reconcile.base"
2845+
2846+#. module: account_easy_reconcile
2847+#: field:easy.reconcile.history,reconcile_line_ids:0
2848+msgid "Reconciled Items"
2849+msgstr "Écritures lettrées"
2850+
2851+#. module: account_easy_reconcile
2852+#: field:account.easy.reconcile,reconcile_method:0
2853+msgid "Method"
2854+msgstr "Méthode"
2855+
2856+#. module: account_easy_reconcile
2857+#: view:easy.reconcile.history:0
2858+msgid "7 Days"
2859+msgstr "7 jours"
2860+
2861+#. module: account_easy_reconcile
2862+#: model:ir.actions.act_window,name:account_easy_reconcile.action_easy_reconcile_history
2863+msgid "Easy Automatic Reconcile History"
2864+msgstr "Lettrage automatisé"
2865+
2866+#. module: account_easy_reconcile
2867+#: field:easy.reconcile.history,date:0
2868+msgid "Run date"
2869+msgstr "Date de lancement"
2870+
2871+#. module: account_easy_reconcile
2872+#: view:account.easy.reconcile:0
2873+msgid ""
2874+"Match one debit line vs one credit line. Do not allow partial "
2875+"reconciliation. The lines should have the same amount (with the write-off) "
2876+"and the same reference to be reconciled."
2877+msgstr ""
2878+"Lettre un débit avec un crédit ayant le même montant et la même référence. "
2879+"Le lettrage ne peut être partiel (écriture d'ajustement en cas d'écart)."
2880+
2881+#. module: account_easy_reconcile
2882+#: model:ir.actions.act_window,name:account_easy_reconcile.act_easy_reconcile_to_history
2883+msgid "History Details"
2884+msgstr "Détails de l'historique"
2885+
2886+#. module: account_easy_reconcile
2887+#: view:account.easy.reconcile:0
2888+msgid "Display items reconciled on the last run"
2889+msgstr "Voir les entrées lettrées au dernier lettrage"
2890+
2891+#. module: account_easy_reconcile
2892+#: field:account.easy.reconcile.method,name:0
2893+msgid "Type"
2894+msgstr "Type"
2895+
2896+#. module: account_easy_reconcile
2897+#: field:account.easy.reconcile,company_id:0
2898+#: field:account.easy.reconcile.method,company_id:0
2899+#: field:easy.reconcile.history,company_id:0
2900+msgid "Company"
2901+msgstr ""
2902+
2903+#. module: account_easy_reconcile
2904+#: field:account.easy.reconcile.method,account_profit_id:0
2905+#: field:easy.reconcile.base,account_profit_id:0
2906+#: field:easy.reconcile.options,account_profit_id:0
2907+#: field:easy.reconcile.simple,account_profit_id:0
2908+#: field:easy.reconcile.simple.name,account_profit_id:0
2909+#: field:easy.reconcile.simple.partner,account_profit_id:0
2910+#: field:easy.reconcile.simple.reference,account_profit_id:0
2911+msgid "Account Profit"
2912+msgstr "Compte de profits"
2913+
2914+#. module: account_easy_reconcile
2915+#: view:easy.reconcile.history:0
2916+msgid "Todays' Reconcilations"
2917+msgstr "Lettrages du jour"
2918+
2919+#. module: account_easy_reconcile
2920+#: view:account.easy.reconcile:0
2921+msgid "Simple. Amount and Name"
2922+msgstr "Simple. Montant et description"
2923+
2924+#. module: account_easy_reconcile
2925+#: field:easy.reconcile.base,partner_ids:0
2926+#: field:easy.reconcile.simple,partner_ids:0
2927+#: field:easy.reconcile.simple.name,partner_ids:0
2928+#: field:easy.reconcile.simple.partner,partner_ids:0
2929+#: field:easy.reconcile.simple.reference,partner_ids:0
2930+msgid "Restrict on partners"
2931+msgstr "Filtrer sur des partenaires"
2932+
2933+#. module: account_easy_reconcile
2934+#: model:ir.actions.act_window,name:account_easy_reconcile.action_account_easy_reconcile
2935+#: model:ir.ui.menu,name:account_easy_reconcile.menu_easy_reconcile
2936+msgid "Easy Automatic Reconcile"
2937+msgstr "Lettrage automatisé"
2938+
2939+#. module: account_easy_reconcile
2940+#: view:easy.reconcile.history:0
2941+msgid "Today"
2942+msgstr "Aujourd'hui"
2943+
2944+#. module: account_easy_reconcile
2945+#: view:easy.reconcile.history:0
2946+msgid "Date"
2947+msgstr "Date"
2948+
2949+#. module: account_easy_reconcile
2950+#: field:account.easy.reconcile,last_history:0
2951+msgid "Last History"
2952+msgstr "Dernier historique"
2953+
2954+#. module: account_easy_reconcile
2955+#: view:account.easy.reconcile:0
2956+msgid "Configuration"
2957+msgstr "Configuration"
2958+
2959+#. module: account_easy_reconcile
2960+#: field:account.easy.reconcile,reconciled_partial_count:0
2961+#: field:easy.reconcile.history,partial_line_ids:0
2962+msgid "Partially Reconciled Items"
2963+msgstr "Écritures partiellement lettrées"
2964+
2965+#. module: account_easy_reconcile
2966+#: model:ir.model,name:account_easy_reconcile.model_easy_reconcile_simple_partner
2967+msgid "easy.reconcile.simple.partner"
2968+msgstr "easy.reconcile.simple.partner"
2969+
2970+#. module: account_easy_reconcile
2971+#: field:account.easy.reconcile.method,write_off:0
2972+#: field:easy.reconcile.base,write_off:0
2973+#: field:easy.reconcile.options,write_off:0
2974+#: field:easy.reconcile.simple,write_off:0
2975+#: field:easy.reconcile.simple.name,write_off:0
2976+#: field:easy.reconcile.simple.partner,write_off:0
2977+#: field:easy.reconcile.simple.reference,write_off:0
2978+msgid "Write off allowed"
2979+msgstr "Écart autorisé"
2980+
2981+#. module: account_easy_reconcile
2982+#: view:account.easy.reconcile:0
2983+msgid "Automatic Easy Reconcile"
2984+msgstr "Lettrage automatisé"
2985+
2986+#. module: account_easy_reconcile
2987+#: field:account.easy.reconcile,account:0
2988+#: field:easy.reconcile.base,account_id:0
2989+#: field:easy.reconcile.simple,account_id:0
2990+#: field:easy.reconcile.simple.name,account_id:0
2991+#: field:easy.reconcile.simple.partner,account_id:0
2992+#: field:easy.reconcile.simple.reference,account_id:0
2993+msgid "Account"
2994+msgstr "Compte"
2995+
2996+#. module: account_easy_reconcile
2997+#: field:account.easy.reconcile.method,task_id:0
2998+msgid "Task"
2999+msgstr "Tâche"
3000+
3001+#. module: account_easy_reconcile
3002+#: field:account.easy.reconcile,name:0
3003+msgid "Name"
3004+msgstr "Nom"
3005+
3006+#. module: account_easy_reconcile
3007+#: view:account.easy.reconcile:0
3008+msgid "Simple. Amount and Partner"
3009+msgstr "Simple. Montant et partenaire"
3010+
3011+#. module: account_easy_reconcile
3012+#: view:account.easy.reconcile:0
3013+msgid "Start Auto Reconcilation"
3014+msgstr "Lancer le lettrage automatisé"
3015+
3016+#. module: account_easy_reconcile
3017+#: model:ir.model,name:account_easy_reconcile.model_easy_reconcile_simple_name
3018+msgid "easy.reconcile.simple.name"
3019+msgstr "easy.reconcile.simple.name"
3020+
3021+#. module: account_easy_reconcile
3022+#: field:account.easy.reconcile.method,filter:0
3023+#: field:easy.reconcile.base,filter:0
3024+#: field:easy.reconcile.options,filter:0
3025+#: field:easy.reconcile.simple,filter:0
3026+#: field:easy.reconcile.simple.name,filter:0
3027+#: field:easy.reconcile.simple.partner,filter:0
3028+#: field:easy.reconcile.simple.reference,filter:0
3029+msgid "Filter"
3030+msgstr "Filtre"
3031+
3032+#. module: account_easy_reconcile
3033+#: view:account.easy.reconcile:0
3034+msgid ""
3035+"Match one debit line vs one credit line. Do not allow partial "
3036+"reconciliation. The lines should have the same amount (with the write-off) "
3037+"and the same partner to be reconciled."
3038+msgstr ""
3039+"Lettre un débit avec un crédit ayant le même montant et le même partenaire. "
3040+"Le lettrage ne peut être partiel (écriture d'ajustement en cas d'écart)."
3041+
3042+#. module: account_easy_reconcile
3043+#: field:easy.reconcile.history,easy_reconcile_id:0
3044+msgid "Reconcile Profile"
3045+msgstr "Profil de réconciliation"
3046+
3047+#. module: account_easy_reconcile
3048+#: model:ir.model,name:account_easy_reconcile.model_account_easy_reconcile_method
3049+msgid "reconcile method for account_easy_reconcile"
3050+msgstr "Méthode de lettrage"
3051+
3052+#. module: account_easy_reconcile
3053+#: view:account.easy.reconcile:0
3054+msgid "Start Auto Reconciliation"
3055+msgstr "Lancer le lettrage automatisé"
3056+
3057+#. module: account_easy_reconcile
3058+#: code:addons/account_easy_reconcile/easy_reconcile.py:257
3059+#, python-format
3060+msgid "Error"
3061+msgstr "Erreur"
3062+
3063+#. module: account_easy_reconcile
3064+#: code:addons/account_easy_reconcile/easy_reconcile.py:258
3065+#, python-format
3066+msgid "There is no history of reconciled items on the task: %s."
3067+msgstr "Il n'y a pas d'historique d'écritures lettrées sur la tâche: %s."
3068+
3069+#. module: account_easy_reconcile
3070+#: view:account.easy.reconcile:0
3071+msgid ""
3072+"Match one debit line vs one credit line. Do not allow partial "
3073+"reconciliation. The lines should have the same amount (with the write-off) "
3074+"and the same name to be reconciled."
3075+msgstr ""
3076+"Lettre un débit avec un crédit ayant le même montant et la même description. "
3077+"Le lettrage ne peut être partiel (écriture d'ajustement en cas d'écart)."
3078+
3079+#. module: account_easy_reconcile
3080+#: field:account.easy.reconcile.method,account_lost_id:0
3081+#: field:easy.reconcile.base,account_lost_id:0
3082+#: field:easy.reconcile.options,account_lost_id:0
3083+#: field:easy.reconcile.simple,account_lost_id:0
3084+#: field:easy.reconcile.simple.name,account_lost_id:0
3085+#: field:easy.reconcile.simple.partner,account_lost_id:0
3086+#: field:easy.reconcile.simple.reference,account_lost_id:0
3087+msgid "Account Lost"
3088+msgstr "Compte de pertes"
3089+
3090+#. module: account_easy_reconcile
3091+#: view:easy.reconcile.history:0
3092+msgid "Reconciliation Profile"
3093+msgstr "Profil de réconciliation"
3094+
3095+#. module: account_easy_reconcile
3096+#: view:account.easy.reconcile:0
3097+#: field:account.easy.reconcile,history_ids:0
3098+msgid "History"
3099+msgstr "Historique"
3100+
3101+#. module: account_easy_reconcile
3102+#: view:account.easy.reconcile:0
3103+#: view:easy.reconcile.history:0
3104+msgid "Go to reconciled items"
3105+msgstr "Voir les entrées lettrées"
3106+
3107+#. module: account_easy_reconcile
3108+#: view:account.easy.reconcile:0
3109+msgid "Profile Information"
3110+msgstr "Information sur le profil"
3111+
3112+#. module: account_easy_reconcile
3113+#: view:account.easy.reconcile.method:0
3114+msgid "Automatic Easy Reconcile Method"
3115+msgstr "Méthode de lettrage automatisé"
3116+
3117+#. module: account_easy_reconcile
3118+#: view:account.easy.reconcile:0
3119+msgid "Simple. Amount and Reference"
3120+msgstr "Simple. Montant et référence"
3121+
3122+#. module: account_easy_reconcile
3123+#: view:account.easy.reconcile:0
3124+msgid "Display items partially reconciled on the last run"
3125+msgstr "Afficher les entrées partiellement lettrées au dernier lettrage"
3126+
3127+#. module: account_easy_reconcile
3128+#: field:account.easy.reconcile.method,sequence:0
3129+msgid "Sequence"
3130+msgstr "Séquence"
3131+
3132+#. module: account_easy_reconcile
3133+#: model:ir.model,name:account_easy_reconcile.model_easy_reconcile_simple
3134+msgid "easy.reconcile.simple"
3135+msgstr "easy.reconcile.simple"
3136+
3137+#. module: account_easy_reconcile
3138+#: view:easy.reconcile.history:0
3139+msgid "Reconciliations of last 7 days"
3140+msgstr "Lettrages des 7 derniers jours"
3141+
3142+#. module: account_easy_reconcile
3143+#: field:account.easy.reconcile.method,date_base_on:0
3144+#: field:easy.reconcile.base,date_base_on:0
3145+#: field:easy.reconcile.options,date_base_on:0
3146+#: field:easy.reconcile.simple,date_base_on:0
3147+#: field:easy.reconcile.simple.name,date_base_on:0
3148+#: field:easy.reconcile.simple.partner,date_base_on:0
3149+#: field:easy.reconcile.simple.reference,date_base_on:0
3150+msgid "Date of reconciliation"
3151+msgstr "Date de lettrage"
3152+
3153+#. module: account_easy_reconcile
3154+#: code:addons/account_easy_reconcile/easy_reconcile_history.py:111
3155+#: view:easy.reconcile.history:0
3156+#: field:easy.reconcile.history,reconcile_partial_ids:0
3157+#, python-format
3158+msgid "Partial Reconciliations"
3159+msgstr "Lettrages partiels"
3160+
3161+#. module: account_easy_reconcile
3162+#: field:account.easy.reconcile.method,journal_id:0
3163+#: field:easy.reconcile.base,journal_id:0
3164+#: field:easy.reconcile.options,journal_id:0
3165+#: field:easy.reconcile.simple,journal_id:0
3166+#: field:easy.reconcile.simple.name,journal_id:0
3167+#: field:easy.reconcile.simple.partner,journal_id:0
3168+#: field:easy.reconcile.simple.reference,journal_id:0
3169+msgid "Journal"
3170+msgstr "Journal"
3171+
3172+#. module: account_easy_reconcile
3173+#: model:ir.model,name:account_easy_reconcile.model_easy_reconcile_simple_reference
3174+msgid "easy.reconcile.simple.reference"
3175+msgstr "easy.reconcile.simple.reference"
3176+
3177+#. module: account_easy_reconcile
3178+#: model:ir.model,name:account_easy_reconcile.model_account_easy_reconcile
3179+msgid "account easy reconcile"
3180+msgstr "Lettrage automatisé"
3181
3182=== added directory 'account_easy_reconcile/security'
3183=== added file 'account_easy_reconcile/security/ir.model.access.csv'
3184--- account_easy_reconcile/security/ir.model.access.csv 1970-01-01 00:00:00 +0000
3185+++ account_easy_reconcile/security/ir.model.access.csv 2014-03-27 09:24:37 +0000
3186@@ -0,0 +1,15 @@
3187+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
3188+access_easy_reconcile_options_acc_user,easy.reconcile.options,model_easy_reconcile_options,account.group_account_user,1,0,0,0
3189+access_account_easy_reconcile_method_acc_user,account.easy.reconcile.method,model_account_easy_reconcile_method,account.group_account_user,1,0,0,0
3190+access_account_easy_reconcile_acc_user,account.easy.reconcile,model_account_easy_reconcile,account.group_account_user,1,1,0,0
3191+access_easy_reconcile_simple_name_acc_user,easy.reconcile.simple.name,model_easy_reconcile_simple_name,account.group_account_user,1,0,0,0
3192+access_easy_reconcile_simple_partner_acc_user,easy.reconcile.simple.partner,model_easy_reconcile_simple_partner,account.group_account_user,1,0,0,0
3193+access_easy_reconcile_simple_reference_acc_user,easy.reconcile.simple.reference,model_easy_reconcile_simple_reference,account.group_account_user,1,0,0,0
3194+access_easy_reconcile_options_acc_mgr,easy.reconcile.options,model_easy_reconcile_options,account.group_account_user,1,0,0,0
3195+access_account_easy_reconcile_method_acc_mgr,account.easy.reconcile.method,model_account_easy_reconcile_method,account.group_account_user,1,1,1,1
3196+access_account_easy_reconcile_acc_mgr,account.easy.reconcile,model_account_easy_reconcile,account.group_account_user,1,1,1,1
3197+access_easy_reconcile_simple_name_acc_mgr,easy.reconcile.simple.name,model_easy_reconcile_simple_name,account.group_account_user,1,0,0,0
3198+access_easy_reconcile_simple_partner_acc_mgr,easy.reconcile.simple.partner,model_easy_reconcile_simple_partner,account.group_account_user,1,0,0,0
3199+access_easy_reconcile_simple_reference_acc_mgr,easy.reconcile.simple.reference,model_easy_reconcile_simple_reference,account.group_account_user,1,0,0,0
3200+access_easy_reconcile_history_acc_user,easy.reconcile.history,model_easy_reconcile_history,account.group_account_user,1,1,1,0
3201+access_easy_reconcile_history_acc_mgr,easy.reconcile.history,model_easy_reconcile_history,account.group_account_manager,1,1,1,1
3202
3203=== added file 'account_easy_reconcile/security/ir_rule.xml'
3204--- account_easy_reconcile/security/ir_rule.xml 1970-01-01 00:00:00 +0000
3205+++ account_easy_reconcile/security/ir_rule.xml 2014-03-27 09:24:37 +0000
3206@@ -0,0 +1,25 @@
3207+<?xml version="1.0" encoding="utf-8"?>
3208+<openerp>
3209+ <data noupdate="1">
3210+ <record id="easy_reconcile_rule" model="ir.rule">
3211+ <field name="name">Easy reconcile multi-company</field>
3212+ <field name="model_id" ref="model_account_easy_reconcile"/>
3213+ <field name="global" eval="True"/>
3214+ <field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])]</field>
3215+ </record>
3216+
3217+ <record id="easy_reconcile_history_rule" model="ir.rule">
3218+ <field name="name">Easy reconcile history multi-company</field>
3219+ <field name="model_id" ref="model_easy_reconcile_history"/>
3220+ <field name="global" eval="True"/>
3221+ <field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])]</field>
3222+ </record>
3223+
3224+ <record id="easy_reconcile_method_rule" model="ir.rule">
3225+ <field name="name">Easy reconcile method multi-company</field>
3226+ <field name="model_id" ref="model_account_easy_reconcile_method"/>
3227+ <field name="global" eval="True"/>
3228+ <field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])]</field>
3229+ </record>
3230+ </data>
3231+</openerp>
3232
3233=== added file 'account_easy_reconcile/simple_reconciliation.py'
3234--- account_easy_reconcile/simple_reconciliation.py 1970-01-01 00:00:00 +0000
3235+++ account_easy_reconcile/simple_reconciliation.py 2014-03-27 09:24:37 +0000
3236@@ -0,0 +1,120 @@
3237+# -*- coding: utf-8 -*-
3238+##############################################################################
3239+#
3240+# Copyright 2012-2013 Camptocamp SA (Guewen Baconnier)
3241+# Copyright (C) 2010 Sébastien Beau
3242+#
3243+# This program is free software: you can redistribute it and/or modify
3244+# it under the terms of the GNU Affero General Public License as
3245+# published by the Free Software Foundation, either version 3 of the
3246+# License, or (at your option) any later version.
3247+#
3248+# This program is distributed in the hope that it will be useful,
3249+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3250+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3251+# GNU Affero General Public License for more details.
3252+#
3253+# You should have received a copy of the GNU Affero General Public License
3254+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3255+#
3256+##############################################################################
3257+
3258+from openerp.osv.orm import AbstractModel, TransientModel
3259+
3260+
3261+class easy_reconcile_simple(AbstractModel):
3262+
3263+ _name = 'easy.reconcile.simple'
3264+ _inherit = 'easy.reconcile.base'
3265+
3266+ # has to be subclassed
3267+ # field name used as key for matching the move lines
3268+ _key_field = None
3269+
3270+ def rec_auto_lines_simple(self, cr, uid, rec, lines, context=None):
3271+ if context is None:
3272+ context = {}
3273+
3274+ if self._key_field is None:
3275+ raise ValueError("_key_field has to be defined")
3276+
3277+ count = 0
3278+ res = []
3279+ while (count < len(lines)):
3280+ for i in xrange(count+1, len(lines)):
3281+ writeoff_account_id = False
3282+ if lines[count][self._key_field] != lines[i][self._key_field]:
3283+ break
3284+
3285+ check = False
3286+ if lines[count]['credit'] > 0 and lines[i]['debit'] > 0:
3287+ credit_line = lines[count]
3288+ debit_line = lines[i]
3289+ check = True
3290+ elif lines[i]['credit'] > 0 and lines[count]['debit'] > 0:
3291+ credit_line = lines[i]
3292+ debit_line = lines[count]
3293+ check = True
3294+ if not check:
3295+ continue
3296+
3297+ reconciled, dummy = self._reconcile_lines(
3298+ cr, uid, rec, [credit_line, debit_line],
3299+ allow_partial=False, context=context)
3300+ if reconciled:
3301+ res += [credit_line['id'], debit_line['id']]
3302+ del lines[i]
3303+ break
3304+ count += 1
3305+ return res, [] # empty list for partial, only full rec in "simple" rec
3306+
3307+ def _simple_order(self, rec, *args, **kwargs):
3308+ return "ORDER BY account_move_line.%s" % self._key_field
3309+
3310+ def _action_rec(self, cr, uid, rec, context=None):
3311+ """Match only 2 move lines, do not allow partial reconcile"""
3312+ select = self._select(rec)
3313+ select += ", account_move_line.%s " % self._key_field
3314+ where, params = self._where(rec)
3315+ where += " AND account_move_line.%s IS NOT NULL " % self._key_field
3316+
3317+ where2, params2 = self._get_filter(cr, uid, rec, context=context)
3318+ query = ' '.join((
3319+ select,
3320+ self._from(rec),
3321+ where, where2,
3322+ self._simple_order(rec)))
3323+
3324+ cr.execute(query, params + params2)
3325+ lines = cr.dictfetchall()
3326+ return self.rec_auto_lines_simple(cr, uid, rec, lines, context)
3327+
3328+
3329+class easy_reconcile_simple_name(TransientModel):
3330+
3331+ _name = 'easy.reconcile.simple.name'
3332+ _inherit = 'easy.reconcile.simple'
3333+
3334+ # has to be subclassed
3335+ # field name used as key for matching the move lines
3336+ _key_field = 'name'
3337+
3338+
3339+class easy_reconcile_simple_partner(TransientModel):
3340+
3341+ _name = 'easy.reconcile.simple.partner'
3342+ _inherit = 'easy.reconcile.simple'
3343+
3344+ # has to be subclassed
3345+ # field name used as key for matching the move lines
3346+ _key_field = 'partner_id'
3347+
3348+
3349+class easy_reconcile_simple_reference(TransientModel):
3350+
3351+ _name = 'easy.reconcile.simple.reference'
3352+ _inherit = 'easy.reconcile.simple'
3353+
3354+ # has to be subclassed
3355+ # field name used as key for matching the move lines
3356+ _key_field = 'ref'
3357
3358=== added directory 'account_statement_bankaccount_completion'
3359=== added file 'account_statement_bankaccount_completion/__init__.py'
3360--- account_statement_bankaccount_completion/__init__.py 1970-01-01 00:00:00 +0000
3361+++ account_statement_bankaccount_completion/__init__.py 2014-03-27 09:24:37 +0000
3362@@ -0,0 +1,21 @@
3363+# -*- coding: utf-8 -*-
3364+#
3365+#
3366+# Author: Laurent Mignon
3367+# Copyright 2013 'ACSONE SA/NV'
3368+#
3369+# This program is free software: you can redistribute it and/or modify
3370+# it under the terms of the GNU Affero General Public License as
3371+# published by the Free Software Foundation, either version 3 of the
3372+# License, or (at your option) any later version.
3373+#
3374+# This program is distributed in the hope that it will be useful,
3375+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3376+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3377+# GNU Affero General Public License for more details.
3378+#
3379+# You should have received a copy of the GNU Affero General Public License
3380+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3381+#
3382+#
3383+import statement
3384
3385=== added file 'account_statement_bankaccount_completion/__openerp__.py'
3386--- account_statement_bankaccount_completion/__openerp__.py 1970-01-01 00:00:00 +0000
3387+++ account_statement_bankaccount_completion/__openerp__.py 2014-03-27 09:24:37 +0000
3388@@ -0,0 +1,48 @@
3389+# -*- coding: utf-8 -*-
3390+#
3391+#
3392+# Author: Laurent Mignon
3393+# Copyright 2013 'ACSONE SA/NV'
3394+#
3395+# This program is free software: you can redistribute it and/or modify
3396+# it under the terms of the GNU Affero General Public License as
3397+# published by the Free Software Foundation, either version 3 of the
3398+# License, or (at your option) any later version.
3399+#
3400+# This program is distributed in the hope that it will be useful,
3401+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3402+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3403+# GNU Affero General Public License for more details.
3404+#
3405+# You should have received a copy of the GNU Affero General Public License
3406+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3407+#
3408+#
3409+
3410+{'name': "Bank statement completion from bank account number",
3411+ 'version': '1.0.1',
3412+ 'author': 'ACSONE SA/NV',
3413+ 'maintainer': 'ACSONE SA/NV',
3414+ 'category': 'Finance',
3415+ 'complexity': 'normal',
3416+ 'depends': [
3417+ 'account_statement_base_completion',
3418+ ],
3419+ 'description': """
3420+ Add a completion method based on the partner bank account number
3421+ provided by the bank/office.
3422+
3423+ Completion will look in the partner with that bank account number
3424+ to match the partner, then it will fill in the bank statement line
3425+ with it to ease the reconciliation.
3426+
3427+ """,
3428+ 'website': 'http://www.acsone.eu',
3429+ 'data': [
3430+ "data.xml",
3431+ ],
3432+ 'demo': [],
3433+ 'installable': True,
3434+ 'auto_install': False,
3435+ 'license': 'AGPL-3',
3436+ }
3437
3438=== added file 'account_statement_bankaccount_completion/data.xml'
3439--- account_statement_bankaccount_completion/data.xml 1970-01-01 00:00:00 +0000
3440+++ account_statement_bankaccount_completion/data.xml 2014-03-27 09:24:37 +0000
3441@@ -0,0 +1,12 @@
3442+<?xml version="1.0" encoding="utf-8"?>
3443+<openerp>
3444+<data noupdate="1">
3445+
3446+ <record id="bank_statement_completion_rule_10" model="account.statement.completion.rule">
3447+ <field name="name">Match from bank account number (Normal or IBAN))</field>
3448+ <field name="sequence">10</field>
3449+ <field name="function_to_call">get_from_bank_account</field>
3450+ </record>
3451+
3452+</data>
3453+</openerp>
3454
3455=== added directory 'account_statement_bankaccount_completion/i18n'
3456=== added file 'account_statement_bankaccount_completion/i18n/account_statement_bankaccount_completion.pot'
3457--- account_statement_bankaccount_completion/i18n/account_statement_bankaccount_completion.pot 1970-01-01 00:00:00 +0000
3458+++ account_statement_bankaccount_completion/i18n/account_statement_bankaccount_completion.pot 2014-03-27 09:24:37 +0000
3459@@ -0,0 +1,43 @@
3460+# Translation of OpenERP Server.
3461+# This file contains the translation of the following modules:
3462+# * account_statement_bankaccount_completion
3463+#
3464+msgid ""
3465+msgstr ""
3466+"Project-Id-Version: OpenERP Server 7.0\n"
3467+"Report-Msgid-Bugs-To: \n"
3468+"POT-Creation-Date: 2014-01-21 11:57+0000\n"
3469+"PO-Revision-Date: 2014-01-21 11:57+0000\n"
3470+"Last-Translator: <>\n"
3471+"Language-Team: \n"
3472+"MIME-Version: 1.0\n"
3473+"Content-Type: text/plain; charset=UTF-8\n"
3474+"Content-Transfer-Encoding: \n"
3475+"Plural-Forms: \n"
3476+
3477+#. module: account_statement_bankaccount_completion
3478+#: help:account.bank.statement.line,partner_acc_number:0
3479+msgid "Account number of the partner"
3480+msgstr ""
3481+
3482+#. module: account_statement_bankaccount_completion
3483+#: model:ir.model,name:account_statement_bankaccount_completion.model_account_bank_statement_line
3484+msgid "Bank Statement Line"
3485+msgstr ""
3486+
3487+#. module: account_statement_bankaccount_completion
3488+#: code:addons/account_statement_bankaccount_completion/statement.py:68
3489+#, python-format
3490+msgid "Line named \"%s\" (Ref:%s) was matched by more than one partner for account number \"%s\"."
3491+msgstr ""
3492+
3493+#. module: account_statement_bankaccount_completion
3494+#: field:account.bank.statement.line,partner_acc_number:0
3495+msgid "Account Number"
3496+msgstr ""
3497+
3498+#. module: account_statement_bankaccount_completion
3499+#: model:ir.model,name:account_statement_bankaccount_completion.model_account_statement_completion_rule
3500+msgid "account.statement.completion.rule"
3501+msgstr ""
3502+
3503
3504=== added file 'account_statement_bankaccount_completion/statement.py'
3505--- account_statement_bankaccount_completion/statement.py 1970-01-01 00:00:00 +0000
3506+++ account_statement_bankaccount_completion/statement.py 2014-03-27 09:24:37 +0000
3507@@ -0,0 +1,96 @@
3508+# -*- coding: utf-8 -*-
3509+#
3510+#
3511+# Author: Laurent Mignon
3512+# Copyright 2013 'ACSONE SA/NV'
3513+#
3514+# This program is free software: you can redistribute it and/or modify
3515+# it under the terms of the GNU Affero General Public License as
3516+# published by the Free Software Foundation, either version 3 of the
3517+# License, or (at your option) any later version.
3518+#
3519+# This program is distributed in the hope that it will be useful,
3520+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3521+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3522+# GNU Affero General Public License for more details.
3523+#
3524+# You should have received a copy of the GNU Affero General Public License
3525+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3526+#
3527+#
3528+
3529+
3530+from openerp.tools.translate import _
3531+from openerp.osv.orm import Model
3532+from openerp.osv import fields
3533+from openerp.addons.account_statement_base_completion.statement import ErrorTooManyPartner
3534+
3535+
3536+class AccountStatementCompletionRule(Model):
3537+ """Add a rule based on transaction ID"""
3538+
3539+ _inherit = "account.statement.completion.rule"
3540+
3541+ def _get_functions(self, cr, uid, context=None):
3542+ res = super(AccountStatementCompletionRule, self)._get_functions(
3543+ cr, uid, context=context)
3544+ res.append(('get_from_bank_account',
3545+ 'From bank account number (Normal or IBAN)'))
3546+ return res
3547+
3548+ _columns = {
3549+ 'function_to_call': fields.selection(_get_functions, 'Method'),
3550+ }
3551+
3552+ def get_from_bank_account(self, cr, uid, st_line, context=None):
3553+ """
3554+ Match the partner based on the partner account number field
3555+ Then, call the generic st_line method to complete other values.
3556+ :param dict st_line: read of the concerned account.bank.statement.line
3557+ :return:
3558+ A dict of value that can be passed directly to the write method of
3559+ the statement line or {}
3560+ {'partner_id': value,
3561+ 'account_id' : value,
3562+ ...}
3563+ """
3564+ partner_acc_number = st_line['partner_acc_number']
3565+ if not partner_acc_number:
3566+ return {}
3567+ st_obj = self.pool.get('account.bank.statement.line')
3568+ res = {}
3569+ res_bank_obj = self.pool.get('res.partner.bank')
3570+ ids = res_bank_obj.search(cr,
3571+ uid,
3572+ [('acc_number', '=', partner_acc_number)],
3573+ context=context)
3574+ if len(ids) > 1:
3575+ raise ErrorTooManyPartner(_('Line named "%s" (Ref:%s) was matched by more than '
3576+ 'one partner for account number "%s".') % (st_line['name'], st_line['ref'], partner_acc_number))
3577+ if len(ids) == 1:
3578+ partner = res_bank_obj.browse(cr, uid, ids[0], context=context).partner_id
3579+ res['partner_id'] = partner.id
3580+ st_vals = st_obj.get_values_for_line(cr,
3581+ uid,
3582+ profile_id=st_line['profile_id'],
3583+ master_account_id=st_line['master_account_id'],
3584+ partner_id=res.get('partner_id', False),
3585+ line_type=st_line['type'],
3586+ amount=st_line['amount'] if st_line['amount'] else 0.0,
3587+ context=context)
3588+ res.update(st_vals)
3589+ return res
3590+
3591+
3592+class AccountStatementLine(Model):
3593+ _inherit = "account.bank.statement.line"
3594+
3595+ _columns = {
3596+ # 'additional_bank_fields' : fields.serialized('Additional infos from bank', help="Used by completion and import system."),
3597+ 'partner_acc_number': fields.sparse(
3598+ type='char',
3599+ string='Account Number',
3600+ size=64,
3601+ serialization_field='additionnal_bank_fields',
3602+ help="Account number of the partner"),
3603+ }
3604
3605=== added directory 'account_statement_bankaccount_completion/tests'
3606=== added file 'account_statement_bankaccount_completion/tests/__init__.py'
3607--- account_statement_bankaccount_completion/tests/__init__.py 1970-01-01 00:00:00 +0000
3608+++ account_statement_bankaccount_completion/tests/__init__.py 2014-03-27 09:24:37 +0000
3609@@ -0,0 +1,27 @@
3610+# -*- coding: utf-8 -*-
3611+#
3612+#
3613+# Authors: Laurent Mignon
3614+# Copyright (c) 2013 Acsone SA/NV (http://www.acsone.eu)
3615+# All Rights Reserved
3616+#
3617+# This program is free software: you can redistribute it and/or modify
3618+# it under the terms of the GNU Affero General Public License as
3619+# published by the Free Software Foundation, either version 3 of the
3620+# License, or (at your option) any later version.
3621+#
3622+# This program is distributed in the hope that it will be useful,
3623+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3624+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3625+# GNU Affero General Public License for more details.
3626+#
3627+# You should have received a copy of the GNU Affero General Public License
3628+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3629+#
3630+#
3631+
3632+from . import test_bankaccount_completion
3633+
3634+checks = [
3635+ test_bankaccount_completion
3636+]
3637
3638=== added file 'account_statement_bankaccount_completion/tests/test_bankaccount_completion.py'
3639--- account_statement_bankaccount_completion/tests/test_bankaccount_completion.py 1970-01-01 00:00:00 +0000
3640+++ account_statement_bankaccount_completion/tests/test_bankaccount_completion.py 2014-03-27 09:24:37 +0000
3641@@ -0,0 +1,91 @@
3642+# -*- coding: utf-8 -*-
3643+#
3644+#
3645+# Authors: Laurent Mignon
3646+# Copyright (c) 2013 Acsone SA/NV (http://www.acsone.eu)
3647+# All Rights Reserved
3648+#
3649+# This program is free software: you can redistribute it and/or modify
3650+# it under the terms of the GNU Affero General Public License as
3651+# published by the Free Software Foundation, either version 3 of the
3652+# License, or (at your option) any later version.
3653+#
3654+# This program is distributed in the hope that it will be useful,
3655+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3656+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3657+# GNU Affero General Public License for more details.
3658+#
3659+# You should have received a copy of the GNU Affero General Public License
3660+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3661+#
3662+#
3663+from openerp.tests import common
3664+import time
3665+
3666+ACC_NUMBER = "BE38733040385372"
3667+
3668+
3669+class bankaccount_completion(common.TransactionCase):
3670+
3671+ def prepare(self):
3672+ self.company_a = self.browse_ref('base.main_company')
3673+ self.profile_obj = self.registry("account.statement.profile")
3674+ self.account_bank_statement_obj = self.registry("account.bank.statement")
3675+ self.account_bank_statement_line_obj = self.registry("account.bank.statement.line")
3676+ self.completion_rule_id = self.ref('account_statement_bankaccount_completion.bank_statement_completion_rule_10')
3677+ self.journal_id = self.registry("ir.model.data").get_object_reference(self.cr, self. uid, "account", "bank_journal")[1]
3678+ self.partner_id = self.ref('base.main_partner')
3679+ # Create the profile
3680+ self.account_id = self.registry("ir.model.data").get_object_reference(self.cr, self.uid, "account", "a_recv")[1]
3681+ self.journal_id = self.registry("ir.model.data").get_object_reference(self.cr, self. uid, "account", "bank_journal")[1]
3682+ self.profile_id = self.profile_obj.create(self.cr, self.uid, {
3683+ "name": "TEST",
3684+ "commission_account_id": self.account_id,
3685+ "journal_id": self.journal_id,
3686+ "rule_ids": [(6, 0, [self.completion_rule_id])]})
3687+ # Create the completion rule
3688+
3689+ # Create a bank statement
3690+ self.statement_id = self.account_bank_statement_obj.create(self.cr, self.uid, {
3691+ "balance_end_real": 0.0,
3692+ "balance_start": 0.0,
3693+ "date": time.strftime('%Y-%m-%d'),
3694+ "journal_id": self.journal_id,
3695+ "profile_id": self.profile_id
3696+
3697+ })
3698+
3699+ # Create bank a statement line
3700+ self.statement_line_id = self.account_bank_statement_line_obj.create(self.cr, self.uid, {
3701+ 'amount': 1000.0,
3702+ 'name': 'EXT001',
3703+ 'ref': 'My ref',
3704+ 'statement_id': self.statement_id,
3705+ 'partner_acc_number': ACC_NUMBER
3706+ })
3707+
3708+ # Add a bank account number to the partner
3709+ res_bank_obj = self.registry('res.partner.bank')
3710+ res_bank_obj.create(self.cr, self.uid, {
3711+ "state": "bank",
3712+ "company_id": self.company_a.id,
3713+ "partner_id": self.partner_id,
3714+ "acc_number": ACC_NUMBER,
3715+ "footer": True,
3716+ "bank_name": "Reserve"
3717+ })
3718+
3719+ def test_00(self):
3720+ """Test complete partner_id from bank account number
3721+
3722+ Test the automatic completion of the partner_id based on the account number associated to the
3723+ statement line
3724+ """
3725+ self.prepare()
3726+ statement_line = self.account_bank_statement_line_obj.browse(self.cr, self.uid, self.statement_line_id)
3727+ # before import, the
3728+ self.assertFalse(statement_line.partner_id, "Partner_id must be blank before completion")
3729+ statement_obj = self.account_bank_statement_obj.browse(self.cr, self.uid, self.statement_id)
3730+ statement_obj.button_auto_completion()
3731+ statement_line = self.account_bank_statement_line_obj.browse(self.cr, self.uid, self.statement_line_id)
3732+ self.assertEquals(self.partner_id, statement_line.partner_id['id'], "Missing expected partner id after completion")
3733
3734=== added directory 'account_statement_base_completion'
3735=== added file 'account_statement_base_completion/__init__.py'
3736--- account_statement_base_completion/__init__.py 1970-01-01 00:00:00 +0000
3737+++ account_statement_base_completion/__init__.py 2014-03-27 09:24:37 +0000
3738@@ -0,0 +1,23 @@
3739+# -*- coding: utf-8 -*-
3740+##############################################################################
3741+#
3742+# Author: Joel Grand-Guillaume
3743+# Copyright 2011-2012 Camptocamp SA
3744+#
3745+# This program is free software: you can redistribute it and/or modify
3746+# it under the terms of the GNU Affero General Public License as
3747+# published by the Free Software Foundation, either version 3 of the
3748+# License, or (at your option) any later version.
3749+#
3750+# This program is distributed in the hope that it will be useful,
3751+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3752+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3753+# GNU Affero General Public License for more details.
3754+#
3755+# You should have received a copy of the GNU Affero General Public License
3756+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3757+#
3758+##############################################################################
3759+
3760+from . import partner
3761+from . import statement
3762
3763=== added file 'account_statement_base_completion/__openerp__.py'
3764--- account_statement_base_completion/__openerp__.py 1970-01-01 00:00:00 +0000
3765+++ account_statement_base_completion/__openerp__.py 2014-03-27 09:24:37 +0000
3766@@ -0,0 +1,77 @@
3767+# -*- coding: utf-8 -*-
3768+##############################################################################
3769+#
3770+# Author: Joel Grand-Guillaume
3771+# Copyright 2011-2012 Camptocamp SA
3772+#
3773+# This program is free software: you can redistribute it and/or modify
3774+# it under the terms of the GNU Affero General Public License as
3775+# published by the Free Software Foundation, either version 3 of the
3776+# License, or (at your option) any later version.
3777+#
3778+# This program is distributed in the hope that it will be useful,
3779+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3780+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3781+# GNU Affero General Public License for more details.
3782+#
3783+# You should have received a copy of the GNU Affero General Public License
3784+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3785+#
3786+##############################################################################
3787+
3788+{'name': "Bank statement base completion",
3789+ 'version': '1.0.1',
3790+ 'author': 'Camptocamp',
3791+ 'maintainer': 'Camptocamp',
3792+ 'category': 'Finance',
3793+ 'complexity': 'normal',
3794+ 'depends': ['account_statement_ext'],
3795+ 'description': """
3796+ The goal of this module is to improve the basic bank statement, help dealing with huge volume of
3797+ reconciliation by providing basic rules to identify the partner of a bank statement line.
3798+ Each bank statement profile can have its own rules to be applied according to a sequence order.
3799+
3800+ Some basic rules are provided in this module:
3801+
3802+ 1) Match from statement line label (based on partner field 'Bank Statement Label')
3803+ 2) Match from statement line label (based on partner name)
3804+ 3) Match from statement line reference (based on Invoice number)
3805+
3806+ You can easily override this module and add your own rules in your own one. The basic rules only
3807+ fill in the partner, but you can use them to fill in any value of the line (in the future, we will
3808+ add a rule to automatically match and reconcile the line).
3809+
3810+ It adds as well a label on the bank statement line (on which the pre-define rules can match) and
3811+ a char field on the partner called 'Bank Statement Label'. Using the pre-define rules, you will be
3812+ able to match various labels for a partner.
3813+
3814+ The reference of the line is always used by the reconciliation process. We're supposed to copy
3815+ there (or write manually) the matching string. This can be: the order Number or an invoice number,
3816+ or anything that will be found in the invoice accounting entry part to make the match.
3817+
3818+ You can use it with our account_advanced_reconcile module to automatize the reconciliation process.
3819+
3820+
3821+ TODO: The rules that look for invoices to find out the partner should take back the payable / receivable
3822+ account from there directly instead of retrieving it from partner properties !
3823+
3824+ """,
3825+ 'website': 'http://www.camptocamp.com',
3826+ 'data': [
3827+ 'statement_view.xml',
3828+ 'partner_view.xml',
3829+ 'data.xml',
3830+ 'security/ir.model.access.csv',
3831+ ],
3832+ 'demo': [],
3833+ 'test': [
3834+ 'test/partner.yml',
3835+ 'test/invoice.yml',
3836+ 'test/supplier_invoice.yml',
3837+ 'test/completion_test.yml'
3838+ ],
3839+ 'installable': True,
3840+ 'images': [],
3841+ 'auto_install': False,
3842+ 'license': 'AGPL-3',
3843+}
3844
3845=== added file 'account_statement_base_completion/data.xml'
3846--- account_statement_base_completion/data.xml 1970-01-01 00:00:00 +0000
3847+++ account_statement_base_completion/data.xml 2014-03-27 09:24:37 +0000
3848@@ -0,0 +1,31 @@
3849+<?xml version="1.0" encoding="utf-8"?>
3850+<openerp>
3851+<data noupdate="1">
3852+
3853+ <record id="bank_statement_completion_rule_2" model="account.statement.completion.rule">
3854+ <field name="name">Match from line label (based on partner field 'Bank Statement Label')</field>
3855+ <field name="sequence">60</field>
3856+ <field name="function_to_call">get_from_label_and_partner_field</field>
3857+ </record>
3858+
3859+ <record id="bank_statement_completion_rule_3" model="account.statement.completion.rule">
3860+ <field name="name">Match from line label (based on partner name)</field>
3861+ <field name="sequence">70</field>
3862+ <field name="function_to_call">get_from_label_and_partner_name</field>
3863+ </record>
3864+
3865+ <record id="bank_statement_completion_rule_4" model="account.statement.completion.rule">
3866+ <field name="name">Match from line reference (based on Invoice number)</field>
3867+ <field name="sequence">40</field>
3868+ <field name="function_to_call">get_from_ref_and_invoice</field>
3869+ </record>
3870+
3871+ <record id="bank_statement_completion_rule_5" model="account.statement.completion.rule">
3872+ <field name="name">Match from line reference (based on Invoice Supplier number)</field>
3873+ <field name="sequence">45</field>
3874+ <field name="function_to_call">get_from_ref_and_supplier_invoice</field>
3875+ </record>
3876+
3877+
3878+</data>
3879+</openerp>
3880
3881=== added directory 'account_statement_base_completion/i18n'
3882=== added file 'account_statement_base_completion/i18n/account_statement_base_completion.pot'
3883--- account_statement_base_completion/i18n/account_statement_base_completion.pot 1970-01-01 00:00:00 +0000
3884+++ account_statement_base_completion/i18n/account_statement_base_completion.pot 2014-03-27 09:24:37 +0000
3885@@ -0,0 +1,199 @@
3886+# Translation of OpenERP Server.
3887+# This file contains the translation of the following modules:
3888+# * account_statement_base_completion
3889+#
3890+msgid ""
3891+msgstr ""
3892+"Project-Id-Version: OpenERP Server 7.0\n"
3893+"Report-Msgid-Bugs-To: \n"
3894+"POT-Creation-Date: 2014-01-21 11:57+0000\n"
3895+"PO-Revision-Date: 2014-01-21 11:57+0000\n"
3896+"Last-Translator: <>\n"
3897+"Language-Team: \n"
3898+"MIME-Version: 1.0\n"
3899+"Content-Type: text/plain; charset=UTF-8\n"
3900+"Content-Transfer-Encoding: \n"
3901+"Plural-Forms: \n"
3902+
3903+#. module: account_statement_base_completion
3904+#: view:account.statement.completion.rule:0
3905+msgid "Related Profiles"
3906+msgstr ""
3907+
3908+#. module: account_statement_base_completion
3909+#: help:account.bank.statement.line,label:0
3910+msgid "Generic field to store a label given from the bank/office on which we can base the default/standard providen rule."
3911+msgstr ""
3912+
3913+#. module: account_statement_base_completion
3914+#: code:addons/account_statement_base_completion/statement.py:169
3915+#, python-format
3916+msgid "Line named \"%s\" (Ref:%s) was matched by more than one partner while looking on %s invoices"
3917+msgstr ""
3918+
3919+#. module: account_statement_base_completion
3920+#: field:account.bank.statement,completion_logs:0
3921+msgid "Completion Log"
3922+msgstr ""
3923+
3924+#. module: account_statement_base_completion
3925+#: field:account.bank.statement.line,label:0
3926+msgid "Label"
3927+msgstr ""
3928+
3929+#. module: account_statement_base_completion
3930+#: model:ir.model,name:account_statement_base_completion.model_account_bank_statement
3931+msgid "Bank Statement"
3932+msgstr ""
3933+
3934+#. module: account_statement_base_completion
3935+#: field:account.statement.completion.rule,function_to_call:0
3936+msgid "Method"
3937+msgstr ""
3938+
3939+#. module: account_statement_base_completion
3940+#: code:addons/account_statement_base_completion/statement.py:326
3941+#, python-format
3942+msgid "Line named \"%s\" (Ref:%s) was matched by more than one partner while looking on partner by name"
3943+msgstr ""
3944+
3945+#. module: account_statement_base_completion
3946+#: code:addons/account_statement_base_completion/statement.py:504
3947+#, python-format
3948+msgid "Statement ID %s auto-completed for %s lines completed"
3949+msgstr ""
3950+
3951+#. module: account_statement_base_completion
3952+#: code:addons/account_statement_base_completion/statement.py:500
3953+#, python-format
3954+msgid "%s Bank Statement ID %s has %s lines completed by %s \n"
3955+"%s\n"
3956+"%s\n"
3957+""
3958+msgstr ""
3959+
3960+#. module: account_statement_base_completion
3961+#: model:ir.model,name:account_statement_base_completion.model_account_bank_statement_line
3962+msgid "Bank Statement Line"
3963+msgstr ""
3964+
3965+#. module: account_statement_base_completion
3966+#: field:account.bank.statement.line,additionnal_bank_fields:0
3967+msgid "Additionnal infos from bank"
3968+msgstr ""
3969+
3970+#. module: account_statement_base_completion
3971+#: view:account.statement.profile:0
3972+msgid "Auto-Completion Rules"
3973+msgstr ""
3974+
3975+#. module: account_statement_base_completion
3976+#: view:account.bank.statement:0
3977+msgid "Importation related infos"
3978+msgstr ""
3979+
3980+#. module: account_statement_base_completion
3981+#: code:addons/account_statement_base_completion/statement.py:159
3982+#: code:addons/account_statement_base_completion/statement.py:179
3983+#, python-format
3984+msgid "Invalid invoice type for completion: %"
3985+msgstr ""
3986+
3987+#. module: account_statement_base_completion
3988+#: field:account.statement.completion.rule,name:0
3989+msgid "Name"
3990+msgstr ""
3991+
3992+#. module: account_statement_base_completion
3993+#: model:ir.model,name:account_statement_base_completion.model_account_statement_profile
3994+msgid "Statement Profile"
3995+msgstr ""
3996+
3997+#. module: account_statement_base_completion
3998+#: view:account.bank.statement:0
3999+msgid "Auto Completion"
4000+msgstr ""
4001+
4002+#. module: account_statement_base_completion
4003+#: view:account.statement.completion.rule:0
4004+#: model:ir.actions.act_window,name:account_statement_base_completion.action_st_completion_rule_tree
4005+#: model:ir.ui.menu,name:account_statement_base_completion.menu_action_st_completion_rule_tree_menu
4006+msgid "Statement Completion Rule"
4007+msgstr ""
4008+
4009+#. module: account_statement_base_completion
4010+#: model:ir.model,name:account_statement_base_completion.model_account_statement_completion_rule
4011+msgid "account.statement.completion.rule"
4012+msgstr ""
4013+
4014+#. module: account_statement_base_completion
4015+#: help:account.bank.statement.line,additionnal_bank_fields:0
4016+msgid "Used by completion and import system. Adds every field that is present in your bank/office statement file"
4017+msgstr ""
4018+
4019+#. module: account_statement_base_completion
4020+#: field:account.statement.completion.rule,profile_ids:0
4021+#: field:account.statement.profile,rule_ids:0
4022+msgid "Related statement profiles"
4023+msgstr ""
4024+
4025+#. module: account_statement_base_completion
4026+#: code:addons/account_statement_base_completion/statement.py:158
4027+#: code:addons/account_statement_base_completion/statement.py:178
4028+#, python-format
4029+msgid "System error"
4030+msgstr ""
4031+
4032+#. module: account_statement_base_completion
4033+#: field:account.bank.statement.line,already_completed:0
4034+msgid "Auto-Completed"
4035+msgstr ""
4036+
4037+#. module: account_statement_base_completion
4038+#: code:addons/account_statement_base_completion/statement.py:448
4039+#: code:addons/account_statement_base_completion/statement.py:466
4040+#, python-format
4041+msgid "ORM bypass error"
4042+msgstr ""
4043+
4044+#. module: account_statement_base_completion
4045+#: field:account.statement.completion.rule,sequence:0
4046+msgid "Sequence"
4047+msgstr ""
4048+
4049+#. module: account_statement_base_completion
4050+#: code:addons/account_statement_base_completion/statement.py:280
4051+#, python-format
4052+msgid "Line named \"%s\" (Ref:%s) was matched by more than one partner while looking on partner label: %s"
4053+msgstr ""
4054+
4055+#. module: account_statement_base_completion
4056+#: help:account.statement.completion.rule,sequence:0
4057+msgid "Lower means parsed first."
4058+msgstr ""
4059+
4060+#. module: account_statement_base_completion
4061+#: field:res.partner,bank_statement_label:0
4062+msgid "Bank Statement Label"
4063+msgstr ""
4064+
4065+#. module: account_statement_base_completion
4066+#: help:account.bank.statement.line,already_completed:0
4067+msgid "When this checkbox is ticked, the auto-completion process/button will ignore this line."
4068+msgstr ""
4069+
4070+#. module: account_statement_base_completion
4071+#: help:res.partner,bank_statement_label:0
4072+msgid "Enter the various label found on your bank statement separated by a ; If one of this label is include in the bank statement line, the partner will be automatically filled (as long as you use this method/rules in your statement profile)."
4073+msgstr ""
4074+
4075+#. module: account_statement_base_completion
4076+#: model:ir.model,name:account_statement_base_completion.model_res_partner
4077+msgid "Partner"
4078+msgstr ""
4079+
4080+#. module: account_statement_base_completion
4081+#: view:account.bank.statement:0
4082+msgid "Completion Logs"
4083+msgstr ""
4084+
4085
4086=== added file 'account_statement_base_completion/i18n/fr.po'
4087--- account_statement_base_completion/i18n/fr.po 1970-01-01 00:00:00 +0000
4088+++ account_statement_base_completion/i18n/fr.po 2014-03-27 09:24:37 +0000
4089@@ -0,0 +1,216 @@
4090+# French translation for banking-addons
4091+# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
4092+# This file is distributed under the same license as the banking-addons package.
4093+# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
4094+#
4095+msgid ""
4096+msgstr ""
4097+"Project-Id-Version: banking-addons\n"
4098+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
4099+"POT-Creation-Date: 2014-01-21 11:57+0000\n"
4100+"PO-Revision-Date: 2014-03-21 15:17+0000\n"
4101+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
4102+"Language-Team: French <fr@li.org>\n"
4103+"MIME-Version: 1.0\n"
4104+"Content-Type: text/plain; charset=UTF-8\n"
4105+"Content-Transfer-Encoding: 8bit\n"
4106+"X-Launchpad-Export-Date: 2014-03-22 07:11+0000\n"
4107+"X-Generator: Launchpad (build 16967)\n"
4108+
4109+#. module: account_statement_base_completion
4110+#: view:account.statement.completion.rule:0
4111+msgid "Related Profiles"
4112+msgstr ""
4113+
4114+#. module: account_statement_base_completion
4115+#: help:account.bank.statement.line,label:0
4116+msgid ""
4117+"Generic field to store a label given from the bank/office on which we can "
4118+"base the default/standard providen rule."
4119+msgstr ""
4120+
4121+#. module: account_statement_base_completion
4122+#: code:addons/account_statement_base_completion/statement.py:169
4123+#, python-format
4124+msgid ""
4125+"Line named \"%s\" (Ref:%s) was matched by more than one partner while "
4126+"looking on %s invoices"
4127+msgstr ""
4128+
4129+#. module: account_statement_base_completion
4130+#: field:account.bank.statement,completion_logs:0
4131+msgid "Completion Log"
4132+msgstr ""
4133+
4134+#. module: account_statement_base_completion
4135+#: field:account.bank.statement.line,label:0
4136+msgid "Label"
4137+msgstr ""
4138+
4139+#. module: account_statement_base_completion
4140+#: model:ir.model,name:account_statement_base_completion.model_account_bank_statement
4141+msgid "Bank Statement"
4142+msgstr ""
4143+
4144+#. module: account_statement_base_completion
4145+#: field:account.statement.completion.rule,function_to_call:0
4146+msgid "Method"
4147+msgstr ""
4148+
4149+#. module: account_statement_base_completion
4150+#: code:addons/account_statement_base_completion/statement.py:326
4151+#, python-format
4152+msgid ""
4153+"Line named \"%s\" (Ref:%s) was matched by more than one partner while "
4154+"looking on partner by name"
4155+msgstr ""
4156+
4157+#. module: account_statement_base_completion
4158+#: code:addons/account_statement_base_completion/statement.py:504
4159+#, python-format
4160+msgid "Statement ID %s auto-completed for %s lines completed"
4161+msgstr ""
4162+
4163+#. module: account_statement_base_completion
4164+#: code:addons/account_statement_base_completion/statement.py:500
4165+#, python-format
4166+msgid ""
4167+"%s Bank Statement ID %s has %s lines completed by %s \n"
4168+"%s\n"
4169+"%s\n"
4170+msgstr ""
4171+
4172+#. module: account_statement_base_completion
4173+#: model:ir.model,name:account_statement_base_completion.model_account_bank_statement_line
4174+msgid "Bank Statement Line"
4175+msgstr ""
4176+
4177+#. module: account_statement_base_completion
4178+#: field:account.bank.statement.line,additionnal_bank_fields:0
4179+msgid "Additionnal infos from bank"
4180+msgstr ""
4181+
4182+#. module: account_statement_base_completion
4183+#: view:account.statement.profile:0
4184+msgid "Auto-Completion Rules"
4185+msgstr ""
4186+
4187+#. module: account_statement_base_completion
4188+#: view:account.bank.statement:0
4189+msgid "Importation related infos"
4190+msgstr ""
4191+
4192+#. module: account_statement_base_completion
4193+#: code:addons/account_statement_base_completion/statement.py:159
4194+#: code:addons/account_statement_base_completion/statement.py:179
4195+#, python-format
4196+msgid "Invalid invoice type for completion: %"
4197+msgstr ""
4198+
4199+#. module: account_statement_base_completion
4200+#: field:account.statement.completion.rule,name:0
4201+msgid "Name"
4202+msgstr ""
4203+
4204+#. module: account_statement_base_completion
4205+#: model:ir.model,name:account_statement_base_completion.model_account_statement_profile
4206+msgid "Statement Profile"
4207+msgstr ""
4208+
4209+#. module: account_statement_base_completion
4210+#: view:account.bank.statement:0
4211+msgid "Auto Completion"
4212+msgstr ""
4213+
4214+#. module: account_statement_base_completion
4215+#: view:account.statement.completion.rule:0
4216+#: model:ir.actions.act_window,name:account_statement_base_completion.action_st_completion_rule_tree
4217+#: model:ir.ui.menu,name:account_statement_base_completion.menu_action_st_completion_rule_tree_menu
4218+msgid "Statement Completion Rule"
4219+msgstr ""
4220+
4221+#. module: account_statement_base_completion
4222+#: model:ir.model,name:account_statement_base_completion.model_account_statement_completion_rule
4223+msgid "account.statement.completion.rule"
4224+msgstr ""
4225+
4226+#. module: account_statement_base_completion
4227+#: help:account.bank.statement.line,additionnal_bank_fields:0
4228+msgid ""
4229+"Used by completion and import system. Adds every field that is present in "
4230+"your bank/office statement file"
4231+msgstr ""
4232+
4233+#. module: account_statement_base_completion
4234+#: field:account.statement.completion.rule,profile_ids:0
4235+#: field:account.statement.profile,rule_ids:0
4236+msgid "Related statement profiles"
4237+msgstr ""
4238+
4239+#. module: account_statement_base_completion
4240+#: code:addons/account_statement_base_completion/statement.py:158
4241+#: code:addons/account_statement_base_completion/statement.py:178
4242+#, python-format
4243+msgid "System error"
4244+msgstr ""
4245+
4246+#. module: account_statement_base_completion
4247+#: field:account.bank.statement.line,already_completed:0
4248+msgid "Auto-Completed"
4249+msgstr ""
4250+
4251+#. module: account_statement_base_completion
4252+#: code:addons/account_statement_base_completion/statement.py:448
4253+#: code:addons/account_statement_base_completion/statement.py:466
4254+#, python-format
4255+msgid "ORM bypass error"
4256+msgstr ""
4257+
4258+#. module: account_statement_base_completion
4259+#: field:account.statement.completion.rule,sequence:0
4260+msgid "Sequence"
4261+msgstr ""
4262+
4263+#. module: account_statement_base_completion
4264+#: code:addons/account_statement_base_completion/statement.py:280
4265+#, python-format
4266+msgid ""
4267+"Line named \"%s\" (Ref:%s) was matched by more than one partner while "
4268+"looking on partner label: %s"
4269+msgstr ""
4270+
4271+#. module: account_statement_base_completion
4272+#: help:account.statement.completion.rule,sequence:0
4273+msgid "Lower means parsed first."
4274+msgstr ""
4275+
4276+#. module: account_statement_base_completion
4277+#: field:res.partner,bank_statement_label:0
4278+msgid "Bank Statement Label"
4279+msgstr ""
4280+
4281+#. module: account_statement_base_completion
4282+#: help:account.bank.statement.line,already_completed:0
4283+msgid ""
4284+"When this checkbox is ticked, the auto-completion process/button will ignore "
4285+"this line."
4286+msgstr ""
4287+
4288+#. module: account_statement_base_completion
4289+#: help:res.partner,bank_statement_label:0
4290+msgid ""
4291+"Enter the various label found on your bank statement separated by a ; If "
4292+" one of this label is include in the bank statement line, the "
4293+"partner will be automatically filled (as long as you use "
4294+"this method/rules in your statement profile)."
4295+msgstr ""
4296+
4297+#. module: account_statement_base_completion
4298+#: model:ir.model,name:account_statement_base_completion.model_res_partner
4299+msgid "Partner"
4300+msgstr ""
4301+
4302+#. module: account_statement_base_completion
4303+#: view:account.bank.statement:0
4304+msgid "Completion Logs"
4305+msgstr ""
4306
4307=== added file 'account_statement_base_completion/partner.py'
4308--- account_statement_base_completion/partner.py 1970-01-01 00:00:00 +0000
4309+++ account_statement_base_completion/partner.py 2014-03-27 09:24:37 +0000
4310@@ -0,0 +1,38 @@
4311+# -*- coding: utf-8 -*-
4312+#################################################################################
4313+# #
4314+# Copyright (C) 2011 Akretion & Camptocamp
4315+# Author : Sébastien BEAU, Joel Grand-Guillaume #
4316+# #
4317+# This program is free software: you can redistribute it and/or modify #
4318+# it under the terms of the GNU Affero General Public License as #
4319+# published by the Free Software Foundation, either version 3 of the #
4320+# License, or (at your option) any later version. #
4321+# #
4322+# This program is distributed in the hope that it will be useful, #
4323+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
4324+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
4325+# GNU Affero General Public License for more details. #
4326+# #
4327+# You should have received a copy of the GNU Affero General Public License #
4328+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
4329+# #
4330+#################################################################################
4331+
4332+from openerp.osv.orm import Model
4333+from openerp.osv import fields, osv
4334+
4335+
4336+class res_partner(Model):
4337+ """
4338+ Add a bank label on the partner so that we can use it to match
4339+ this partner when we found this in a statement line.
4340+ """
4341+ _inherit = 'res.partner'
4342+
4343+ _columns = {
4344+ 'bank_statement_label': fields.char('Bank Statement Label', size=100,
4345+ help="Enter the various label found on your bank statement separated by a ; If \
4346+ one of this label is include in the bank statement line, the partner will be automatically \
4347+ filled (as long as you use this method/rules in your statement profile)."),
4348+ }
4349
4350=== added file 'account_statement_base_completion/partner_view.xml'
4351--- account_statement_base_completion/partner_view.xml 1970-01-01 00:00:00 +0000
4352+++ account_statement_base_completion/partner_view.xml 2014-03-27 09:24:37 +0000
4353@@ -0,0 +1,22 @@
4354+<?xml version="1.0" encoding="UTF-8"?>
4355+
4356+
4357+<openerp>
4358+ <data>
4359+
4360+ <record id="bk_view_partner_form" model="ir.ui.view">
4361+ <field name="name">account_bank_statement_import.view.partner.form</field>
4362+ <field name="model">res.partner</field>
4363+ <field name="type">form</field>
4364+ <field name="priority">20</field>
4365+ <field name="inherit_id" ref="account.view_partner_property_form"/>
4366+ <field name="arch" type="xml">
4367+ <field name="property_account_payable" position="after">
4368+ <field name="bank_statement_label"/>
4369+ </field>
4370+ </field>
4371+ </record>
4372+
4373+
4374+ </data>
4375+</openerp>
4376
4377=== added directory 'account_statement_base_completion/security'
4378=== added file 'account_statement_base_completion/security/ir.model.access.csv'
4379--- account_statement_base_completion/security/ir.model.access.csv 1970-01-01 00:00:00 +0000
4380+++ account_statement_base_completion/security/ir.model.access.csv 2014-03-27 09:24:37 +0000
4381@@ -0,0 +1,3 @@
4382+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
4383+access_account_bank_st_cmpl_user,account.statement.completion.rule,model_account_statement_completion_rule,account.group_account_user,1,0,0,0
4384+access_account_bank_st_cmpl_manager,account.statement.completion.rule,model_account_statement_completion_rule,account.group_account_manager,1,1,1,1
4385
4386=== added file 'account_statement_base_completion/statement.py'
4387--- account_statement_base_completion/statement.py 1970-01-01 00:00:00 +0000
4388+++ account_statement_base_completion/statement.py 2014-03-27 09:24:37 +0000
4389@@ -0,0 +1,573 @@
4390+# -*- coding: utf-8 -*-
4391+##############################################################################
4392+#
4393+# Author: Nicolas Bessi, Joel Grand-Guillaume
4394+# Copyright 2011-2012 Camptocamp SA
4395+#
4396+# This program is free software: you can redistribute it and/or modify
4397+# it under the terms of the GNU Affero General Public License as
4398+# published by the Free Software Foundation, either version 3 of the
4399+# License, or (at your option) any later version.
4400+#
4401+# This program is distributed in the hope that it will be useful,
4402+# but WITHOUT ANY WARRANTY; without even the implied warranty of
4403+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4404+# GNU Affero General Public License for more details.
4405+#
4406+# You should have received a copy of the GNU Affero General Public License
4407+# along with this program. If not, see <http://www.gnu.org/licenses/>.
4408+#
4409+##############################################################################
4410+# TODO replace customer supplier by package constant
4411+import traceback
4412+import sys
4413+import logging
4414+import simplejson
4415+import inspect
4416+
4417+import psycopg2
4418+
4419+from collections import defaultdict
4420+import re
4421+from tools.translate import _
4422+from openerp.osv import osv, orm, fields
4423+from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
4424+from operator import attrgetter
4425+import datetime
4426+
4427+_logger = logging.getLogger(__name__)
4428+
4429+
4430+class ErrorTooManyPartner(Exception):
4431+ """
4432+ New Exception definition that is raised when more than one partner is matched by
4433+ the completion rule.
4434+ """
4435+ def __init__(self, value):
4436+ self.value = value
4437+
4438+ def __str__(self):
4439+ return repr(self.value)
4440+
4441+ def __repr__(self):
4442+ return repr(self.value)
4443+
4444+
4445+class AccountStatementProfil(orm.Model):
4446+ """
4447+ Extend the class to add rules per profile that will match at least the partner,
4448+ but it could also be used to match other values as well.
4449+ """
4450+
4451+ _inherit = "account.statement.profile"
4452+
4453+ _columns = {
4454+ # @Akretion: For now, we don't implement this features, but this would probably be there:
4455+ # 'auto_completion': fields.text('Auto Completion'),
4456+ # 'transferts_account_id':fields.many2one('account.account', 'Transferts Account'),
4457+ # => You can implement it in a module easily, we design it with your needs in mind
4458+ # as well!
4459+
4460+ 'rule_ids': fields.many2many(
4461+ 'account.statement.completion.rule',
4462+ string='Related statement profiles',
4463+ rel='as_rul_st_prof_rel'),
4464+ }
4465+
4466+ def _get_rules(self, cr, uid, profile, context=None):
4467+ if isinstance(profile, (int, long)):
4468+ prof = self.browse(cr, uid, profile, context=context)
4469+ else:
4470+ prof = profile
4471+ # We need to respect the sequence order
4472+ return sorted(prof.rule_ids, key=attrgetter('sequence'))
4473+
4474+ def _find_values_from_rules(self, cr, uid, calls, line, context=None):
4475+ """
4476+ This method will execute all related rules, in their sequence order,
4477+ to retrieve all the values returned by the first rules that will match.
4478+ :param calls: list of lookup function name available in rules
4479+ :param dict line: read of the concerned account.bank.statement.line
4480+ :return:
4481+ A dict of value that can be passed directly to the write method of
4482+ the statement line or {}
4483+ {'partner_id': value,
4484+ 'account_id: value,
4485+
4486+ ...}
4487+ """
4488+ if context is None:
4489+ context = {}
4490+ if not calls:
4491+ calls = self._get_rules(cr, uid, line['profile_id'], context=context)
4492+ rule_obj = self.pool.get('account.statement.completion.rule')
4493+
4494+ for call in calls:
4495+ method_to_call = getattr(rule_obj, call.function_to_call)
4496+ if len(inspect.getargspec(method_to_call).args) == 6:
4497+ result = method_to_call(cr, uid, call.id, line, context)
4498+ else:
4499+ result = method_to_call(cr, uid, line, context)
4500+ if result:
4501+ result['already_completed'] = True
4502+ return result
4503+ return None
4504+
4505+
4506+class AccountStatementCompletionRule(orm.Model):
4507+ """
4508+ This will represent all the completion method that we can have to
4509+ fullfill the bank statement lines. You'll be able to extend them in you own module
4510+ and choose those to apply for every statement profile.
4511+ The goal of a rule is to fullfill at least the partner of the line, but
4512+ if possible also the reference because we'll use it in the reconciliation
4513+ process. The reference should contain the invoice number or the SO number
4514+ or any reference that will be matched by the invoice accounting move.
4515+ """
4516+
4517+ _name = "account.statement.completion.rule"
4518+ _order = "sequence asc"
4519+
4520+ def _get_functions(self, cr, uid, context=None):
4521+ """
4522+ List of available methods for rules. Override this to add you own.
4523+ """
4524+ return [
4525+ ('get_from_ref_and_invoice', 'From line reference (based on customer invoice number)'),
4526+ ('get_from_ref_and_supplier_invoice', 'From line reference (based on supplier invoice number)'),
4527+ ('get_from_label_and_partner_field', 'From line label (based on partner field)'),
4528+ ('get_from_label_and_partner_name', 'From line label (based on partner name)')]
4529+
4530+ _columns = {
4531+ 'sequence': fields.integer('Sequence', help="Lower means parsed first."),
4532+ 'name': fields.char('Name', size=128),
4533+ 'profile_ids': fields.many2many(
4534+ 'account.statement.profile',
4535+ rel='as_rul_st_prof_rel',
4536+ string='Related statement profiles'),
4537+ 'function_to_call': fields.selection(_get_functions, 'Method'),
4538+ }
4539+
4540+ def _find_invoice(self, cr, uid, st_line, inv_type, context=None):
4541+ """Find invoice related to statement line"""
4542+ inv_obj = self.pool.get('account.invoice')
4543+ if inv_type == 'supplier':
4544+ type_domain = ('in_invoice', 'in_refund')
4545+ number_field = 'supplier_invoice_number'
4546+ elif inv_type == 'customer':
4547+ type_domain = ('out_invoice', 'out_refund')
4548+ number_field = 'number'
4549+ else:
4550+ raise osv.except_osv(_('System error'),
4551+ _('Invalid invoice type for completion: %') % inv_type)
4552+
4553+ inv_id = inv_obj.search(cr, uid,
4554+ [(number_field, '=', st_line['ref'].strip()),
4555+ ('type', 'in', type_domain)],
4556+ context=context)
4557+ if inv_id:
4558+ if len(inv_id) == 1:
4559+ inv = inv_obj.browse(cr, uid, inv_id[0], context=context)
4560+ else:
4561+ raise ErrorTooManyPartner(_('Line named "%s" (Ref:%s) was matched by more '
4562+ 'than one partner while looking on %s invoices') %
4563+ (st_line['name'], st_line['ref'], inv_type))
4564+ return inv
4565+ return False
4566+
4567+ def _from_invoice(self, cr, uid, line, inv_type, context):
4568+ """Populate statement line values"""
4569+ if not inv_type in ('supplier', 'customer'):
4570+ raise osv.except_osv(_('System error'),
4571+ _('Invalid invoice type for completion: %') % inv_type)
4572+ res = {}
4573+ inv = self._find_invoice(cr, uid, line, inv_type, context=context)
4574+ if inv:
4575+ # FIXME use only commercial_partner_id of invoice in 7.1
4576+ # this is for backward compatibility in 7.0 before
4577+ # the refactoring of res.partner
4578+ if hasattr(inv, 'commercial_partner_id'):
4579+ partner_id = inv.commercial_partner_id.id
4580+ else:
4581+ partner_id = inv.partner_id.id
4582+
4583+ res = {'partner_id': partner_id,
4584+ 'account_id': inv.account_id.id,
4585+ 'type': inv_type}
4586+ override_acc = line['master_account_id']
4587+ if override_acc:
4588+ res['account_id'] = override_acc
4589+ return res
4590+
4591+ # Should be private but data are initialised with no update XML
4592+ def get_from_ref_and_supplier_invoice(self, cr, uid, line, context=None):
4593+ """
4594+ Match the partner based on the invoice supplier invoice number and the reference of the statement
4595+ line. Then, call the generic get_values_for_line method to complete other values.
4596+ If more than one partner matched, raise the ErrorTooManyPartner error.
4597+
4598+ :param dict line: read of the concerned account.bank.statement.line
4599+ :return:
4600+ A dict of value that can be passed directly to the write method of
4601+ the statement line or {}
4602+ {'partner_id': value,
4603+ 'account_id': value,
4604+
4605+ ...}
4606+ """
4607+ return self._from_invoice(cr, uid, line, 'supplier', context=context)
4608+
4609+ # Should be private but data are initialised with no update XML
4610+ def get_from_ref_and_invoice(self, cr, uid, line, context=None):
4611+ """
4612+ Match the partner based on the invoice number and the reference of the statement
4613+ line. Then, call the generic get_values_for_line method to complete other values.
4614+ If more than one partner matched, raise the ErrorTooManyPartner error.
4615+
4616+ :param dict line: read of the concerned account.bank.statement.line
4617+ :return:
4618+ A dict of value that can be passed directly to the write method of
4619+ the statement line or {}
4620+ {'partner_id': value,
4621+ 'account_id': value,
4622+ ...}
4623+ """
4624+ return self._from_invoice(cr, uid, line, 'customer', context=context)
4625+
4626+ # Should be private but data are initialised with no update XML
4627+ def get_from_label_and_partner_field(self, cr, uid, st_line, context=None):
4628+ """
4629+ Match the partner based on the label field of the statement line
4630+ and the text defined in the 'bank_statement_label' field of the partner.
4631+ Remember that we can have values separated with ; Then, call the generic
4632+ get_values_for_line method to complete other values.
4633+ If more than one partner matched, raise the ErrorTooManyPartner error.
4634+
4635+ :param dict st_line: read of the concerned account.bank.statement.line
4636+ :return:
4637+ A dict of value that can be passed directly to the write method of
4638+ the statement line or {}
4639+ {'partner_id': value,
4640+ 'account_id': value,
4641+
4642+ ...}
4643+ """
4644+ partner_obj = self.pool.get('res.partner')
4645+ st_obj = self.pool.get('account.bank.statement.line')
4646+ res = {}
4647+ # As we have to iterate on each partner for each line,
4648+ # we memoize the pair to avoid
4649+ # to redo computation for each line.
4650+ # Following code can be done by a single SQL query
4651+ # but this option is not really maintanable
4652+ if not context.get('label_memoizer'):
4653+ context['label_memoizer'] = defaultdict(list)
4654+ partner_ids = partner_obj.search(cr,
4655+ uid,
4656+ [('bank_statement_label', '!=', False)])
4657+ line_ids = context.get('line_ids', [])
4658+ for partner in partner_obj.browse(cr, uid, partner_ids, context=context):
4659+ vals = '|'.join(re.escape(x.strip()) for x in partner.bank_statement_label.split(';'))
4660+ or_regex = ".*%s.*" % vals
4661+ sql = ("SELECT id from account_bank_statement_line"
4662+ " WHERE id in %s"
4663+ " AND name ~* %s")
4664+ cr.execute(sql, (line_ids, or_regex))
4665+ pairs = cr.fetchall()
4666+ for pair in pairs:
4667+ context['label_memoizer'][pair[0]].append(partner)
4668+
4669+ if st_line['id'] in context['label_memoizer']:
4670+ found_partner = context['label_memoizer'][st_line['id']]
4671+ if len(found_partner) > 1:
4672+ msg = (_('Line named "%s" (Ref:%s) was matched by '
4673+ 'more than one partner while looking on partner label: %s') %
4674+ (st_line['name'], st_line['ref'], ','.join([x.name for x in found_partner])))
4675+ raise ErrorTooManyPartner(msg)
4676+ res['partner_id'] = found_partner[0].id
4677+ st_vals = st_obj.get_values_for_line(cr,
4678+ uid,
4679+ profile_id=st_line['profile_id'],
4680+ master_account_id=st_line['master_account_id'],
4681+ partner_id=found_partner[0].id,
4682+ line_type=False,
4683+ amount=st_line['amount'] if st_line['amount'] else 0.0,
4684+ context=context)
4685+ res.update(st_vals)
4686+ return res
4687+
4688+ def get_from_label_and_partner_name(self, cr, uid, st_line, context=None):
4689+ """
4690+ Match the partner based on the label field of the statement line
4691+ and the name of the partner.
4692+ Then, call the generic get_values_for_line method to complete other values.
4693+ If more than one partner matched, raise the ErrorTooManyPartner error.
4694+
4695+ :param dict st_line: read of the concerned account.bank.statement.line
4696+ :return:
4697+ A dict of value that can be passed directly to the write method of
4698+ the statement line or {}
4699+ {'partner_id': value,
4700+ 'account_id': value,
4701+
4702+ ...}
4703+ """
4704+ res = {}
4705+ # We memoize allowed partner
4706+ if not context.get('partner_memoizer'):
4707+ context['partner_memoizer'] = tuple(self.pool['res.partner'].search(cr, uid, []))
4708+ if not context['partner_memoizer']:
4709+ return res
4710+ st_obj = self.pool.get('account.bank.statement.line')
4711+ # regexp_replace(name,'([^a-zA-Z0-9 -])', '\\\1', 'g'), 'i') escape the column name to avoid false positive. (ex 'jho..doe' -> 'joh\.\.doe'
4712+ sql = """SELECT id FROM (
4713+ SELECT id, regexp_matches(%s, regexp_replace(name,'([^[:alpha:]0-9 -])', %s, 'g'), 'i') AS name_match FROM res_partner
4714+ WHERE id IN %s) AS res_patner_matcher
4715+ WHERE name_match IS NOT NULL"""
4716+ cr.execute(sql, (st_line['name'], r"\\\1", context['partner_memoizer']))
4717+ result = cr.fetchall()
4718+ if not result:
4719+ return res
4720+ if len(result) > 1:
4721+ raise ErrorTooManyPartner(_('Line named "%s" (Ref:%s) was matched by more '
4722+ 'than one partner while looking on partner by name') %
4723+ (st_line['name'], st_line['ref']))
4724+ res['partner_id'] = result[0][0]
4725+ st_vals = st_obj.get_values_for_line(cr,
4726+ uid,
4727+ profile_id=st_line['profile_id'],
4728+ master_account_id=st_line['master_account_id'],
4729+ partner_id=res['partner_id'],
4730+ line_type=False,
4731+ amount=st_line['amount'] if st_line['amount'] else 0.0,
4732+ context=context)
4733+ res.update(st_vals)
4734+ return res
4735+
4736+
4737+class AccountStatementLine(orm.Model):
4738+ """
4739+ Add sparse field on the statement line to allow to store all the
4740+ bank infos that are given by a bank/office. You can then add you own in your
4741+ module. The idea here is to store all bank/office infos in the additionnal_bank_fields
4742+ serialized field when importing the file. If many values, add a tab in the bank
4743+ statement line to store your specific one. Have a look in account_statement_base_import
4744+ module to see how we've done it.
4745+ """
4746+ _inherit = "account.bank.statement.line"
4747+
4748+ _columns = {
4749+ 'additionnal_bank_fields': fields.serialized(
4750+ 'Additionnal infos from bank',
4751+ help="Used by completion and import system. Adds every field that "
4752+ "is present in your bank/office statement file"),
4753+ 'label': fields.sparse(
4754+ type='char',
4755+ string='Label',
4756+ serialization_field='additionnal_bank_fields',
4757+ help="Generic field to store a label given from the "
4758+ "bank/office on which we can base the default/standard "
4759+ "providen rule."),
4760+ 'already_completed': fields.boolean(
4761+ "Auto-Completed",
4762+ help="When this checkbox is ticked, the auto-completion "
4763+ "process/button will ignore this line."),
4764+ }
4765+
4766+ _defaults = {
4767+ 'already_completed': False,
4768+ }
4769+
4770+ def _get_line_values_from_rules(self, cr, uid, line, rules, context=None):
4771+ """
4772+ We'll try to find out the values related to the line based on rules setted on
4773+ the profile.. We will ignore line for which already_completed is ticked.
4774+
4775+ :return:
4776+ A dict of dict value that can be passed directly to the write method of
4777+ the statement line or {}. The first dict has statement line ID as a key:
4778+ {117009: {'partner_id': 100997, 'account_id': 489L}}
4779+ """
4780+ profile_obj = self.pool.get('account.statement.profile')
4781+ if line.get('already_completed'):
4782+ return {}
4783+ # Ask the rule
4784+ vals = profile_obj._find_values_from_rules(cr, uid, rules, line, context)
4785+ if vals:
4786+ vals['id'] = line['id']
4787+ return vals
4788+ return {}
4789+
4790+ def _get_available_columns(self, statement_store, include_serializable=False):
4791+ """Return writeable by SQL columns"""
4792+ statement_line_obj = self.pool['account.bank.statement.line']
4793+ model_cols = statement_line_obj._columns
4794+ avail = [k for k, col in model_cols.iteritems() if not hasattr(col, '_fnct')]
4795+ keys = [k for k in statement_store[0].keys() if k in avail]
4796+ # add sparse fields..
4797+ if include_serializable:
4798+ for k, col in model_cols.iteritems():
4799+ if k in statement_store[0].keys() and \
4800+ isinstance(col, fields.sparse) and \
4801+ col.serialization_field not in keys and \
4802+ col._type == 'char':
4803+ keys.append(col.serialization_field)
4804+ keys.sort()
4805+ return keys
4806+
4807+ def _serialize_sparse_fields(self, cols, statement_store):
4808+ """ Serialize sparse fields values in the target serialized field
4809+ Return a copy of statement_store
4810+ """
4811+ statement_line_obj = self.pool['account.bank.statement.line']
4812+ model_cols = statement_line_obj._columns
4813+ sparse_fields = dict([(k, col) for k, col in model_cols.iteritems() if isinstance(col, fields.sparse) and col._type == 'char'])
4814+ values = []
4815+ for statement in statement_store:
4816+ to_json_k = set()
4817+ st_copy = statement.copy()
4818+ for k, col in sparse_fields.iteritems():
4819+ if k in st_copy:
4820+ to_json_k.add(col.serialization_field)
4821+ serialized = st_copy.setdefault(col.serialization_field, {})
4822+ serialized[k] = st_copy[k]
4823+ for k in to_json_k:
4824+ st_copy[k] = simplejson.dumps(st_copy[k])
4825+ values.append(st_copy)
4826+ return values
4827+
4828+ def _insert_lines(self, cr, uid, statement_store, context=None):
4829+ """ Do raw insert into database because ORM is awfully slow
4830+ when doing batch write. It is a shame that batch function
4831+ does not exist"""
4832+ statement_line_obj = self.pool['account.bank.statement.line']
4833+ statement_line_obj.check_access_rule(cr, uid, [], 'create')
4834+ statement_line_obj.check_access_rights(cr, uid, 'create', raise_exception=True)
4835+ cols = self._get_available_columns(statement_store, include_serializable=True)
4836+ tmp_vals = (', '.join(cols), ', '.join(['%%(%s)s' % i for i in cols]))
4837+ sql = "INSERT INTO account_bank_statement_line (%s) VALUES (%s);" % tmp_vals
4838+ try:
4839+ cr.executemany(sql, tuple(self._serialize_sparse_fields(cols, statement_store)))
4840+ except psycopg2.Error as sql_err:
4841+ cr.rollback()
4842+ raise osv.except_osv(_("ORM bypass error"),
4843+ sql_err.pgerror)
4844+
4845+ def _update_line(self, cr, uid, vals, context=None):
4846+ """ Do raw update into database because ORM is awfully slow
4847+ when cheking security.
4848+ TODO / WARM: sparse fields are skipped by the method. IOW, if your
4849+ completion rule update an sparse field, the updated value will never
4850+ be stored in the database. It would be safer to call the update method
4851+ from the ORM for records updating this kind of fields.
4852+ """
4853+ cols = self._get_available_columns([vals])
4854+ tmp_vals = (', '.join(['%s = %%(%s)s' % (i, i) for i in cols]))
4855+ sql = "UPDATE account_bank_statement_line SET %s where id = %%(id)s;" % tmp_vals
4856+ try:
4857+ cr.execute(sql, vals)
4858+ except psycopg2.Error as sql_err:
4859+ cr.rollback()
4860+ raise osv.except_osv(_("ORM bypass error"),
4861+ sql_err.pgerror)
4862+
4863+
4864+class AccountBankStatement(orm.Model):
4865+ """
4866+ We add a basic button and stuff to support the auto-completion
4867+ of the bank statement once line have been imported or manually fullfill.
4868+ """
4869+ _inherit = "account.bank.statement"
4870+
4871+ _columns = {
4872+ 'completion_logs': fields.text('Completion Log', readonly=True),
4873+ }
4874+
4875+ def write_completion_log(self, cr, uid, stat_id, error_msg, number_imported, context=None):
4876+ """
4877+ Write the log in the completion_logs field of the bank statement to let the user
4878+ know what have been done. This is an append mode, so we don't overwrite what
4879+ already recoded.
4880+
4881+ :param int/long stat_id: ID of the account.bank.statement
4882+ :param char error_msg: Message to add
4883+ :number_imported int/long: Number of lines that have been completed
4884+ :return True
4885+ """
4886+ user_name = self.pool.get('res.users').read(cr, uid, uid,
4887+ ['name'], context=context)['name']
4888+
4889+ log = self.read(cr, uid, stat_id, ['completion_logs'],
4890+ context=context)['completion_logs']
4891+ log = log if log else ""
4892+
4893+ completion_date = datetime.datetime.now().strftime(DEFAULT_SERVER_DATETIME_FORMAT)
4894+ message = (_("%s Bank Statement ID %s has %s lines completed by %s \n%s\n%s\n") %
4895+ (completion_date, stat_id, number_imported, user_name, error_msg, log))
4896+ self.write(cr, uid, [stat_id], {'completion_logs': message}, context=context)
4897+
4898+ body = (_('Statement ID %s auto-completed for %s lines completed') %
4899+ (stat_id, number_imported)),
4900+ self.message_post(cr, uid,
4901+ [stat_id],
4902+ body=body,
4903+ context=context)
4904+ return True
4905+
4906+ def button_auto_completion(self, cr, uid, ids, context=None):
4907+ """
4908+ Complete line with values given by rules and tic the already_completed
4909+ checkbox so we won't compute them again unless the user untick them!
4910+ """
4911+ if context is None:
4912+ context = {}
4913+ stat_line_obj = self.pool['account.bank.statement.line']
4914+ profile_obj = self.pool.get('account.statement.profile')
4915+ compl_lines = 0
4916+ stat_line_obj.check_access_rule(cr, uid, [], 'create')
4917+ stat_line_obj.check_access_rights(cr, uid, 'create', raise_exception=True)
4918+ for stat in self.browse(cr, uid, ids, context=context):
4919+ msg_lines = []
4920+ ctx = context.copy()
4921+ ctx['line_ids'] = tuple((x.id for x in stat.line_ids))
4922+ b_profile = stat.profile_id
4923+ rules = profile_obj._get_rules(cr, uid, b_profile, context=context)
4924+ profile_id = b_profile.id # Only for perfo even it gains almost nothing
4925+ master_account_id = b_profile.receivable_account_id
4926+ master_account_id = master_account_id.id if master_account_id else False
4927+ res = False
4928+ for line in stat_line_obj.read(cr, uid, ctx['line_ids']):
4929+ try:
4930+ # performance trick
4931+ line['master_account_id'] = master_account_id
4932+ line['profile_id'] = profile_id
4933+ res = stat_line_obj._get_line_values_from_rules(cr, uid, line,
4934+ rules, context=ctx)
4935+ if res:
4936+ compl_lines += 1
4937+ except ErrorTooManyPartner, exc:
4938+ msg_lines.append(repr(exc))
4939+ except Exception, exc:
4940+ msg_lines.append(repr(exc))
4941+ error_type, error_value, trbk = sys.exc_info()
4942+ st = "Error: %s\nDescription: %s\nTraceback:" % (error_type.__name__, error_value)
4943+ st += ''.join(traceback.format_tb(trbk, 30))
4944+ _logger.error(st)
4945+ if res:
4946+ #stat_line_obj.write(cr, uid, [line.id], vals, context=ctx)
4947+ try:
4948+ stat_line_obj._update_line(cr, uid, res, context=context)
4949+ except Exception as exc:
4950+ msg_lines.append(repr(exc))
4951+ error_type, error_value, trbk = sys.exc_info()
4952+ st = "Error: %s\nDescription: %s\nTraceback:" % (error_type.__name__, error_value)
4953+ st += ''.join(traceback.format_tb(trbk, 30))
4954+ _logger.error(st)
4955+ # we can commit as it is not needed to be atomic
4956+ # commiting here adds a nice perfo boost
4957+ if not compl_lines % 500:
4958+ cr.commit()
4959+ msg = u'\n'.join(msg_lines)
4960+ self.write_completion_log(cr, uid, stat.id,
4961+ msg, compl_lines, context=context)
4962+ return True
4963
4964=== added file 'account_statement_base_completion/statement_view.xml'
4965--- account_statement_base_completion/statement_view.xml 1970-01-01 00:00:00 +0000
4966+++ account_statement_base_completion/statement_view.xml 2014-03-27 09:24:37 +0000
4967@@ -0,0 +1,104 @@
4968+<?xml version="1.0" encoding="utf-8"?>
4969+<openerp>
4970+<data>
4971+
4972+ <record id="bank_statement_view_form" model="ir.ui.view">
4973+ <field name="name">account_bank_statement_import_base.bank_statement.view_form</field>
4974+ <field name="model">account.bank.statement</field>
4975+ <field name="inherit_id" ref="account.view_bank_statement_form" />
4976+ <field eval="16" name="priority"/>
4977+ <field name="type">form</field>
4978+ <field name="arch" type="xml">
4979+ <data>
4980+ <xpath expr="/form/sheet/notebook/page/field[@name='line_ids']/form/group/field[@name='sequence']" position="after">
4981+ <separator colspan="4" string="Importation related infos"/>
4982+ <field name="label" />
4983+ <field name="already_completed" />
4984+ </xpath>
4985+
4986+ <!-- <xpath expr="/form/group[2]" position="attributes">
4987+ <attribute name="col">10</attribute>
4988+ </xpath> -->
4989+
4990+ <button name="button_confirm_bank" position="before">
4991+ <button name="button_auto_completion" string="Auto Completion" states='draft,open' type="object" class="oe_highlight" icon="gtk-execute"/>
4992+ </button>
4993+
4994+ <xpath expr="/form/sheet/notebook/page[@string='Transactions']" position="after">
4995+ <page string="Completion Logs" attrs="{'invisible':[('completion_logs','=',False)]}">
4996+ <field name="completion_logs" colspan="4" nolabel="1" attrs="{'invisible':[('completion_logs','=',False)]}"/>
4997+ </page>
4998+ </xpath>
4999+
5000+ </data>
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to status/vote changes: