Merge lp:~camptocamp/banking-addons/bank-statement-reconcile-7.0-add-cancel-line-lep into lp:banking-addons/bank-statement-reconcile-70

Proposed by Leonardo Pistone
Status: Merged
Merged at revision: 158
Proposed branch: lp:~camptocamp/banking-addons/bank-statement-reconcile-7.0-add-cancel-line-lep
Merge into: lp:banking-addons/bank-statement-reconcile-70
Diff against target: 1235 lines (+1139/-0)
18 files modified
account_statement_cancel_line/__init__.py (+25/-0)
account_statement_cancel_line/__openerp__.py (+74/-0)
account_statement_cancel_line/i18n/account_statement_cancel_line.pot (+97/-0)
account_statement_cancel_line/i18n/fr.po (+97/-0)
account_statement_cancel_line/migrations/0.3/post-set-statement-line-state.py (+38/-0)
account_statement_cancel_line/statement.py (+118/-0)
account_statement_cancel_line/statement_line.py (+213/-0)
account_statement_cancel_line/statement_view.xml (+28/-0)
account_statement_cancel_line/test/cancel_line.yml (+80/-0)
account_statement_cancel_line/test/confirm_statement_no_double_moves.yml (+70/-0)
account_statement_cancel_line/test/test_confirm_last_line_balance_check.yml (+42/-0)
account_statement_cancel_line/test/test_confirm_last_line_no_balance_check.yml (+44/-0)
account_statement_cancel_line/wizard/__init__.py (+24/-0)
account_statement_cancel_line/wizard/cancel_line.py (+46/-0)
account_statement_cancel_line/wizard/cancel_statement.py (+51/-0)
account_statement_cancel_line/wizard/cancel_statement_line.py (+46/-0)
account_statement_cancel_line/wizard/cancel_statement_line_view.xml (+22/-0)
account_statement_cancel_line/wizard/cancel_statement_view.xml (+24/-0)
To merge this branch: bzr merge lp:~camptocamp/banking-addons/bank-statement-reconcile-7.0-add-cancel-line-lep
Reviewer Review Type Date Requested Status
Frederic Clementi - Camptocamp functional Approve
Nicolas Bessi - Camptocamp (community) no test, code review Approve
Leonardo Pistone Abstain
Stefan Rijnhart (Opener) Abstain
Joël Grand-Guillaume @ camptocamp code review, no tests Approve
Review via email: mp+202831@code.launchpad.net

Commit message

new module account_statement_cancel_line

Description of the change

New module account_statement_cancel_line. See __openep__.py for a description of what that does.

Thanks!

To post a comment you must log in.
Revision history for this message
Leonardo Pistone (lepistone) wrote :

After an internal review, I added french translations, and a migration file to set the state correctly on existing statements, and I also merged upstream.

Revision history for this message
Leonardo Pistone (lepistone) wrote :

I finished some fixes: an improved confirmation wizard, and a fix in the tests.

thanks!

Revision history for this message
Leonardo Pistone (lepistone) wrote :

I put this MP to 'work in progress' because I found a bug here. I'm doing a test and a fix.

Revision history for this message
Leonardo Pistone (lepistone) wrote :

I fixed the bug i'd found: if the last line in draft was confirmed and the statement confirmed, we were skipping the balance check.

I added two tests that show that.

Revision history for this message
Joël Grand-Guillaume @ camptocamp (jgrandguillaume-c2c) wrote :

LGTM, Thank you Leonardo

review: Approve (code review, no tests)
Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

Thanks for considering account_banking for your naming! Having this module will certainly help in merging the projects.

I tried to test the module, and was confronted by the dependency on account_default_draft_move. This dependency enforces alternative accounting practises which may be required in your region, but not in ours and should not be part of this change IMHO. Would you consider making this module agnostic towards the cancelling draft moves? With this, I mean that when cancelling a bank statement line, you can simply attempt to cancel and remove the associated move line and do the constraints in the various modules do their work.

review: Needs Information
Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

s/cancelling draft moves/cancelling *posted* moves/

obviously

Revision history for this message
Leonardo Pistone (lepistone) wrote :

Thanks for your review Stefan.

The point you raise makes sense to me. Speaking as a developer and not an accountant, making this module agnostic on account_default_draft_move would be probably feasible, but the integration test would break. That makes sense to me, since the business logic changes a bit.

In fact I would not feel at ease adapting the test, because the two workflows (with or without default_draft) seem like two scenarios that I'd like to test separately to be somewhat confident.

To do that properly, probably I would need to remove the dependency here, write new tests for the non-default-draft case, and then write a new module that depends on account_statement_cancel_line and account_default_draft_move, with the tests I have now.

So your proposal makes sense to me, but I am not prepared to do that right now - it does not cover my use case anyway.

I would be happy to review and accept such a change if someone does it.

Leo

Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

OK. Abstain for now then.

review: Abstain
Revision history for this message
Leonardo Pistone (lepistone) wrote :

oops, we found that that bug:

- create a statement with two lines
- confirm the first one
- confirm the whole statement

Then the first line gets two moves. At the moment, I pushed a yaml test to expose it.

review: Disapprove
132. By Leonardo Pistone

[fix] duplicate moves when confirming a statement with a confirmed line

Add a test to expose the bug.
To reproduce: create a statement with two lines, confirm one, and then confirm
the whole statement. The first line has two associated moves.

Revision history for this message
Leonardo Pistone (lepistone) wrote :

The bug should now be fixed, and we are green again.

review: Abstain
Revision history for this message
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote :

LGTM

review: Approve (no test, code review)
Revision history for this message
Frederic Clementi - Camptocamp (frederic-clementi) wrote :

Ok is fine.

Thanks leo

everything seems to work smoothly now.

review: Approve (functional)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added directory 'account_statement_cancel_line'
=== added file 'account_statement_cancel_line/__init__.py'
--- account_statement_cancel_line/__init__.py 1970-01-01 00:00:00 +0000
+++ account_statement_cancel_line/__init__.py 2014-06-13 10:06:12 +0000
@@ -0,0 +1,25 @@
1# -*- coding: utf-8 -*-
2###############################################################################
3# #
4# Author: Leonardo Pistone
5# Copyright 2014 Camptocamp SA
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU Affero General Public License as #
9# published by the Free Software Foundation, either version 3 of the #
10# License, or (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU Affero General Public License for more details. #
16# #
17# You should have received a copy of the GNU Affero General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21"""Account Statement Cancel Line."""
22
23import statement # noqa
24import statement_line # noqa
25import wizard # noqa
026
=== added file 'account_statement_cancel_line/__openerp__.py'
--- account_statement_cancel_line/__openerp__.py 1970-01-01 00:00:00 +0000
+++ account_statement_cancel_line/__openerp__.py 2014-06-13 10:06:12 +0000
@@ -0,0 +1,74 @@
1# -*- coding: utf-8 -*-
2###############################################################################
3# #
4# Author: Leonardo Pistone #
5# Copyright 2014 Camptocamp SA #
6# #
7# Inspired by module account_banking by EduSense BV, Therp BV, Smile #
8# #
9# This program is free software: you can redistribute it and/or modify #
10# it under the terms of the GNU Affero General Public License as #
11# published by the Free Software Foundation, either version 3 of the #
12# License, or (at your option) any later version. #
13# #
14# This program is distributed in the hope that it will be useful, #
15# but WITHOUT ANY WARRANTY; without even the implied warranty of #
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
17# GNU Affero General Public License for more details. #
18# #
19# You should have received a copy of the GNU Affero General Public License #
20# along with this program. If not, see <http://www.gnu.org/licenses/>. #
21# #
22###############################################################################
23{
24 'name': "Account Statement Cancel Line",
25 'version': '0.3',
26 'author': 'Camptocamp',
27 'maintainer': 'Camptocamp',
28 'category': 'Finance',
29 'complexity': 'normal',
30 'depends': [
31 'account',
32 'account_statement_ext',
33 'account_default_draft_move',
34 'account_statement_base_completion',
35 ],
36 'description': """
37 Account Statement Cancel Line
38
39 This module allows to cancel one line of the statement without
40 cancelling the whole thing.
41
42 To do that, a state is added to the statement line.
43
44 When the user confirms or cancels the whole statement, we keep the
45 previous functionality, and then we change the state in all statement
46 lines. We also add a warning if any lines are reconciled. If no lines
47 are reconciled, we show a generic warning because the operation could
48 take a long time.
49
50 When the user confirms or cancels a statement line, we update the state
51 of the line, and if necessary we update the state of the whole
52 statement, too.
53
54 If the user tries to cancel a line that is reconciled, we ask for
55 confirmation before proceeding.
56 """,
57 'website': 'http://www.camptocamp.com',
58 'init_xml': [],
59 'update_xml': [
60 'statement_view.xml',
61 'wizard/cancel_statement_view.xml',
62 'wizard/cancel_statement_line_view.xml',
63 ],
64 'demo_xml': [],
65 'test': [
66 'test/cancel_line.yml',
67 'test/test_confirm_last_line_balance_check.yml',
68 'test/test_confirm_last_line_no_balance_check.yml',
69 'test/confirm_statement_no_double_moves.yml',
70 ],
71 'installable': True,
72 'images': [],
73 'license': 'AGPL-3',
74}
075
=== added directory 'account_statement_cancel_line/i18n'
=== added file 'account_statement_cancel_line/i18n/account_statement_cancel_line.pot'
--- account_statement_cancel_line/i18n/account_statement_cancel_line.pot 1970-01-01 00:00:00 +0000
+++ account_statement_cancel_line/i18n/account_statement_cancel_line.pot 2014-06-13 10:06:12 +0000
@@ -0,0 +1,97 @@
1# Translation of OpenERP Server.
2# This file contains the translation of the following modules:
3# * account_statement_cancel_line
4#
5msgid ""
6msgstr ""
7"Project-Id-Version: OpenERP Server 7.0\n"
8"Report-Msgid-Bugs-To: \n"
9"POT-Creation-Date: 2014-02-17 16:46+0000\n"
10"PO-Revision-Date: 2014-02-17 16:46+0000\n"
11"Last-Translator: <>\n"
12"Language-Team: \n"
13"MIME-Version: 1.0\n"
14"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Transfer-Encoding: \n"
16"Plural-Forms: \n"
17
18#. module: account_statement_cancel_line
19#: model:ir.model,name:account_statement_cancel_line.model_account_bank_statement_line
20msgid "Bank Statement Line"
21msgstr ""
22
23#. module: account_statement_cancel_line
24#: view:wizard.cancel.statement:0
25#: view:wizard.cancel.statement.line:0
26msgid "Some entries are already reconciled. Do you want to unreconcile them and proceed?"
27msgstr ""
28
29#. module: account_statement_cancel_line
30#: view:account.bank.statement:0
31msgid "Cancel transaction"
32msgstr ""
33
34#. module: account_statement_cancel_line
35#: model:ir.model,name:account_statement_cancel_line.model_wizard_cancel_statement
36msgid "Cancel Statement"
37msgstr ""
38
39#. module: account_statement_cancel_line
40#: model:ir.model,name:account_statement_cancel_line.model_account_bank_statement
41msgid "Bank Statement"
42msgstr ""
43
44#. module: account_statement_cancel_line
45#: model:ir.model,name:account_statement_cancel_line.model_wizard_cancel_statement_line
46msgid "Cancel Statement Line"
47msgstr ""
48
49#. module: account_statement_cancel_line
50#: field:account.bank.statement.line,state:0
51msgid "State"
52msgstr ""
53
54#. module: account_statement_cancel_line
55#: view:wizard.cancel.statement:0
56#: view:wizard.cancel.statement.line:0
57msgid "Reconciled Entries"
58msgstr ""
59
60#. module: account_statement_cancel_line
61#: selection:account.bank.statement.line,state:0
62msgid "Draft"
63msgstr ""
64
65#. module: account_statement_cancel_line
66#: selection:account.bank.statement.line,state:0
67msgid "Confirmed"
68msgstr ""
69
70#. module: account_statement_cancel_line
71#: view:wizard.cancel.statement:0
72#: view:wizard.cancel.statement.line:0
73msgid "Cancel"
74msgstr ""
75
76#. module: account_statement_cancel_line
77#: view:account.bank.statement:0
78msgid "Confirm transaction"
79msgstr ""
80
81#. module: account_statement_cancel_line
82#: view:wizard.cancel.statement:0
83#: view:wizard.cancel.statement.line:0
84msgid "Unreconcile"
85msgstr ""
86
87#. module: account_statement_cancel_line
88#: view:wizard.cancel.statement:0
89#: view:wizard.cancel.statement.line:0
90msgid "or"
91msgstr ""
92
93#. module: account_statement_cancel_line
94#: view:wizard.cancel.statement:0
95#: view:wizard.cancel.statement.line:0
96msgid "Unreconciliation"
97msgstr ""
098
=== added file 'account_statement_cancel_line/i18n/fr.po'
--- account_statement_cancel_line/i18n/fr.po 1970-01-01 00:00:00 +0000
+++ account_statement_cancel_line/i18n/fr.po 2014-06-13 10:06:12 +0000
@@ -0,0 +1,97 @@
1# Translation of OpenERP Server.
2# This file contains the translation of the following modules:
3# * account_statement_cancel_line
4#
5msgid ""
6msgstr ""
7"Project-Id-Version: OpenERP Server 7.0\n"
8"Report-Msgid-Bugs-To: \n"
9"POT-Creation-Date: 2014-02-17 15:59+0000\n"
10"PO-Revision-Date: 2014-02-17 15:59+0000\n"
11"Last-Translator: <>\n"
12"Language-Team: \n"
13"MIME-Version: 1.0\n"
14"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Transfer-Encoding: \n"
16"Plural-Forms: \n"
17
18#. module: account_statement_cancel_line
19#: model:ir.model,name:account_statement_cancel_line.model_account_bank_statement_line
20msgid "Bank Statement Line"
21msgstr "Ligne de relevé bancaire"
22
23#. module: account_statement_cancel_line
24#: view:wizard.cancel.statement:0
25#: view:wizard.cancel.statement.line:0
26msgid "Some entries are already reconciled. Do you want to unreconcile them and proceed?"
27msgstr "Certaines écritures sont déja léttrées. Voulez-vous annuler définitivement tout les léttrages et poursuivre?"
28
29#. module: account_statement_cancel_line
30#: view:account.bank.statement:0
31msgid "Cancel transaction"
32msgstr "Annuler ligne"
33
34#. module: account_statement_cancel_line
35#: model:ir.model,name:account_statement_cancel_line.model_wizard_cancel_statement
36msgid "Cancel Statement"
37msgstr "Annuler le relevé"
38
39#. module: account_statement_cancel_line
40#: model:ir.model,name:account_statement_cancel_line.model_account_bank_statement
41msgid "Bank Statement"
42msgstr "Relevé bancaire"
43
44#. module: account_statement_cancel_line
45#: model:ir.model,name:account_statement_cancel_line.model_wizard_cancel_statement_line
46msgid "Cancel Statement Line"
47msgstr "Annuler ligne de relevé"
48
49#. module: account_statement_cancel_line
50#: field:account.bank.statement.line,state:0
51msgid "State"
52msgstr "Etat"
53
54#. module: account_statement_cancel_line
55#: view:wizard.cancel.statement:0
56#: view:wizard.cancel.statement.line:0
57msgid "Reconciled Entries"
58msgstr "Lignes léttrées"
59
60#. module: account_statement_cancel_line
61#: selection:account.bank.statement.line,state:0
62msgid "Draft"
63msgstr "Brouillon"
64
65#. module: account_statement_cancel_line
66#: selection:account.bank.statement.line,state:0
67msgid "Confirmed"
68msgstr "Confirmée"
69
70#. module: account_statement_cancel_line
71#: view:wizard.cancel.statement:0
72#: view:wizard.cancel.statement.line:0
73msgid "Cancel"
74msgstr "Annuler"
75
76#. module: account_statement_cancel_line
77#: view:account.bank.statement:0
78msgid "Confirm transaction"
79msgstr "Confirmer ligne"
80
81#. module: account_statement_cancel_line
82#: view:wizard.cancel.statement:0
83#: view:wizard.cancel.statement.line:0
84msgid "Unreconcile"
85msgstr "Déléttrer"
86
87#. module: account_statement_cancel_line
88#: view:wizard.cancel.statement:0
89#: view:wizard.cancel.statement.line:0
90msgid "or"
91msgstr "ou"
92
93#. module: account_statement_cancel_line
94#: view:wizard.cancel.statement:0
95#: view:wizard.cancel.statement.line:0
96msgid "Unreconciliation"
97msgstr "Déléttrage"
098
=== added directory 'account_statement_cancel_line/migrations'
=== added directory 'account_statement_cancel_line/migrations/0.3'
=== added file 'account_statement_cancel_line/migrations/0.3/post-set-statement-line-state.py'
--- account_statement_cancel_line/migrations/0.3/post-set-statement-line-state.py 1970-01-01 00:00:00 +0000
+++ account_statement_cancel_line/migrations/0.3/post-set-statement-line-state.py 2014-06-13 10:06:12 +0000
@@ -0,0 +1,38 @@
1# -*- coding: utf-8 -*-
2###############################################################################
3# #
4# Author: Leonardo Pistone #
5# Copyright 2014 Camptocamp SA #
6# #
7# Inspired by module account_banking by EduSense BV, Therp BV, Smile #
8# #
9# This program is free software: you can redistribute it and/or modify #
10# it under the terms of the GNU Affero General Public License as #
11# published by the Free Software Foundation, either version 3 of the #
12# License, or (at your option) any later version. #
13# #
14# This program is distributed in the hope that it will be useful, #
15# but WITHOUT ANY WARRANTY; without even the implied warranty of #
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
17# GNU Affero General Public License for more details. #
18# #
19# You should have received a copy of the GNU Affero General Public License #
20# along with this program. If not, see <http://www.gnu.org/licenses/>. #
21# #
22###############################################################################
23
24__name__ = ("account.bank.statement.line:: set new field 'state' to "
25 "confirmed for all statement lines belonging to confirmed "
26 "statements")
27
28
29def migrate(cr, version):
30 """This module adds the field state to the statement line. Here we set it
31 correctly on existing statements. The names, and so this migration, are
32 intentionally kept in sync with the account_banking module."""
33 cr.execute("UPDATE account_bank_statement_line as sl "
34 " SET state = 'confirmed'"
35 " FROM account_bank_statement as s "
36 " WHERE sl.statement_id = s.id "
37 " AND s.state = 'confirm' "
38 )
039
=== added file 'account_statement_cancel_line/statement.py'
--- account_statement_cancel_line/statement.py 1970-01-01 00:00:00 +0000
+++ account_statement_cancel_line/statement.py 2014-06-13 10:06:12 +0000
@@ -0,0 +1,118 @@
1# -*- coding: utf-8 -*-
2###############################################################################
3# #
4# Author: Leonardo Pistone
5# Copyright 2014 Camptocamp SA
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU Affero General Public License as #
9# published by the Free Software Foundation, either version 3 of the #
10# License, or (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU Affero General Public License for more details. #
16# #
17# You should have received a copy of the GNU Affero General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21"""Account Statement Cancel Line."""
22
23from openerp.osv import orm
24
25
26class Statement(orm.Model):
27
28 """Bank Statement.
29
30 Minimal changes to allow cancelling single lines and checking if there are
31 any lines that are already reconciled.
32
33 """
34
35 _inherit = "account.bank.statement"
36
37 def button_confirm_bank(self, cr, uid, ids, context=None):
38 """If all lines are draft, change their state.
39 Otherwise, confirm line by line to avoid duplicate moves.
40 Return super.
41
42 """
43 st_line_obj = self.pool['account.bank.statement.line']
44
45 statement_ids_fully_confirm = []
46 for st in self.browse(cr, uid, ids, context=context):
47 if all(l.state == 'draft' for l in st.line_ids):
48 statement_ids_fully_confirm.append(st.id)
49 st_line_obj.write(cr, uid, [l.id for l in st.line_ids], {
50 'state': 'confirmed'
51 }, context=context)
52 else:
53 st_line_obj.confirm(cr, uid, [l.id for l in st.line_ids],
54 context=context)
55
56 if statement_ids_fully_confirm:
57 return super(Statement, self).button_confirm_bank(
58 cr, uid, statement_ids_fully_confirm, context)
59 else:
60 return True
61
62 def button_cancel(self, cr, uid, ids, context=None):
63 """Check if there is any reconciliation. Return action."""
64 st_line_obj = self.pool['account.bank.statement.line']
65 for statement in self.browse(cr, uid, ids, context=context):
66 ctx = context.copy()
67 ctx['default_reconcile_warning'] = st_line_obj.has_reconciliation(
68 cr,
69 uid,
70 [line.id for line in statement.line_ids],
71 context=context)
72 return {
73 'type': 'ir.actions.act_window',
74 'res_model': 'wizard.cancel.statement',
75 'view_type': 'form',
76 'view_mode': 'form',
77 'target': 'new',
78 'context': ctx,
79 }
80
81 self.do_cancel(cr, uid, ids, context=context)
82
83 def do_cancel(self, cr, uid, ids, context=None):
84 """Change the state on the statement lines. Return super.
85
86 This method is called directly when there are no reconciliations, or
87 from the warning wizard, if there are reconciliations.
88
89 """
90 st_line_obj = self.pool['account.bank.statement.line']
91 for st_data in self.read(cr, uid, ids, ['line_ids'], context=context):
92 st_line_obj.write(cr, uid, st_data['line_ids'], {
93 'state': 'draft'
94 }, context=context)
95
96 return super(Statement, self).button_cancel(
97 cr, uid, ids, context)
98
99 def confirm_statement_from_lines(self, cr, uid, ids, context=None):
100 """If all lines are confirmed, so is the whole statement.
101
102 Return True if we changed anything.
103
104 """
105 need_to_update_view = False
106 for statement in self.browse(cr, uid, ids, context=context):
107 if all(line.state == 'confirmed' for line in statement.line_ids):
108 self.write(cr, uid, [statement.id], {
109 'state': 'confirm'
110 }, context=context)
111 need_to_update_view = True
112 self.balance_check(
113 cr,
114 uid,
115 statement.id,
116 journal_type=statement.journal_id.type,
117 context=context)
118 return need_to_update_view
0119
=== added file 'account_statement_cancel_line/statement_line.py'
--- account_statement_cancel_line/statement_line.py 1970-01-01 00:00:00 +0000
+++ account_statement_cancel_line/statement_line.py 2014-06-13 10:06:12 +0000
@@ -0,0 +1,213 @@
1# -*- coding: utf-8 -*-
2###############################################################################
3# #
4# Author: Leonardo Pistone
5# Copyright 2014 Camptocamp SA
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU Affero General Public License as #
9# published by the Free Software Foundation, either version 3 of the #
10# License, or (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU Affero General Public License for more details. #
16# #
17# You should have received a copy of the GNU Affero General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21"""Account Statement Cancel Line."""
22
23from openerp.osv import fields, orm
24
25from openerp.tools.translate import _
26
27
28class StatementLine(orm.Model):
29
30 """Add a state to the statement line."""
31
32 _inherit = "account.bank.statement.line"
33
34 _columns = {
35 'state': fields.selection(
36 [('draft', 'Draft'), ('confirmed', 'Confirmed')],
37 'State',
38 readonly=True,
39 required=True
40 ),
41 }
42
43 _defaults = {
44 'state': 'draft',
45 }
46
47 def confirm(self, cr, uid, ids, context=None):
48 """Confirm just one statement line, return action.
49
50 The module account_banking does have a similar method, but at the
51 moment it uses a different logic (for example, it uses vouchers, where
52 the bank-statement-reconcile branch does not).
53
54 """
55 if context is None:
56 context = {}
57 local_ctx = context.copy()
58 # if account_constraints is installed, we need to tell it that moves
59 # are being created by a statement, which is OK.
60 # The module tries to prevent direct changes to the moves created by
61 # bank statements.
62 local_ctx['from_parent_object'] = True
63
64 statement_pool = self.pool.get('account.bank.statement')
65 res = {}
66
67 for st_line in self.browse(cr, uid, ids, context):
68 if st_line.state != 'draft':
69 continue
70 st = st_line.statement_id
71 curr_id = st.journal_id.company_id.currency_id.id
72
73 st_number = st.name
74 st_line_number = statement_pool.get_next_st_line_number(
75 cr, uid, st_number, st_line, context)
76
77 # We pass the local_ctx so that account_constraints allows us to
78 # work on the moves generated by the bank statement
79 statement_pool.create_move_from_st_line(
80 cr,
81 uid,
82 st_line.id,
83 curr_id,
84 st_line_number,
85 local_ctx)
86 self.write(cr, uid, st_line.id, {
87 'state': 'confirmed'
88 }, context)
89 if statement_pool.confirm_statement_from_lines(cr, uid, [st.id],
90 context=context):
91 # to see that the state of the statement has changed, we need
92 # to update the whole view. Do that only if necessary.
93 res = {
94 'type': 'ir.actions.client',
95 'tag': 'reload',
96 }
97
98 return res
99
100 def has_reconciliation(self, cr, uid, ids, context=None):
101 """Check if the line has some reconciliation. Return boolean."""
102 if context is None:
103 context = {}
104
105 for st_line in self.browse(cr, uid, ids, context=context):
106 for move in st_line.move_ids:
107 for move_line in move.line_id:
108 if move_line.reconcile:
109 # aha! we have some reconciliation!
110 return True
111
112 # no reconciliation to worry about
113 return False
114
115 def button_cancel(self, cr, uid, ids, context=None):
116 """Check if a line is reconciled, and cancel it. Return action."""
117 if context is None:
118 context = {}
119
120 if self.has_reconciliation(cr, uid, ids, context=context):
121 # ask confirmation, we have some reconciliation already
122 return {
123 'type': 'ir.actions.act_window',
124 'res_model': 'wizard.cancel.statement.line',
125 'view_type': 'form',
126 'view_mode': 'form',
127 'target': 'new',
128 'context': context,
129 }
130
131 # no reconciliation to worry about: we cancel our lines directly then
132 return self.cancel(cr, uid, ids, context=context)
133
134 def cancel(self, cr, uid, ids, context=None):
135 """Cancel one statement line, return action.
136
137 This is again similar to the method cancel in the account_banking
138 module.
139
140 """
141 if context is None:
142 context = {}
143 local_ctx = context.copy()
144 # if account_constraints is installed, we need to tell it that moves
145 # are being created by a statement, which is OK.
146 # The module tries to prevent direct changes to the moves created by
147 # bank statements.
148 local_ctx['from_parent_object'] = True
149
150 move_pool = self.pool['account.move']
151 statement_pool = self.pool['account.bank.statement']
152
153 st_line_ids = []
154
155 # to avoid duplicates if all lines come from the same statement
156 statement_ids = set()
157
158 move_unlink_ids = []
159 # harvest ids for various actions
160 for st_line in self.browse(cr, uid, ids, context):
161 if st_line.state != 'confirmed':
162 continue
163
164 for move in st_line.move_ids:
165 # We allow for people canceling and removing
166 # the associated payments, which can lead to confirmed
167 # statement lines without an associated move
168 move_unlink_ids.append(move.id)
169 # do we need to check that?
170 if move.state != 'draft':
171 raise orm.except_orm(
172 _('Confirmed Journal Entry'),
173 _('You cannot delete a confirmed Statement Line '
174 'associated to a Journal Entry that is posted.'))
175 st_line_ids.append(st_line.id)
176 if st_line.statement_id.state != 'draft':
177 statement_ids.add(st_line.statement_id.id)
178
179 move_pool.button_cancel(
180 cr, uid, move_unlink_ids, context=context)
181
182 move_pool.unlink(cr, uid, move_unlink_ids, context=local_ctx)
183 self.write(cr, uid, st_line_ids, {
184 'state': 'draft',
185 'already_completed': False
186 }, context=context)
187 if statement_ids:
188 # if we cancel one or more lines, the statement goes back to draft,
189 # too
190 statement_pool.write(cr, uid, list(statement_ids), {
191 'state': 'draft'
192 }, context=context)
193 # then we manually update the view of the statement
194 return {
195 'type': 'ir.actions.client',
196 'tag': 'reload',
197 }
198 else:
199 # no need to update the view then
200 return {}
201
202 def unlink(self, cr, uid, ids, context=None):
203 """Don't allow deletion of a confirmed statement line. Return super."""
204 if type(ids) is int:
205 ids = [ids]
206 for line in self.browse(cr, uid, ids, context=context):
207 if line.state == 'confirmed':
208 raise orm.except_orm(
209 _('Confirmed Statement Line'),
210 _("You cannot delete a confirmed Statement Line"
211 ": '%s'") % line.name)
212 return super(StatementLine, self).unlink(
213 cr, uid, ids, context=context)
0214
=== added file 'account_statement_cancel_line/statement_view.xml'
--- account_statement_cancel_line/statement_view.xml 1970-01-01 00:00:00 +0000
+++ account_statement_cancel_line/statement_view.xml 2014-06-13 10:06:12 +0000
@@ -0,0 +1,28 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4
5 <record id="view_bank_statement_form_cancel_line" model="ir.ui.view">
6 <field name="name">account.bank.statement.form.</field>
7 <field name="inherit_id" ref="account.view_bank_statement_form" />
8 <field name="model">account.bank.statement</field>
9 <field name="arch" type="xml">
10 <data>
11 <xpath expr="//field[@name='line_ids']/tree/field[@name='amount']"
12 position="after">
13 <field name="state"/>
14 <button name="confirm" states="draft"
15 string="Confirm transaction"
16 icon="gtk-ok"
17 type="object"/>
18 <button name="button_cancel" states="confirmed"
19 string="Cancel transaction"
20 icon="gtk-cancel"
21 type="object"/>
22 </xpath>
23 </data>
24 </field>
25 </record>
26
27 </data>
28</openerp>
029
=== added directory 'account_statement_cancel_line/test'
=== added file 'account_statement_cancel_line/test/cancel_line.yml'
--- account_statement_cancel_line/test/cancel_line.yml 1970-01-01 00:00:00 +0000
+++ account_statement_cancel_line/test/cancel_line.yml 2014-06-13 10:06:12 +0000
@@ -0,0 +1,80 @@
1-
2 In order to test the cancellation of statement lines, I need a statement
3 profile.
4-
5 !record {model: account.statement.profile, id: profile_test}:
6 name: Bank EUR Profile for automatic checks
7 journal_id: account.bank_journal
8 commission_account_id: account.a_expense
9 company_id: base.main_company
10-
11 Now I create a statement. I create statment lines separately because I need
12 to find each one by XML id
13-
14 !record {model: account.bank.statement, id: statement_test}:
15 name: My Statement
16 profile_id: profile_test
17 company_id: base.main_company
18-
19 I create a first statement line
20-
21 !record {model: account.bank.statement.line, id: statement_line_1}:
22 name: line1
23 statement_id: statement_test
24 ref: ref1
25 date: '2014-01-20'
26 amount: 100.0
27-
28 I create a second statement line
29-
30 !record {model: account.bank.statement.line, id: statement_line_2}:
31 name: line2
32 statement_id: statement_test
33 ref: ref2
34 date: '2014-01-25'
35 amount: 200.0
36-
37 I check that the state of the statement is "Draft"
38-
39 !assert {model: account.bank.statement, id: statement_test}:
40 - state == 'draft'
41-
42 I confirm the statement
43-
44 !python {model: account.bank.statement}: |
45 result = self.button_confirm_bank(cr, uid, [ref("statement_test")])
46-
47 I check that the state of the statement is "Closed"
48-
49 !assert {model: account.bank.statement, id: statement_test}:
50 - state == 'confirm'
51-
52 I check that the state of the statement line is "Confirmed"
53-
54 !assert {model: account.bank.statement.line, id: statement_line_1}:
55 - state == 'confirmed'
56-
57 I check that a move was generated
58-
59 !assert {model: account.bank.statement.line, id: statement_line_1}:
60 - move_ids
61-
62 Now I cancel a statement line
63-
64 !python {model: account.bank.statement.line}: |
65 result = self.button_cancel(cr, uid, [ref("statement_line_1")])
66-
67 I check that the state of the statement went back to "Draft"
68-
69 !assert {model: account.bank.statement, id: statement_test}:
70 - state == 'draft'
71-
72 I also check that the state of the statement line went back to "Draft"
73-
74 !assert {model: account.bank.statement.line, id: statement_line_1}:
75 - state == 'draft'
76-
77 And the move is not there anymore
78-
79 !assert {model: account.bank.statement.line, id: statement_line_1}:
80 - move_ids == []
081
=== added file 'account_statement_cancel_line/test/confirm_statement_no_double_moves.yml'
--- account_statement_cancel_line/test/confirm_statement_no_double_moves.yml 1970-01-01 00:00:00 +0000
+++ account_statement_cancel_line/test/confirm_statement_no_double_moves.yml 2014-06-13 10:06:12 +0000
@@ -0,0 +1,70 @@
1-
2 I want to check that if I confirm a line and then the whole statement,
3 no duplicate moves are created.
4 First, I need a statement profile.
5-
6 !record {model: account.statement.profile, id: profile_test_10}:
7 name: Another Bank EUR Profile for automatic checks
8 journal_id: account.bank_journal
9 commission_account_id: account.a_expense
10 company_id: base.main_company
11-
12 Now I create a statement. I create statment lines separately because I need
13 to find each one by XML id
14-
15 !record {model: account.bank.statement, id: statement_test_10}:
16 name: My Statement
17 profile_id: profile_test_10
18 company_id: base.main_company
19-
20 I create a first statement line
21-
22 !record {model: account.bank.statement.line, id: statement_line_11}:
23 name: line11
24 statement_id: statement_test_10
25 ref: ref11
26 date: '2014-01-20'
27 amount: 100.0
28-
29 I create a second statement line
30-
31 !record {model: account.bank.statement.line, id: statement_line_12}:
32 name: line12
33 statement_id: statement_test_10
34 ref: ref12
35 date: '2014-01-25'
36 amount: 200.0
37-
38 Now I confirm only the first statement line
39-
40 !python {model: account.bank.statement.line}: |
41 result = self.confirm(cr, uid, [ref("statement_line_11")])
42-
43 I check that the state of the statement is still "Draft"
44-
45 !assert {model: account.bank.statement, id: statement_test_10}:
46 - state == 'draft'
47-
48 I confirm the statement
49-
50 !python {model: account.bank.statement}: |
51 result = self.button_confirm_bank(cr, uid, [ref("statement_test_10")])
52-
53 I check that the state of the statement is "Closed"
54-
55 !assert {model: account.bank.statement, id: statement_test_10}:
56 - state == 'confirm'
57-
58 I check that a move was generated for the first statment line
59 and that the state is confirmed
60-
61 !assert {model: account.bank.statement.line, id: statement_line_11}:
62 - len(move_ids) == 1
63 - state == 'confirmed'
64-
65 I check that a move was generated for the second statment line
66 and that the state is confirmed
67-
68 !assert {model: account.bank.statement.line, id: statement_line_12}:
69 - len(move_ids) == 1
70 - state == 'confirmed'
071
=== added file 'account_statement_cancel_line/test/test_confirm_last_line_balance_check.yml'
--- account_statement_cancel_line/test/test_confirm_last_line_balance_check.yml 1970-01-01 00:00:00 +0000
+++ account_statement_cancel_line/test/test_confirm_last_line_balance_check.yml 2014-06-13 10:06:12 +0000
@@ -0,0 +1,42 @@
1-
2 I want to check that the behaviour when I confirm the only line of a
3 statement that is draft.
4-
5 I start with a profile
6-
7 !record {model: account.statement.profile, id: profile_test3}:
8 name: Profile for automatic checks
9 balance_check: True
10 journal_id: account.bank_journal
11 commission_account_id: account.a_expense
12-
13 Now I create a statement.
14-
15 !record {model: account.bank.statement, id: statement_test3}:
16 name: My Statement
17 profile_id: profile_test3
18 company_id: base.main_company
19 balance_start: 100.0
20 balance_end_real: 150.0
21-
22 I create a statement line
23-
24 !record {model: account.bank.statement.line, id: statement_line_3}:
25 name: line1
26 statement_id: statement_test3
27 ref: line1
28 date: '2014-01-20'
29 amount: 10.0
30-
31 Now I confirm the statement line. That should not pass the balance check
32-
33 !python {model: account.bank.statement.line}: |
34 # i.e. assertRaises
35 from openerp.osv.osv import except_osv
36 try:
37 self.confirm(cr, uid, [ref("statement_line_3")])
38 except except_osv as exc:
39 print exc.args
40 assert u'The statement balance is incorrect' in exc.args[1], 'We got an error which is not what we expected'
41 else:
42 raise AssertionError('Balance check should have blocked this.')
043
=== added file 'account_statement_cancel_line/test/test_confirm_last_line_no_balance_check.yml'
--- account_statement_cancel_line/test/test_confirm_last_line_no_balance_check.yml 1970-01-01 00:00:00 +0000
+++ account_statement_cancel_line/test/test_confirm_last_line_no_balance_check.yml 2014-06-13 10:06:12 +0000
@@ -0,0 +1,44 @@
1-
2 I want to check that the behaviour when I confirm the only line of a
3 statement that is draft.
4-
5 I start with a profile
6-
7 !record {model: account.statement.profile, id: profile_test4}:
8 name: Profile for automatic checks
9 balance_check: False
10 journal_id: account.bank_journal
11 commission_account_id: account.a_expense
12-
13 Now I create a statement.
14-
15 !record {model: account.bank.statement, id: statement_test4}:
16 name: My Statement
17 profile_id: profile_test4
18 company_id: base.main_company
19 balance_start: 100.0
20 balance_end_real: 150.0
21-
22 I create a statement line
23-
24 !record {model: account.bank.statement.line, id: statement_line_4}:
25 name: line1
26 statement_id: statement_test4
27 ref: line1
28 date: '2014-01-20'
29 amount: 10.0
30-
31 Now I confirm the statement line
32-
33 !python {model: account.bank.statement.line}: |
34 result = self.confirm(cr, uid, [ref("statement_line_4")])
35-
36 The line should be confirmed
37-
38 !assert {model: account.bank.statement.line, id: statement_line_4}:
39 - state == 'confirmed'
40-
41 And the statement should be confirmed as well
42-
43 !assert {model: account.bank.statement, id: statement_test4}:
44 - state == 'confirm'
045
=== added directory 'account_statement_cancel_line/tests'
=== added directory 'account_statement_cancel_line/wizard'
=== added file 'account_statement_cancel_line/wizard/__init__.py'
--- account_statement_cancel_line/wizard/__init__.py 1970-01-01 00:00:00 +0000
+++ account_statement_cancel_line/wizard/__init__.py 2014-06-13 10:06:12 +0000
@@ -0,0 +1,24 @@
1# -*- coding: utf-8 -*-
2###############################################################################
3# #
4# Author: Leonardo Pistone
5# Copyright 2014 Camptocamp SA
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU Affero General Public License as #
9# published by the Free Software Foundation, either version 3 of the #
10# License, or (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU Affero General Public License for more details. #
16# #
17# You should have received a copy of the GNU Affero General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21"""Wizard for asking the confirmation when some move is reconciled."""
22
23import cancel_statement # noqa
24import cancel_statement_line # noqa
025
=== added file 'account_statement_cancel_line/wizard/cancel_line.py'
--- account_statement_cancel_line/wizard/cancel_line.py 1970-01-01 00:00:00 +0000
+++ account_statement_cancel_line/wizard/cancel_line.py 2014-06-13 10:06:12 +0000
@@ -0,0 +1,46 @@
1# -*- coding: utf-8 -*-
2###############################################################################
3# #
4# Author: Leonardo Pistone
5# Copyright 2014 Camptocamp SA
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU Affero General Public License as #
9# published by the Free Software Foundation, either version 3 of the #
10# License, or (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU Affero General Public License for more details. #
16# #
17# You should have received a copy of the GNU Affero General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21"""Wizard to Cancel a Statement Line."""
22
23from openerp.osv import orm
24
25
26class wizard_cancel_statement_line(orm.TransientModel):
27
28 """Wizard to Cancel a Statement Line."""
29
30 _name = "wizard.cancel.statement.line"
31 _description = "Cancel Statement Line"
32 _columns = {
33 }
34
35 def unreconcile(self, cr, uid, ids, context=None):
36 """Proceed and cancel the statement line, return Action.
37
38 This will delete the move.line and the reconciliation.
39
40 """
41 return self.pool['account.bank.statement.line'].cancel(
42 cr,
43 uid,
44 context['active_ids'],
45 context=context
46 )
047
=== added file 'account_statement_cancel_line/wizard/cancel_statement.py'
--- account_statement_cancel_line/wizard/cancel_statement.py 1970-01-01 00:00:00 +0000
+++ account_statement_cancel_line/wizard/cancel_statement.py 2014-06-13 10:06:12 +0000
@@ -0,0 +1,51 @@
1# -*- coding: utf-8 -*-
2###############################################################################
3# #
4# Author: Leonardo Pistone
5# Copyright 2014 Camptocamp SA
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU Affero General Public License as #
9# published by the Free Software Foundation, either version 3 of the #
10# License, or (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU Affero General Public License for more details. #
16# #
17# You should have received a copy of the GNU Affero General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21"""Wizard to Cancel a Statement."""
22
23from openerp.osv import orm, fields
24
25
26class wizard_cancel_statement(orm.TransientModel):
27
28 """Wizard to Cancel a Statement."""
29
30 _name = "wizard.cancel.statement"
31 _description = "Cancel Statement"
32 _columns = {
33 'reconcile_warning': fields.boolean(
34 'Show reconcile warning',
35 help='This is a hidden field set with a default in the context '
36 'to choose between two different warning messages in the view.'
37 ),
38 }
39
40 def do_cancel_button(self, cr, uid, ids, context=None):
41 """Proceed and cancel the statement, return Action.
42
43 This will delete the move.line and the reconciliation.
44
45 """
46 return self.pool['account.bank.statement'].do_cancel(
47 cr,
48 uid,
49 context['active_ids'],
50 context=context
51 )
052
=== added file 'account_statement_cancel_line/wizard/cancel_statement_line.py'
--- account_statement_cancel_line/wizard/cancel_statement_line.py 1970-01-01 00:00:00 +0000
+++ account_statement_cancel_line/wizard/cancel_statement_line.py 2014-06-13 10:06:12 +0000
@@ -0,0 +1,46 @@
1# -*- coding: utf-8 -*-
2###############################################################################
3# #
4# Author: Leonardo Pistone
5# Copyright 2014 Camptocamp SA
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU Affero General Public License as #
9# published by the Free Software Foundation, either version 3 of the #
10# License, or (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU Affero General Public License for more details. #
16# #
17# You should have received a copy of the GNU Affero General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21"""Wizard to Cancel a Statement Line."""
22
23from openerp.osv import orm
24
25
26class wizard_cancel_statement_line(orm.TransientModel):
27
28 """Wizard to Cancel a Statement Line."""
29
30 _name = "wizard.cancel.statement.line"
31 _description = "Cancel Statement Line"
32 _columns = {
33 }
34
35 def unreconcile(self, cr, uid, ids, context=None):
36 """Proceed and cancel the statement line, return Action.
37
38 This will delete the move.line and the reconciliation.
39
40 """
41 return self.pool['account.bank.statement.line'].cancel(
42 cr,
43 uid,
44 context['active_ids'],
45 context=context
46 )
047
=== added file 'account_statement_cancel_line/wizard/cancel_statement_line_view.xml'
--- account_statement_cancel_line/wizard/cancel_statement_line_view.xml 1970-01-01 00:00:00 +0000
+++ account_statement_cancel_line/wizard/cancel_statement_line_view.xml 2014-06-13 10:06:12 +0000
@@ -0,0 +1,22 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4
5 <record id="view_wizard_cancel_statement_line_form" model="ir.ui.view">
6 <field name="name">view.wizard.cancel.statement.line.form</field>
7 <field name="model">wizard.cancel.statement.line</field>
8 <field name="arch" type="xml">
9 <form string="Reconciled Entries" version="7.0">
10 <separator string="Unreconciliation"/>
11 <label string="Some entries are already reconciled. Do you want to unreconcile them and proceed?"/>
12 <footer>
13 <button name="unreconcile" string="Unreconcile" type="object" class="oe_highlight"/>
14 or
15 <button string="Cancel" class="oe_link" special="cancel"/>
16 </footer>
17 </form>
18 </field>
19 </record>
20
21 </data>
22</openerp>
023
=== added file 'account_statement_cancel_line/wizard/cancel_statement_view.xml'
--- account_statement_cancel_line/wizard/cancel_statement_view.xml 1970-01-01 00:00:00 +0000
+++ account_statement_cancel_line/wizard/cancel_statement_view.xml 2014-06-13 10:06:12 +0000
@@ -0,0 +1,24 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4
5 <record id="view_wizard_cancel_statement_form" model="ir.ui.view">
6 <field name="name">view.wizard.cancel.statement.form</field>
7 <field name="model">wizard.cancel.statement</field>
8 <field name="arch" type="xml">
9 <form string="Reconciled Entries" version="7.0">
10 <separator string="Cancel statement"/>
11 <field name="reconcile_warning" invisible="1" />
12 <label attrs="{'invisible': [('reconcile_warning', '=', False)]}" string="Some entries are already reconciled. Do you want to unreconcile them and proceed?"/>
13 <label attrs="{'invisible': [('reconcile_warning', '=', True)]}" string="Cancelling the statement will delete the generated Journal Entries (if un posted) and could take a long time for a long statement. Do you want to proceed?"/>
14 <footer>
15 <button name="do_cancel_button" string="Proceed" type="object" class="oe_highlight"/>
16 or
17 <button string="Cancel" class="oe_link" special="cancel"/>
18 </footer>
19 </form>
20 </field>
21 </record>
22
23 </data>
24</openerp>

Subscribers

People subscribed via source and target branches