Merge lp:~camptocamp/banking-addons/bank-statement-reconcile-7.0-add-cancel-line-lep into lp:banking-addons/bank-statement-reconcile-70
- bank-statement-reconcile-7.0-add-cancel-line-lep
- Merge into bank-statement-reconcile-70
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 |
Related bugs: |
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_
Description of the change
New module account_
Thanks!
Leonardo Pistone (lepistone) wrote : | # |
Leonardo Pistone (lepistone) wrote : | # |
I finished some fixes: an improved confirmation wizard, and a fix in the tests.
thanks!
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.
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.
Joël Grand-Guillaume @ camptocamp (jgrandguillaume-c2c) wrote : | # |
LGTM, Thank you Leonardo
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_
Stefan Rijnhart (Opener) (stefan-opener) wrote : | # |
s/cancelling draft moves/cancelling *posted* moves/
obviously
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_
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_
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
Stefan Rijnhart (Opener) (stefan-opener) wrote : | # |
OK. Abstain for now then.
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.
- 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.
Leonardo Pistone (lepistone) wrote : | # |
The bug should now be fixed, and we are green again.
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote : | # |
LGTM
Frederic Clementi - Camptocamp (frederic-clementi) wrote : | # |
Ok is fine.
Thanks leo
everything seems to work smoothly now.
Preview Diff
1 | === added directory 'account_statement_cancel_line' | |||
2 | === added file 'account_statement_cancel_line/__init__.py' | |||
3 | --- account_statement_cancel_line/__init__.py 1970-01-01 00:00:00 +0000 | |||
4 | +++ account_statement_cancel_line/__init__.py 2014-06-13 10:06:12 +0000 | |||
5 | @@ -0,0 +1,25 @@ | |||
6 | 1 | # -*- coding: utf-8 -*- | ||
7 | 2 | ############################################################################### | ||
8 | 3 | # # | ||
9 | 4 | # Author: Leonardo Pistone | ||
10 | 5 | # Copyright 2014 Camptocamp SA | ||
11 | 6 | # # | ||
12 | 7 | # This program is free software: you can redistribute it and/or modify # | ||
13 | 8 | # it under the terms of the GNU Affero General Public License as # | ||
14 | 9 | # published by the Free Software Foundation, either version 3 of the # | ||
15 | 10 | # License, or (at your option) any later version. # | ||
16 | 11 | # # | ||
17 | 12 | # This program is distributed in the hope that it will be useful, # | ||
18 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # | ||
19 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # | ||
20 | 15 | # GNU Affero General Public License for more details. # | ||
21 | 16 | # # | ||
22 | 17 | # You should have received a copy of the GNU Affero General Public License # | ||
23 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. # | ||
24 | 19 | # # | ||
25 | 20 | ############################################################################### | ||
26 | 21 | """Account Statement Cancel Line.""" | ||
27 | 22 | |||
28 | 23 | import statement # noqa | ||
29 | 24 | import statement_line # noqa | ||
30 | 25 | import wizard # noqa | ||
31 | 0 | 26 | ||
32 | === added file 'account_statement_cancel_line/__openerp__.py' | |||
33 | --- account_statement_cancel_line/__openerp__.py 1970-01-01 00:00:00 +0000 | |||
34 | +++ account_statement_cancel_line/__openerp__.py 2014-06-13 10:06:12 +0000 | |||
35 | @@ -0,0 +1,74 @@ | |||
36 | 1 | # -*- coding: utf-8 -*- | ||
37 | 2 | ############################################################################### | ||
38 | 3 | # # | ||
39 | 4 | # Author: Leonardo Pistone # | ||
40 | 5 | # Copyright 2014 Camptocamp SA # | ||
41 | 6 | # # | ||
42 | 7 | # Inspired by module account_banking by EduSense BV, Therp BV, Smile # | ||
43 | 8 | # # | ||
44 | 9 | # This program is free software: you can redistribute it and/or modify # | ||
45 | 10 | # it under the terms of the GNU Affero General Public License as # | ||
46 | 11 | # published by the Free Software Foundation, either version 3 of the # | ||
47 | 12 | # License, or (at your option) any later version. # | ||
48 | 13 | # # | ||
49 | 14 | # This program is distributed in the hope that it will be useful, # | ||
50 | 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # | ||
51 | 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # | ||
52 | 17 | # GNU Affero General Public License for more details. # | ||
53 | 18 | # # | ||
54 | 19 | # You should have received a copy of the GNU Affero General Public License # | ||
55 | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. # | ||
56 | 21 | # # | ||
57 | 22 | ############################################################################### | ||
58 | 23 | { | ||
59 | 24 | 'name': "Account Statement Cancel Line", | ||
60 | 25 | 'version': '0.3', | ||
61 | 26 | 'author': 'Camptocamp', | ||
62 | 27 | 'maintainer': 'Camptocamp', | ||
63 | 28 | 'category': 'Finance', | ||
64 | 29 | 'complexity': 'normal', | ||
65 | 30 | 'depends': [ | ||
66 | 31 | 'account', | ||
67 | 32 | 'account_statement_ext', | ||
68 | 33 | 'account_default_draft_move', | ||
69 | 34 | 'account_statement_base_completion', | ||
70 | 35 | ], | ||
71 | 36 | 'description': """ | ||
72 | 37 | Account Statement Cancel Line | ||
73 | 38 | |||
74 | 39 | This module allows to cancel one line of the statement without | ||
75 | 40 | cancelling the whole thing. | ||
76 | 41 | |||
77 | 42 | To do that, a state is added to the statement line. | ||
78 | 43 | |||
79 | 44 | When the user confirms or cancels the whole statement, we keep the | ||
80 | 45 | previous functionality, and then we change the state in all statement | ||
81 | 46 | lines. We also add a warning if any lines are reconciled. If no lines | ||
82 | 47 | are reconciled, we show a generic warning because the operation could | ||
83 | 48 | take a long time. | ||
84 | 49 | |||
85 | 50 | When the user confirms or cancels a statement line, we update the state | ||
86 | 51 | of the line, and if necessary we update the state of the whole | ||
87 | 52 | statement, too. | ||
88 | 53 | |||
89 | 54 | If the user tries to cancel a line that is reconciled, we ask for | ||
90 | 55 | confirmation before proceeding. | ||
91 | 56 | """, | ||
92 | 57 | 'website': 'http://www.camptocamp.com', | ||
93 | 58 | 'init_xml': [], | ||
94 | 59 | 'update_xml': [ | ||
95 | 60 | 'statement_view.xml', | ||
96 | 61 | 'wizard/cancel_statement_view.xml', | ||
97 | 62 | 'wizard/cancel_statement_line_view.xml', | ||
98 | 63 | ], | ||
99 | 64 | 'demo_xml': [], | ||
100 | 65 | 'test': [ | ||
101 | 66 | 'test/cancel_line.yml', | ||
102 | 67 | 'test/test_confirm_last_line_balance_check.yml', | ||
103 | 68 | 'test/test_confirm_last_line_no_balance_check.yml', | ||
104 | 69 | 'test/confirm_statement_no_double_moves.yml', | ||
105 | 70 | ], | ||
106 | 71 | 'installable': True, | ||
107 | 72 | 'images': [], | ||
108 | 73 | 'license': 'AGPL-3', | ||
109 | 74 | } | ||
110 | 0 | 75 | ||
111 | === added directory 'account_statement_cancel_line/i18n' | |||
112 | === added file 'account_statement_cancel_line/i18n/account_statement_cancel_line.pot' | |||
113 | --- account_statement_cancel_line/i18n/account_statement_cancel_line.pot 1970-01-01 00:00:00 +0000 | |||
114 | +++ account_statement_cancel_line/i18n/account_statement_cancel_line.pot 2014-06-13 10:06:12 +0000 | |||
115 | @@ -0,0 +1,97 @@ | |||
116 | 1 | # Translation of OpenERP Server. | ||
117 | 2 | # This file contains the translation of the following modules: | ||
118 | 3 | # * account_statement_cancel_line | ||
119 | 4 | # | ||
120 | 5 | msgid "" | ||
121 | 6 | msgstr "" | ||
122 | 7 | "Project-Id-Version: OpenERP Server 7.0\n" | ||
123 | 8 | "Report-Msgid-Bugs-To: \n" | ||
124 | 9 | "POT-Creation-Date: 2014-02-17 16:46+0000\n" | ||
125 | 10 | "PO-Revision-Date: 2014-02-17 16:46+0000\n" | ||
126 | 11 | "Last-Translator: <>\n" | ||
127 | 12 | "Language-Team: \n" | ||
128 | 13 | "MIME-Version: 1.0\n" | ||
129 | 14 | "Content-Type: text/plain; charset=UTF-8\n" | ||
130 | 15 | "Content-Transfer-Encoding: \n" | ||
131 | 16 | "Plural-Forms: \n" | ||
132 | 17 | |||
133 | 18 | #. module: account_statement_cancel_line | ||
134 | 19 | #: model:ir.model,name:account_statement_cancel_line.model_account_bank_statement_line | ||
135 | 20 | msgid "Bank Statement Line" | ||
136 | 21 | msgstr "" | ||
137 | 22 | |||
138 | 23 | #. module: account_statement_cancel_line | ||
139 | 24 | #: view:wizard.cancel.statement:0 | ||
140 | 25 | #: view:wizard.cancel.statement.line:0 | ||
141 | 26 | msgid "Some entries are already reconciled. Do you want to unreconcile them and proceed?" | ||
142 | 27 | msgstr "" | ||
143 | 28 | |||
144 | 29 | #. module: account_statement_cancel_line | ||
145 | 30 | #: view:account.bank.statement:0 | ||
146 | 31 | msgid "Cancel transaction" | ||
147 | 32 | msgstr "" | ||
148 | 33 | |||
149 | 34 | #. module: account_statement_cancel_line | ||
150 | 35 | #: model:ir.model,name:account_statement_cancel_line.model_wizard_cancel_statement | ||
151 | 36 | msgid "Cancel Statement" | ||
152 | 37 | msgstr "" | ||
153 | 38 | |||
154 | 39 | #. module: account_statement_cancel_line | ||
155 | 40 | #: model:ir.model,name:account_statement_cancel_line.model_account_bank_statement | ||
156 | 41 | msgid "Bank Statement" | ||
157 | 42 | msgstr "" | ||
158 | 43 | |||
159 | 44 | #. module: account_statement_cancel_line | ||
160 | 45 | #: model:ir.model,name:account_statement_cancel_line.model_wizard_cancel_statement_line | ||
161 | 46 | msgid "Cancel Statement Line" | ||
162 | 47 | msgstr "" | ||
163 | 48 | |||
164 | 49 | #. module: account_statement_cancel_line | ||
165 | 50 | #: field:account.bank.statement.line,state:0 | ||
166 | 51 | msgid "State" | ||
167 | 52 | msgstr "" | ||
168 | 53 | |||
169 | 54 | #. module: account_statement_cancel_line | ||
170 | 55 | #: view:wizard.cancel.statement:0 | ||
171 | 56 | #: view:wizard.cancel.statement.line:0 | ||
172 | 57 | msgid "Reconciled Entries" | ||
173 | 58 | msgstr "" | ||
174 | 59 | |||
175 | 60 | #. module: account_statement_cancel_line | ||
176 | 61 | #: selection:account.bank.statement.line,state:0 | ||
177 | 62 | msgid "Draft" | ||
178 | 63 | msgstr "" | ||
179 | 64 | |||
180 | 65 | #. module: account_statement_cancel_line | ||
181 | 66 | #: selection:account.bank.statement.line,state:0 | ||
182 | 67 | msgid "Confirmed" | ||
183 | 68 | msgstr "" | ||
184 | 69 | |||
185 | 70 | #. module: account_statement_cancel_line | ||
186 | 71 | #: view:wizard.cancel.statement:0 | ||
187 | 72 | #: view:wizard.cancel.statement.line:0 | ||
188 | 73 | msgid "Cancel" | ||
189 | 74 | msgstr "" | ||
190 | 75 | |||
191 | 76 | #. module: account_statement_cancel_line | ||
192 | 77 | #: view:account.bank.statement:0 | ||
193 | 78 | msgid "Confirm transaction" | ||
194 | 79 | msgstr "" | ||
195 | 80 | |||
196 | 81 | #. module: account_statement_cancel_line | ||
197 | 82 | #: view:wizard.cancel.statement:0 | ||
198 | 83 | #: view:wizard.cancel.statement.line:0 | ||
199 | 84 | msgid "Unreconcile" | ||
200 | 85 | msgstr "" | ||
201 | 86 | |||
202 | 87 | #. module: account_statement_cancel_line | ||
203 | 88 | #: view:wizard.cancel.statement:0 | ||
204 | 89 | #: view:wizard.cancel.statement.line:0 | ||
205 | 90 | msgid "or" | ||
206 | 91 | msgstr "" | ||
207 | 92 | |||
208 | 93 | #. module: account_statement_cancel_line | ||
209 | 94 | #: view:wizard.cancel.statement:0 | ||
210 | 95 | #: view:wizard.cancel.statement.line:0 | ||
211 | 96 | msgid "Unreconciliation" | ||
212 | 97 | msgstr "" | ||
213 | 0 | 98 | ||
214 | === added file 'account_statement_cancel_line/i18n/fr.po' | |||
215 | --- account_statement_cancel_line/i18n/fr.po 1970-01-01 00:00:00 +0000 | |||
216 | +++ account_statement_cancel_line/i18n/fr.po 2014-06-13 10:06:12 +0000 | |||
217 | @@ -0,0 +1,97 @@ | |||
218 | 1 | # Translation of OpenERP Server. | ||
219 | 2 | # This file contains the translation of the following modules: | ||
220 | 3 | # * account_statement_cancel_line | ||
221 | 4 | # | ||
222 | 5 | msgid "" | ||
223 | 6 | msgstr "" | ||
224 | 7 | "Project-Id-Version: OpenERP Server 7.0\n" | ||
225 | 8 | "Report-Msgid-Bugs-To: \n" | ||
226 | 9 | "POT-Creation-Date: 2014-02-17 15:59+0000\n" | ||
227 | 10 | "PO-Revision-Date: 2014-02-17 15:59+0000\n" | ||
228 | 11 | "Last-Translator: <>\n" | ||
229 | 12 | "Language-Team: \n" | ||
230 | 13 | "MIME-Version: 1.0\n" | ||
231 | 14 | "Content-Type: text/plain; charset=UTF-8\n" | ||
232 | 15 | "Content-Transfer-Encoding: \n" | ||
233 | 16 | "Plural-Forms: \n" | ||
234 | 17 | |||
235 | 18 | #. module: account_statement_cancel_line | ||
236 | 19 | #: model:ir.model,name:account_statement_cancel_line.model_account_bank_statement_line | ||
237 | 20 | msgid "Bank Statement Line" | ||
238 | 21 | msgstr "Ligne de relevé bancaire" | ||
239 | 22 | |||
240 | 23 | #. module: account_statement_cancel_line | ||
241 | 24 | #: view:wizard.cancel.statement:0 | ||
242 | 25 | #: view:wizard.cancel.statement.line:0 | ||
243 | 26 | msgid "Some entries are already reconciled. Do you want to unreconcile them and proceed?" | ||
244 | 27 | msgstr "Certaines écritures sont déja léttrées. Voulez-vous annuler définitivement tout les léttrages et poursuivre?" | ||
245 | 28 | |||
246 | 29 | #. module: account_statement_cancel_line | ||
247 | 30 | #: view:account.bank.statement:0 | ||
248 | 31 | msgid "Cancel transaction" | ||
249 | 32 | msgstr "Annuler ligne" | ||
250 | 33 | |||
251 | 34 | #. module: account_statement_cancel_line | ||
252 | 35 | #: model:ir.model,name:account_statement_cancel_line.model_wizard_cancel_statement | ||
253 | 36 | msgid "Cancel Statement" | ||
254 | 37 | msgstr "Annuler le relevé" | ||
255 | 38 | |||
256 | 39 | #. module: account_statement_cancel_line | ||
257 | 40 | #: model:ir.model,name:account_statement_cancel_line.model_account_bank_statement | ||
258 | 41 | msgid "Bank Statement" | ||
259 | 42 | msgstr "Relevé bancaire" | ||
260 | 43 | |||
261 | 44 | #. module: account_statement_cancel_line | ||
262 | 45 | #: model:ir.model,name:account_statement_cancel_line.model_wizard_cancel_statement_line | ||
263 | 46 | msgid "Cancel Statement Line" | ||
264 | 47 | msgstr "Annuler ligne de relevé" | ||
265 | 48 | |||
266 | 49 | #. module: account_statement_cancel_line | ||
267 | 50 | #: field:account.bank.statement.line,state:0 | ||
268 | 51 | msgid "State" | ||
269 | 52 | msgstr "Etat" | ||
270 | 53 | |||
271 | 54 | #. module: account_statement_cancel_line | ||
272 | 55 | #: view:wizard.cancel.statement:0 | ||
273 | 56 | #: view:wizard.cancel.statement.line:0 | ||
274 | 57 | msgid "Reconciled Entries" | ||
275 | 58 | msgstr "Lignes léttrées" | ||
276 | 59 | |||
277 | 60 | #. module: account_statement_cancel_line | ||
278 | 61 | #: selection:account.bank.statement.line,state:0 | ||
279 | 62 | msgid "Draft" | ||
280 | 63 | msgstr "Brouillon" | ||
281 | 64 | |||
282 | 65 | #. module: account_statement_cancel_line | ||
283 | 66 | #: selection:account.bank.statement.line,state:0 | ||
284 | 67 | msgid "Confirmed" | ||
285 | 68 | msgstr "Confirmée" | ||
286 | 69 | |||
287 | 70 | #. module: account_statement_cancel_line | ||
288 | 71 | #: view:wizard.cancel.statement:0 | ||
289 | 72 | #: view:wizard.cancel.statement.line:0 | ||
290 | 73 | msgid "Cancel" | ||
291 | 74 | msgstr "Annuler" | ||
292 | 75 | |||
293 | 76 | #. module: account_statement_cancel_line | ||
294 | 77 | #: view:account.bank.statement:0 | ||
295 | 78 | msgid "Confirm transaction" | ||
296 | 79 | msgstr "Confirmer ligne" | ||
297 | 80 | |||
298 | 81 | #. module: account_statement_cancel_line | ||
299 | 82 | #: view:wizard.cancel.statement:0 | ||
300 | 83 | #: view:wizard.cancel.statement.line:0 | ||
301 | 84 | msgid "Unreconcile" | ||
302 | 85 | msgstr "Déléttrer" | ||
303 | 86 | |||
304 | 87 | #. module: account_statement_cancel_line | ||
305 | 88 | #: view:wizard.cancel.statement:0 | ||
306 | 89 | #: view:wizard.cancel.statement.line:0 | ||
307 | 90 | msgid "or" | ||
308 | 91 | msgstr "ou" | ||
309 | 92 | |||
310 | 93 | #. module: account_statement_cancel_line | ||
311 | 94 | #: view:wizard.cancel.statement:0 | ||
312 | 95 | #: view:wizard.cancel.statement.line:0 | ||
313 | 96 | msgid "Unreconciliation" | ||
314 | 97 | msgstr "Déléttrage" | ||
315 | 0 | 98 | ||
316 | === added directory 'account_statement_cancel_line/migrations' | |||
317 | === added directory 'account_statement_cancel_line/migrations/0.3' | |||
318 | === added file 'account_statement_cancel_line/migrations/0.3/post-set-statement-line-state.py' | |||
319 | --- account_statement_cancel_line/migrations/0.3/post-set-statement-line-state.py 1970-01-01 00:00:00 +0000 | |||
320 | +++ account_statement_cancel_line/migrations/0.3/post-set-statement-line-state.py 2014-06-13 10:06:12 +0000 | |||
321 | @@ -0,0 +1,38 @@ | |||
322 | 1 | # -*- coding: utf-8 -*- | ||
323 | 2 | ############################################################################### | ||
324 | 3 | # # | ||
325 | 4 | # Author: Leonardo Pistone # | ||
326 | 5 | # Copyright 2014 Camptocamp SA # | ||
327 | 6 | # # | ||
328 | 7 | # Inspired by module account_banking by EduSense BV, Therp BV, Smile # | ||
329 | 8 | # # | ||
330 | 9 | # This program is free software: you can redistribute it and/or modify # | ||
331 | 10 | # it under the terms of the GNU Affero General Public License as # | ||
332 | 11 | # published by the Free Software Foundation, either version 3 of the # | ||
333 | 12 | # License, or (at your option) any later version. # | ||
334 | 13 | # # | ||
335 | 14 | # This program is distributed in the hope that it will be useful, # | ||
336 | 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # | ||
337 | 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # | ||
338 | 17 | # GNU Affero General Public License for more details. # | ||
339 | 18 | # # | ||
340 | 19 | # You should have received a copy of the GNU Affero General Public License # | ||
341 | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. # | ||
342 | 21 | # # | ||
343 | 22 | ############################################################################### | ||
344 | 23 | |||
345 | 24 | __name__ = ("account.bank.statement.line:: set new field 'state' to " | ||
346 | 25 | "confirmed for all statement lines belonging to confirmed " | ||
347 | 26 | "statements") | ||
348 | 27 | |||
349 | 28 | |||
350 | 29 | def migrate(cr, version): | ||
351 | 30 | """This module adds the field state to the statement line. Here we set it | ||
352 | 31 | correctly on existing statements. The names, and so this migration, are | ||
353 | 32 | intentionally kept in sync with the account_banking module.""" | ||
354 | 33 | cr.execute("UPDATE account_bank_statement_line as sl " | ||
355 | 34 | " SET state = 'confirmed'" | ||
356 | 35 | " FROM account_bank_statement as s " | ||
357 | 36 | " WHERE sl.statement_id = s.id " | ||
358 | 37 | " AND s.state = 'confirm' " | ||
359 | 38 | ) | ||
360 | 0 | 39 | ||
361 | === added file 'account_statement_cancel_line/statement.py' | |||
362 | --- account_statement_cancel_line/statement.py 1970-01-01 00:00:00 +0000 | |||
363 | +++ account_statement_cancel_line/statement.py 2014-06-13 10:06:12 +0000 | |||
364 | @@ -0,0 +1,118 @@ | |||
365 | 1 | # -*- coding: utf-8 -*- | ||
366 | 2 | ############################################################################### | ||
367 | 3 | # # | ||
368 | 4 | # Author: Leonardo Pistone | ||
369 | 5 | # Copyright 2014 Camptocamp SA | ||
370 | 6 | # # | ||
371 | 7 | # This program is free software: you can redistribute it and/or modify # | ||
372 | 8 | # it under the terms of the GNU Affero General Public License as # | ||
373 | 9 | # published by the Free Software Foundation, either version 3 of the # | ||
374 | 10 | # License, or (at your option) any later version. # | ||
375 | 11 | # # | ||
376 | 12 | # This program is distributed in the hope that it will be useful, # | ||
377 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # | ||
378 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # | ||
379 | 15 | # GNU Affero General Public License for more details. # | ||
380 | 16 | # # | ||
381 | 17 | # You should have received a copy of the GNU Affero General Public License # | ||
382 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. # | ||
383 | 19 | # # | ||
384 | 20 | ############################################################################### | ||
385 | 21 | """Account Statement Cancel Line.""" | ||
386 | 22 | |||
387 | 23 | from openerp.osv import orm | ||
388 | 24 | |||
389 | 25 | |||
390 | 26 | class Statement(orm.Model): | ||
391 | 27 | |||
392 | 28 | """Bank Statement. | ||
393 | 29 | |||
394 | 30 | Minimal changes to allow cancelling single lines and checking if there are | ||
395 | 31 | any lines that are already reconciled. | ||
396 | 32 | |||
397 | 33 | """ | ||
398 | 34 | |||
399 | 35 | _inherit = "account.bank.statement" | ||
400 | 36 | |||
401 | 37 | def button_confirm_bank(self, cr, uid, ids, context=None): | ||
402 | 38 | """If all lines are draft, change their state. | ||
403 | 39 | Otherwise, confirm line by line to avoid duplicate moves. | ||
404 | 40 | Return super. | ||
405 | 41 | |||
406 | 42 | """ | ||
407 | 43 | st_line_obj = self.pool['account.bank.statement.line'] | ||
408 | 44 | |||
409 | 45 | statement_ids_fully_confirm = [] | ||
410 | 46 | for st in self.browse(cr, uid, ids, context=context): | ||
411 | 47 | if all(l.state == 'draft' for l in st.line_ids): | ||
412 | 48 | statement_ids_fully_confirm.append(st.id) | ||
413 | 49 | st_line_obj.write(cr, uid, [l.id for l in st.line_ids], { | ||
414 | 50 | 'state': 'confirmed' | ||
415 | 51 | }, context=context) | ||
416 | 52 | else: | ||
417 | 53 | st_line_obj.confirm(cr, uid, [l.id for l in st.line_ids], | ||
418 | 54 | context=context) | ||
419 | 55 | |||
420 | 56 | if statement_ids_fully_confirm: | ||
421 | 57 | return super(Statement, self).button_confirm_bank( | ||
422 | 58 | cr, uid, statement_ids_fully_confirm, context) | ||
423 | 59 | else: | ||
424 | 60 | return True | ||
425 | 61 | |||
426 | 62 | def button_cancel(self, cr, uid, ids, context=None): | ||
427 | 63 | """Check if there is any reconciliation. Return action.""" | ||
428 | 64 | st_line_obj = self.pool['account.bank.statement.line'] | ||
429 | 65 | for statement in self.browse(cr, uid, ids, context=context): | ||
430 | 66 | ctx = context.copy() | ||
431 | 67 | ctx['default_reconcile_warning'] = st_line_obj.has_reconciliation( | ||
432 | 68 | cr, | ||
433 | 69 | uid, | ||
434 | 70 | [line.id for line in statement.line_ids], | ||
435 | 71 | context=context) | ||
436 | 72 | return { | ||
437 | 73 | 'type': 'ir.actions.act_window', | ||
438 | 74 | 'res_model': 'wizard.cancel.statement', | ||
439 | 75 | 'view_type': 'form', | ||
440 | 76 | 'view_mode': 'form', | ||
441 | 77 | 'target': 'new', | ||
442 | 78 | 'context': ctx, | ||
443 | 79 | } | ||
444 | 80 | |||
445 | 81 | self.do_cancel(cr, uid, ids, context=context) | ||
446 | 82 | |||
447 | 83 | def do_cancel(self, cr, uid, ids, context=None): | ||
448 | 84 | """Change the state on the statement lines. Return super. | ||
449 | 85 | |||
450 | 86 | This method is called directly when there are no reconciliations, or | ||
451 | 87 | from the warning wizard, if there are reconciliations. | ||
452 | 88 | |||
453 | 89 | """ | ||
454 | 90 | st_line_obj = self.pool['account.bank.statement.line'] | ||
455 | 91 | for st_data in self.read(cr, uid, ids, ['line_ids'], context=context): | ||
456 | 92 | st_line_obj.write(cr, uid, st_data['line_ids'], { | ||
457 | 93 | 'state': 'draft' | ||
458 | 94 | }, context=context) | ||
459 | 95 | |||
460 | 96 | return super(Statement, self).button_cancel( | ||
461 | 97 | cr, uid, ids, context) | ||
462 | 98 | |||
463 | 99 | def confirm_statement_from_lines(self, cr, uid, ids, context=None): | ||
464 | 100 | """If all lines are confirmed, so is the whole statement. | ||
465 | 101 | |||
466 | 102 | Return True if we changed anything. | ||
467 | 103 | |||
468 | 104 | """ | ||
469 | 105 | need_to_update_view = False | ||
470 | 106 | for statement in self.browse(cr, uid, ids, context=context): | ||
471 | 107 | if all(line.state == 'confirmed' for line in statement.line_ids): | ||
472 | 108 | self.write(cr, uid, [statement.id], { | ||
473 | 109 | 'state': 'confirm' | ||
474 | 110 | }, context=context) | ||
475 | 111 | need_to_update_view = True | ||
476 | 112 | self.balance_check( | ||
477 | 113 | cr, | ||
478 | 114 | uid, | ||
479 | 115 | statement.id, | ||
480 | 116 | journal_type=statement.journal_id.type, | ||
481 | 117 | context=context) | ||
482 | 118 | return need_to_update_view | ||
483 | 0 | 119 | ||
484 | === added file 'account_statement_cancel_line/statement_line.py' | |||
485 | --- account_statement_cancel_line/statement_line.py 1970-01-01 00:00:00 +0000 | |||
486 | +++ account_statement_cancel_line/statement_line.py 2014-06-13 10:06:12 +0000 | |||
487 | @@ -0,0 +1,213 @@ | |||
488 | 1 | # -*- coding: utf-8 -*- | ||
489 | 2 | ############################################################################### | ||
490 | 3 | # # | ||
491 | 4 | # Author: Leonardo Pistone | ||
492 | 5 | # Copyright 2014 Camptocamp SA | ||
493 | 6 | # # | ||
494 | 7 | # This program is free software: you can redistribute it and/or modify # | ||
495 | 8 | # it under the terms of the GNU Affero General Public License as # | ||
496 | 9 | # published by the Free Software Foundation, either version 3 of the # | ||
497 | 10 | # License, or (at your option) any later version. # | ||
498 | 11 | # # | ||
499 | 12 | # This program is distributed in the hope that it will be useful, # | ||
500 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # | ||
501 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # | ||
502 | 15 | # GNU Affero General Public License for more details. # | ||
503 | 16 | # # | ||
504 | 17 | # You should have received a copy of the GNU Affero General Public License # | ||
505 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. # | ||
506 | 19 | # # | ||
507 | 20 | ############################################################################### | ||
508 | 21 | """Account Statement Cancel Line.""" | ||
509 | 22 | |||
510 | 23 | from openerp.osv import fields, orm | ||
511 | 24 | |||
512 | 25 | from openerp.tools.translate import _ | ||
513 | 26 | |||
514 | 27 | |||
515 | 28 | class StatementLine(orm.Model): | ||
516 | 29 | |||
517 | 30 | """Add a state to the statement line.""" | ||
518 | 31 | |||
519 | 32 | _inherit = "account.bank.statement.line" | ||
520 | 33 | |||
521 | 34 | _columns = { | ||
522 | 35 | 'state': fields.selection( | ||
523 | 36 | [('draft', 'Draft'), ('confirmed', 'Confirmed')], | ||
524 | 37 | 'State', | ||
525 | 38 | readonly=True, | ||
526 | 39 | required=True | ||
527 | 40 | ), | ||
528 | 41 | } | ||
529 | 42 | |||
530 | 43 | _defaults = { | ||
531 | 44 | 'state': 'draft', | ||
532 | 45 | } | ||
533 | 46 | |||
534 | 47 | def confirm(self, cr, uid, ids, context=None): | ||
535 | 48 | """Confirm just one statement line, return action. | ||
536 | 49 | |||
537 | 50 | The module account_banking does have a similar method, but at the | ||
538 | 51 | moment it uses a different logic (for example, it uses vouchers, where | ||
539 | 52 | the bank-statement-reconcile branch does not). | ||
540 | 53 | |||
541 | 54 | """ | ||
542 | 55 | if context is None: | ||
543 | 56 | context = {} | ||
544 | 57 | local_ctx = context.copy() | ||
545 | 58 | # if account_constraints is installed, we need to tell it that moves | ||
546 | 59 | # are being created by a statement, which is OK. | ||
547 | 60 | # The module tries to prevent direct changes to the moves created by | ||
548 | 61 | # bank statements. | ||
549 | 62 | local_ctx['from_parent_object'] = True | ||
550 | 63 | |||
551 | 64 | statement_pool = self.pool.get('account.bank.statement') | ||
552 | 65 | res = {} | ||
553 | 66 | |||
554 | 67 | for st_line in self.browse(cr, uid, ids, context): | ||
555 | 68 | if st_line.state != 'draft': | ||
556 | 69 | continue | ||
557 | 70 | st = st_line.statement_id | ||
558 | 71 | curr_id = st.journal_id.company_id.currency_id.id | ||
559 | 72 | |||
560 | 73 | st_number = st.name | ||
561 | 74 | st_line_number = statement_pool.get_next_st_line_number( | ||
562 | 75 | cr, uid, st_number, st_line, context) | ||
563 | 76 | |||
564 | 77 | # We pass the local_ctx so that account_constraints allows us to | ||
565 | 78 | # work on the moves generated by the bank statement | ||
566 | 79 | statement_pool.create_move_from_st_line( | ||
567 | 80 | cr, | ||
568 | 81 | uid, | ||
569 | 82 | st_line.id, | ||
570 | 83 | curr_id, | ||
571 | 84 | st_line_number, | ||
572 | 85 | local_ctx) | ||
573 | 86 | self.write(cr, uid, st_line.id, { | ||
574 | 87 | 'state': 'confirmed' | ||
575 | 88 | }, context) | ||
576 | 89 | if statement_pool.confirm_statement_from_lines(cr, uid, [st.id], | ||
577 | 90 | context=context): | ||
578 | 91 | # to see that the state of the statement has changed, we need | ||
579 | 92 | # to update the whole view. Do that only if necessary. | ||
580 | 93 | res = { | ||
581 | 94 | 'type': 'ir.actions.client', | ||
582 | 95 | 'tag': 'reload', | ||
583 | 96 | } | ||
584 | 97 | |||
585 | 98 | return res | ||
586 | 99 | |||
587 | 100 | def has_reconciliation(self, cr, uid, ids, context=None): | ||
588 | 101 | """Check if the line has some reconciliation. Return boolean.""" | ||
589 | 102 | if context is None: | ||
590 | 103 | context = {} | ||
591 | 104 | |||
592 | 105 | for st_line in self.browse(cr, uid, ids, context=context): | ||
593 | 106 | for move in st_line.move_ids: | ||
594 | 107 | for move_line in move.line_id: | ||
595 | 108 | if move_line.reconcile: | ||
596 | 109 | # aha! we have some reconciliation! | ||
597 | 110 | return True | ||
598 | 111 | |||
599 | 112 | # no reconciliation to worry about | ||
600 | 113 | return False | ||
601 | 114 | |||
602 | 115 | def button_cancel(self, cr, uid, ids, context=None): | ||
603 | 116 | """Check if a line is reconciled, and cancel it. Return action.""" | ||
604 | 117 | if context is None: | ||
605 | 118 | context = {} | ||
606 | 119 | |||
607 | 120 | if self.has_reconciliation(cr, uid, ids, context=context): | ||
608 | 121 | # ask confirmation, we have some reconciliation already | ||
609 | 122 | return { | ||
610 | 123 | 'type': 'ir.actions.act_window', | ||
611 | 124 | 'res_model': 'wizard.cancel.statement.line', | ||
612 | 125 | 'view_type': 'form', | ||
613 | 126 | 'view_mode': 'form', | ||
614 | 127 | 'target': 'new', | ||
615 | 128 | 'context': context, | ||
616 | 129 | } | ||
617 | 130 | |||
618 | 131 | # no reconciliation to worry about: we cancel our lines directly then | ||
619 | 132 | return self.cancel(cr, uid, ids, context=context) | ||
620 | 133 | |||
621 | 134 | def cancel(self, cr, uid, ids, context=None): | ||
622 | 135 | """Cancel one statement line, return action. | ||
623 | 136 | |||
624 | 137 | This is again similar to the method cancel in the account_banking | ||
625 | 138 | module. | ||
626 | 139 | |||
627 | 140 | """ | ||
628 | 141 | if context is None: | ||
629 | 142 | context = {} | ||
630 | 143 | local_ctx = context.copy() | ||
631 | 144 | # if account_constraints is installed, we need to tell it that moves | ||
632 | 145 | # are being created by a statement, which is OK. | ||
633 | 146 | # The module tries to prevent direct changes to the moves created by | ||
634 | 147 | # bank statements. | ||
635 | 148 | local_ctx['from_parent_object'] = True | ||
636 | 149 | |||
637 | 150 | move_pool = self.pool['account.move'] | ||
638 | 151 | statement_pool = self.pool['account.bank.statement'] | ||
639 | 152 | |||
640 | 153 | st_line_ids = [] | ||
641 | 154 | |||
642 | 155 | # to avoid duplicates if all lines come from the same statement | ||
643 | 156 | statement_ids = set() | ||
644 | 157 | |||
645 | 158 | move_unlink_ids = [] | ||
646 | 159 | # harvest ids for various actions | ||
647 | 160 | for st_line in self.browse(cr, uid, ids, context): | ||
648 | 161 | if st_line.state != 'confirmed': | ||
649 | 162 | continue | ||
650 | 163 | |||
651 | 164 | for move in st_line.move_ids: | ||
652 | 165 | # We allow for people canceling and removing | ||
653 | 166 | # the associated payments, which can lead to confirmed | ||
654 | 167 | # statement lines without an associated move | ||
655 | 168 | move_unlink_ids.append(move.id) | ||
656 | 169 | # do we need to check that? | ||
657 | 170 | if move.state != 'draft': | ||
658 | 171 | raise orm.except_orm( | ||
659 | 172 | _('Confirmed Journal Entry'), | ||
660 | 173 | _('You cannot delete a confirmed Statement Line ' | ||
661 | 174 | 'associated to a Journal Entry that is posted.')) | ||
662 | 175 | st_line_ids.append(st_line.id) | ||
663 | 176 | if st_line.statement_id.state != 'draft': | ||
664 | 177 | statement_ids.add(st_line.statement_id.id) | ||
665 | 178 | |||
666 | 179 | move_pool.button_cancel( | ||
667 | 180 | cr, uid, move_unlink_ids, context=context) | ||
668 | 181 | |||
669 | 182 | move_pool.unlink(cr, uid, move_unlink_ids, context=local_ctx) | ||
670 | 183 | self.write(cr, uid, st_line_ids, { | ||
671 | 184 | 'state': 'draft', | ||
672 | 185 | 'already_completed': False | ||
673 | 186 | }, context=context) | ||
674 | 187 | if statement_ids: | ||
675 | 188 | # if we cancel one or more lines, the statement goes back to draft, | ||
676 | 189 | # too | ||
677 | 190 | statement_pool.write(cr, uid, list(statement_ids), { | ||
678 | 191 | 'state': 'draft' | ||
679 | 192 | }, context=context) | ||
680 | 193 | # then we manually update the view of the statement | ||
681 | 194 | return { | ||
682 | 195 | 'type': 'ir.actions.client', | ||
683 | 196 | 'tag': 'reload', | ||
684 | 197 | } | ||
685 | 198 | else: | ||
686 | 199 | # no need to update the view then | ||
687 | 200 | return {} | ||
688 | 201 | |||
689 | 202 | def unlink(self, cr, uid, ids, context=None): | ||
690 | 203 | """Don't allow deletion of a confirmed statement line. Return super.""" | ||
691 | 204 | if type(ids) is int: | ||
692 | 205 | ids = [ids] | ||
693 | 206 | for line in self.browse(cr, uid, ids, context=context): | ||
694 | 207 | if line.state == 'confirmed': | ||
695 | 208 | raise orm.except_orm( | ||
696 | 209 | _('Confirmed Statement Line'), | ||
697 | 210 | _("You cannot delete a confirmed Statement Line" | ||
698 | 211 | ": '%s'") % line.name) | ||
699 | 212 | return super(StatementLine, self).unlink( | ||
700 | 213 | cr, uid, ids, context=context) | ||
701 | 0 | 214 | ||
702 | === added file 'account_statement_cancel_line/statement_view.xml' | |||
703 | --- account_statement_cancel_line/statement_view.xml 1970-01-01 00:00:00 +0000 | |||
704 | +++ account_statement_cancel_line/statement_view.xml 2014-06-13 10:06:12 +0000 | |||
705 | @@ -0,0 +1,28 @@ | |||
706 | 1 | <?xml version="1.0" encoding="utf-8"?> | ||
707 | 2 | <openerp> | ||
708 | 3 | <data> | ||
709 | 4 | |||
710 | 5 | <record id="view_bank_statement_form_cancel_line" model="ir.ui.view"> | ||
711 | 6 | <field name="name">account.bank.statement.form.</field> | ||
712 | 7 | <field name="inherit_id" ref="account.view_bank_statement_form" /> | ||
713 | 8 | <field name="model">account.bank.statement</field> | ||
714 | 9 | <field name="arch" type="xml"> | ||
715 | 10 | <data> | ||
716 | 11 | <xpath expr="//field[@name='line_ids']/tree/field[@name='amount']" | ||
717 | 12 | position="after"> | ||
718 | 13 | <field name="state"/> | ||
719 | 14 | <button name="confirm" states="draft" | ||
720 | 15 | string="Confirm transaction" | ||
721 | 16 | icon="gtk-ok" | ||
722 | 17 | type="object"/> | ||
723 | 18 | <button name="button_cancel" states="confirmed" | ||
724 | 19 | string="Cancel transaction" | ||
725 | 20 | icon="gtk-cancel" | ||
726 | 21 | type="object"/> | ||
727 | 22 | </xpath> | ||
728 | 23 | </data> | ||
729 | 24 | </field> | ||
730 | 25 | </record> | ||
731 | 26 | |||
732 | 27 | </data> | ||
733 | 28 | </openerp> | ||
734 | 0 | 29 | ||
735 | === added directory 'account_statement_cancel_line/test' | |||
736 | === added file 'account_statement_cancel_line/test/cancel_line.yml' | |||
737 | --- account_statement_cancel_line/test/cancel_line.yml 1970-01-01 00:00:00 +0000 | |||
738 | +++ account_statement_cancel_line/test/cancel_line.yml 2014-06-13 10:06:12 +0000 | |||
739 | @@ -0,0 +1,80 @@ | |||
740 | 1 | - | ||
741 | 2 | In order to test the cancellation of statement lines, I need a statement | ||
742 | 3 | profile. | ||
743 | 4 | - | ||
744 | 5 | !record {model: account.statement.profile, id: profile_test}: | ||
745 | 6 | name: Bank EUR Profile for automatic checks | ||
746 | 7 | journal_id: account.bank_journal | ||
747 | 8 | commission_account_id: account.a_expense | ||
748 | 9 | company_id: base.main_company | ||
749 | 10 | - | ||
750 | 11 | Now I create a statement. I create statment lines separately because I need | ||
751 | 12 | to find each one by XML id | ||
752 | 13 | - | ||
753 | 14 | !record {model: account.bank.statement, id: statement_test}: | ||
754 | 15 | name: My Statement | ||
755 | 16 | profile_id: profile_test | ||
756 | 17 | company_id: base.main_company | ||
757 | 18 | - | ||
758 | 19 | I create a first statement line | ||
759 | 20 | - | ||
760 | 21 | !record {model: account.bank.statement.line, id: statement_line_1}: | ||
761 | 22 | name: line1 | ||
762 | 23 | statement_id: statement_test | ||
763 | 24 | ref: ref1 | ||
764 | 25 | date: '2014-01-20' | ||
765 | 26 | amount: 100.0 | ||
766 | 27 | - | ||
767 | 28 | I create a second statement line | ||
768 | 29 | - | ||
769 | 30 | !record {model: account.bank.statement.line, id: statement_line_2}: | ||
770 | 31 | name: line2 | ||
771 | 32 | statement_id: statement_test | ||
772 | 33 | ref: ref2 | ||
773 | 34 | date: '2014-01-25' | ||
774 | 35 | amount: 200.0 | ||
775 | 36 | - | ||
776 | 37 | I check that the state of the statement is "Draft" | ||
777 | 38 | - | ||
778 | 39 | !assert {model: account.bank.statement, id: statement_test}: | ||
779 | 40 | - state == 'draft' | ||
780 | 41 | - | ||
781 | 42 | I confirm the statement | ||
782 | 43 | - | ||
783 | 44 | !python {model: account.bank.statement}: | | ||
784 | 45 | result = self.button_confirm_bank(cr, uid, [ref("statement_test")]) | ||
785 | 46 | - | ||
786 | 47 | I check that the state of the statement is "Closed" | ||
787 | 48 | - | ||
788 | 49 | !assert {model: account.bank.statement, id: statement_test}: | ||
789 | 50 | - state == 'confirm' | ||
790 | 51 | - | ||
791 | 52 | I check that the state of the statement line is "Confirmed" | ||
792 | 53 | - | ||
793 | 54 | !assert {model: account.bank.statement.line, id: statement_line_1}: | ||
794 | 55 | - state == 'confirmed' | ||
795 | 56 | - | ||
796 | 57 | I check that a move was generated | ||
797 | 58 | - | ||
798 | 59 | !assert {model: account.bank.statement.line, id: statement_line_1}: | ||
799 | 60 | - move_ids | ||
800 | 61 | - | ||
801 | 62 | Now I cancel a statement line | ||
802 | 63 | - | ||
803 | 64 | !python {model: account.bank.statement.line}: | | ||
804 | 65 | result = self.button_cancel(cr, uid, [ref("statement_line_1")]) | ||
805 | 66 | - | ||
806 | 67 | I check that the state of the statement went back to "Draft" | ||
807 | 68 | - | ||
808 | 69 | !assert {model: account.bank.statement, id: statement_test}: | ||
809 | 70 | - state == 'draft' | ||
810 | 71 | - | ||
811 | 72 | I also check that the state of the statement line went back to "Draft" | ||
812 | 73 | - | ||
813 | 74 | !assert {model: account.bank.statement.line, id: statement_line_1}: | ||
814 | 75 | - state == 'draft' | ||
815 | 76 | - | ||
816 | 77 | And the move is not there anymore | ||
817 | 78 | - | ||
818 | 79 | !assert {model: account.bank.statement.line, id: statement_line_1}: | ||
819 | 80 | - move_ids == [] | ||
820 | 0 | 81 | ||
821 | === added file 'account_statement_cancel_line/test/confirm_statement_no_double_moves.yml' | |||
822 | --- account_statement_cancel_line/test/confirm_statement_no_double_moves.yml 1970-01-01 00:00:00 +0000 | |||
823 | +++ account_statement_cancel_line/test/confirm_statement_no_double_moves.yml 2014-06-13 10:06:12 +0000 | |||
824 | @@ -0,0 +1,70 @@ | |||
825 | 1 | - | ||
826 | 2 | I want to check that if I confirm a line and then the whole statement, | ||
827 | 3 | no duplicate moves are created. | ||
828 | 4 | First, I need a statement profile. | ||
829 | 5 | - | ||
830 | 6 | !record {model: account.statement.profile, id: profile_test_10}: | ||
831 | 7 | name: Another Bank EUR Profile for automatic checks | ||
832 | 8 | journal_id: account.bank_journal | ||
833 | 9 | commission_account_id: account.a_expense | ||
834 | 10 | company_id: base.main_company | ||
835 | 11 | - | ||
836 | 12 | Now I create a statement. I create statment lines separately because I need | ||
837 | 13 | to find each one by XML id | ||
838 | 14 | - | ||
839 | 15 | !record {model: account.bank.statement, id: statement_test_10}: | ||
840 | 16 | name: My Statement | ||
841 | 17 | profile_id: profile_test_10 | ||
842 | 18 | company_id: base.main_company | ||
843 | 19 | - | ||
844 | 20 | I create a first statement line | ||
845 | 21 | - | ||
846 | 22 | !record {model: account.bank.statement.line, id: statement_line_11}: | ||
847 | 23 | name: line11 | ||
848 | 24 | statement_id: statement_test_10 | ||
849 | 25 | ref: ref11 | ||
850 | 26 | date: '2014-01-20' | ||
851 | 27 | amount: 100.0 | ||
852 | 28 | - | ||
853 | 29 | I create a second statement line | ||
854 | 30 | - | ||
855 | 31 | !record {model: account.bank.statement.line, id: statement_line_12}: | ||
856 | 32 | name: line12 | ||
857 | 33 | statement_id: statement_test_10 | ||
858 | 34 | ref: ref12 | ||
859 | 35 | date: '2014-01-25' | ||
860 | 36 | amount: 200.0 | ||
861 | 37 | - | ||
862 | 38 | Now I confirm only the first statement line | ||
863 | 39 | - | ||
864 | 40 | !python {model: account.bank.statement.line}: | | ||
865 | 41 | result = self.confirm(cr, uid, [ref("statement_line_11")]) | ||
866 | 42 | - | ||
867 | 43 | I check that the state of the statement is still "Draft" | ||
868 | 44 | - | ||
869 | 45 | !assert {model: account.bank.statement, id: statement_test_10}: | ||
870 | 46 | - state == 'draft' | ||
871 | 47 | - | ||
872 | 48 | I confirm the statement | ||
873 | 49 | - | ||
874 | 50 | !python {model: account.bank.statement}: | | ||
875 | 51 | result = self.button_confirm_bank(cr, uid, [ref("statement_test_10")]) | ||
876 | 52 | - | ||
877 | 53 | I check that the state of the statement is "Closed" | ||
878 | 54 | - | ||
879 | 55 | !assert {model: account.bank.statement, id: statement_test_10}: | ||
880 | 56 | - state == 'confirm' | ||
881 | 57 | - | ||
882 | 58 | I check that a move was generated for the first statment line | ||
883 | 59 | and that the state is confirmed | ||
884 | 60 | - | ||
885 | 61 | !assert {model: account.bank.statement.line, id: statement_line_11}: | ||
886 | 62 | - len(move_ids) == 1 | ||
887 | 63 | - state == 'confirmed' | ||
888 | 64 | - | ||
889 | 65 | I check that a move was generated for the second statment line | ||
890 | 66 | and that the state is confirmed | ||
891 | 67 | - | ||
892 | 68 | !assert {model: account.bank.statement.line, id: statement_line_12}: | ||
893 | 69 | - len(move_ids) == 1 | ||
894 | 70 | - state == 'confirmed' | ||
895 | 0 | 71 | ||
896 | === added file 'account_statement_cancel_line/test/test_confirm_last_line_balance_check.yml' | |||
897 | --- account_statement_cancel_line/test/test_confirm_last_line_balance_check.yml 1970-01-01 00:00:00 +0000 | |||
898 | +++ account_statement_cancel_line/test/test_confirm_last_line_balance_check.yml 2014-06-13 10:06:12 +0000 | |||
899 | @@ -0,0 +1,42 @@ | |||
900 | 1 | - | ||
901 | 2 | I want to check that the behaviour when I confirm the only line of a | ||
902 | 3 | statement that is draft. | ||
903 | 4 | - | ||
904 | 5 | I start with a profile | ||
905 | 6 | - | ||
906 | 7 | !record {model: account.statement.profile, id: profile_test3}: | ||
907 | 8 | name: Profile for automatic checks | ||
908 | 9 | balance_check: True | ||
909 | 10 | journal_id: account.bank_journal | ||
910 | 11 | commission_account_id: account.a_expense | ||
911 | 12 | - | ||
912 | 13 | Now I create a statement. | ||
913 | 14 | - | ||
914 | 15 | !record {model: account.bank.statement, id: statement_test3}: | ||
915 | 16 | name: My Statement | ||
916 | 17 | profile_id: profile_test3 | ||
917 | 18 | company_id: base.main_company | ||
918 | 19 | balance_start: 100.0 | ||
919 | 20 | balance_end_real: 150.0 | ||
920 | 21 | - | ||
921 | 22 | I create a statement line | ||
922 | 23 | - | ||
923 | 24 | !record {model: account.bank.statement.line, id: statement_line_3}: | ||
924 | 25 | name: line1 | ||
925 | 26 | statement_id: statement_test3 | ||
926 | 27 | ref: line1 | ||
927 | 28 | date: '2014-01-20' | ||
928 | 29 | amount: 10.0 | ||
929 | 30 | - | ||
930 | 31 | Now I confirm the statement line. That should not pass the balance check | ||
931 | 32 | - | ||
932 | 33 | !python {model: account.bank.statement.line}: | | ||
933 | 34 | # i.e. assertRaises | ||
934 | 35 | from openerp.osv.osv import except_osv | ||
935 | 36 | try: | ||
936 | 37 | self.confirm(cr, uid, [ref("statement_line_3")]) | ||
937 | 38 | except except_osv as exc: | ||
938 | 39 | print exc.args | ||
939 | 40 | assert u'The statement balance is incorrect' in exc.args[1], 'We got an error which is not what we expected' | ||
940 | 41 | else: | ||
941 | 42 | raise AssertionError('Balance check should have blocked this.') | ||
942 | 0 | 43 | ||
943 | === added file 'account_statement_cancel_line/test/test_confirm_last_line_no_balance_check.yml' | |||
944 | --- account_statement_cancel_line/test/test_confirm_last_line_no_balance_check.yml 1970-01-01 00:00:00 +0000 | |||
945 | +++ account_statement_cancel_line/test/test_confirm_last_line_no_balance_check.yml 2014-06-13 10:06:12 +0000 | |||
946 | @@ -0,0 +1,44 @@ | |||
947 | 1 | - | ||
948 | 2 | I want to check that the behaviour when I confirm the only line of a | ||
949 | 3 | statement that is draft. | ||
950 | 4 | - | ||
951 | 5 | I start with a profile | ||
952 | 6 | - | ||
953 | 7 | !record {model: account.statement.profile, id: profile_test4}: | ||
954 | 8 | name: Profile for automatic checks | ||
955 | 9 | balance_check: False | ||
956 | 10 | journal_id: account.bank_journal | ||
957 | 11 | commission_account_id: account.a_expense | ||
958 | 12 | - | ||
959 | 13 | Now I create a statement. | ||
960 | 14 | - | ||
961 | 15 | !record {model: account.bank.statement, id: statement_test4}: | ||
962 | 16 | name: My Statement | ||
963 | 17 | profile_id: profile_test4 | ||
964 | 18 | company_id: base.main_company | ||
965 | 19 | balance_start: 100.0 | ||
966 | 20 | balance_end_real: 150.0 | ||
967 | 21 | - | ||
968 | 22 | I create a statement line | ||
969 | 23 | - | ||
970 | 24 | !record {model: account.bank.statement.line, id: statement_line_4}: | ||
971 | 25 | name: line1 | ||
972 | 26 | statement_id: statement_test4 | ||
973 | 27 | ref: line1 | ||
974 | 28 | date: '2014-01-20' | ||
975 | 29 | amount: 10.0 | ||
976 | 30 | - | ||
977 | 31 | Now I confirm the statement line | ||
978 | 32 | - | ||
979 | 33 | !python {model: account.bank.statement.line}: | | ||
980 | 34 | result = self.confirm(cr, uid, [ref("statement_line_4")]) | ||
981 | 35 | - | ||
982 | 36 | The line should be confirmed | ||
983 | 37 | - | ||
984 | 38 | !assert {model: account.bank.statement.line, id: statement_line_4}: | ||
985 | 39 | - state == 'confirmed' | ||
986 | 40 | - | ||
987 | 41 | And the statement should be confirmed as well | ||
988 | 42 | - | ||
989 | 43 | !assert {model: account.bank.statement, id: statement_test4}: | ||
990 | 44 | - state == 'confirm' | ||
991 | 0 | 45 | ||
992 | === added directory 'account_statement_cancel_line/tests' | |||
993 | === added directory 'account_statement_cancel_line/wizard' | |||
994 | === added file 'account_statement_cancel_line/wizard/__init__.py' | |||
995 | --- account_statement_cancel_line/wizard/__init__.py 1970-01-01 00:00:00 +0000 | |||
996 | +++ account_statement_cancel_line/wizard/__init__.py 2014-06-13 10:06:12 +0000 | |||
997 | @@ -0,0 +1,24 @@ | |||
998 | 1 | # -*- coding: utf-8 -*- | ||
999 | 2 | ############################################################################### | ||
1000 | 3 | # # | ||
1001 | 4 | # Author: Leonardo Pistone | ||
1002 | 5 | # Copyright 2014 Camptocamp SA | ||
1003 | 6 | # # | ||
1004 | 7 | # This program is free software: you can redistribute it and/or modify # | ||
1005 | 8 | # it under the terms of the GNU Affero General Public License as # | ||
1006 | 9 | # published by the Free Software Foundation, either version 3 of the # | ||
1007 | 10 | # License, or (at your option) any later version. # | ||
1008 | 11 | # # | ||
1009 | 12 | # This program is distributed in the hope that it will be useful, # | ||
1010 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # | ||
1011 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # | ||
1012 | 15 | # GNU Affero General Public License for more details. # | ||
1013 | 16 | # # | ||
1014 | 17 | # You should have received a copy of the GNU Affero General Public License # | ||
1015 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. # | ||
1016 | 19 | # # | ||
1017 | 20 | ############################################################################### | ||
1018 | 21 | """Wizard for asking the confirmation when some move is reconciled.""" | ||
1019 | 22 | |||
1020 | 23 | import cancel_statement # noqa | ||
1021 | 24 | import cancel_statement_line # noqa | ||
1022 | 0 | 25 | ||
1023 | === added file 'account_statement_cancel_line/wizard/cancel_line.py' | |||
1024 | --- account_statement_cancel_line/wizard/cancel_line.py 1970-01-01 00:00:00 +0000 | |||
1025 | +++ account_statement_cancel_line/wizard/cancel_line.py 2014-06-13 10:06:12 +0000 | |||
1026 | @@ -0,0 +1,46 @@ | |||
1027 | 1 | # -*- coding: utf-8 -*- | ||
1028 | 2 | ############################################################################### | ||
1029 | 3 | # # | ||
1030 | 4 | # Author: Leonardo Pistone | ||
1031 | 5 | # Copyright 2014 Camptocamp SA | ||
1032 | 6 | # # | ||
1033 | 7 | # This program is free software: you can redistribute it and/or modify # | ||
1034 | 8 | # it under the terms of the GNU Affero General Public License as # | ||
1035 | 9 | # published by the Free Software Foundation, either version 3 of the # | ||
1036 | 10 | # License, or (at your option) any later version. # | ||
1037 | 11 | # # | ||
1038 | 12 | # This program is distributed in the hope that it will be useful, # | ||
1039 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # | ||
1040 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # | ||
1041 | 15 | # GNU Affero General Public License for more details. # | ||
1042 | 16 | # # | ||
1043 | 17 | # You should have received a copy of the GNU Affero General Public License # | ||
1044 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. # | ||
1045 | 19 | # # | ||
1046 | 20 | ############################################################################### | ||
1047 | 21 | """Wizard to Cancel a Statement Line.""" | ||
1048 | 22 | |||
1049 | 23 | from openerp.osv import orm | ||
1050 | 24 | |||
1051 | 25 | |||
1052 | 26 | class wizard_cancel_statement_line(orm.TransientModel): | ||
1053 | 27 | |||
1054 | 28 | """Wizard to Cancel a Statement Line.""" | ||
1055 | 29 | |||
1056 | 30 | _name = "wizard.cancel.statement.line" | ||
1057 | 31 | _description = "Cancel Statement Line" | ||
1058 | 32 | _columns = { | ||
1059 | 33 | } | ||
1060 | 34 | |||
1061 | 35 | def unreconcile(self, cr, uid, ids, context=None): | ||
1062 | 36 | """Proceed and cancel the statement line, return Action. | ||
1063 | 37 | |||
1064 | 38 | This will delete the move.line and the reconciliation. | ||
1065 | 39 | |||
1066 | 40 | """ | ||
1067 | 41 | return self.pool['account.bank.statement.line'].cancel( | ||
1068 | 42 | cr, | ||
1069 | 43 | uid, | ||
1070 | 44 | context['active_ids'], | ||
1071 | 45 | context=context | ||
1072 | 46 | ) | ||
1073 | 0 | 47 | ||
1074 | === added file 'account_statement_cancel_line/wizard/cancel_statement.py' | |||
1075 | --- account_statement_cancel_line/wizard/cancel_statement.py 1970-01-01 00:00:00 +0000 | |||
1076 | +++ account_statement_cancel_line/wizard/cancel_statement.py 2014-06-13 10:06:12 +0000 | |||
1077 | @@ -0,0 +1,51 @@ | |||
1078 | 1 | # -*- coding: utf-8 -*- | ||
1079 | 2 | ############################################################################### | ||
1080 | 3 | # # | ||
1081 | 4 | # Author: Leonardo Pistone | ||
1082 | 5 | # Copyright 2014 Camptocamp SA | ||
1083 | 6 | # # | ||
1084 | 7 | # This program is free software: you can redistribute it and/or modify # | ||
1085 | 8 | # it under the terms of the GNU Affero General Public License as # | ||
1086 | 9 | # published by the Free Software Foundation, either version 3 of the # | ||
1087 | 10 | # License, or (at your option) any later version. # | ||
1088 | 11 | # # | ||
1089 | 12 | # This program is distributed in the hope that it will be useful, # | ||
1090 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # | ||
1091 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # | ||
1092 | 15 | # GNU Affero General Public License for more details. # | ||
1093 | 16 | # # | ||
1094 | 17 | # You should have received a copy of the GNU Affero General Public License # | ||
1095 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. # | ||
1096 | 19 | # # | ||
1097 | 20 | ############################################################################### | ||
1098 | 21 | """Wizard to Cancel a Statement.""" | ||
1099 | 22 | |||
1100 | 23 | from openerp.osv import orm, fields | ||
1101 | 24 | |||
1102 | 25 | |||
1103 | 26 | class wizard_cancel_statement(orm.TransientModel): | ||
1104 | 27 | |||
1105 | 28 | """Wizard to Cancel a Statement.""" | ||
1106 | 29 | |||
1107 | 30 | _name = "wizard.cancel.statement" | ||
1108 | 31 | _description = "Cancel Statement" | ||
1109 | 32 | _columns = { | ||
1110 | 33 | 'reconcile_warning': fields.boolean( | ||
1111 | 34 | 'Show reconcile warning', | ||
1112 | 35 | help='This is a hidden field set with a default in the context ' | ||
1113 | 36 | 'to choose between two different warning messages in the view.' | ||
1114 | 37 | ), | ||
1115 | 38 | } | ||
1116 | 39 | |||
1117 | 40 | def do_cancel_button(self, cr, uid, ids, context=None): | ||
1118 | 41 | """Proceed and cancel the statement, return Action. | ||
1119 | 42 | |||
1120 | 43 | This will delete the move.line and the reconciliation. | ||
1121 | 44 | |||
1122 | 45 | """ | ||
1123 | 46 | return self.pool['account.bank.statement'].do_cancel( | ||
1124 | 47 | cr, | ||
1125 | 48 | uid, | ||
1126 | 49 | context['active_ids'], | ||
1127 | 50 | context=context | ||
1128 | 51 | ) | ||
1129 | 0 | 52 | ||
1130 | === added file 'account_statement_cancel_line/wizard/cancel_statement_line.py' | |||
1131 | --- account_statement_cancel_line/wizard/cancel_statement_line.py 1970-01-01 00:00:00 +0000 | |||
1132 | +++ account_statement_cancel_line/wizard/cancel_statement_line.py 2014-06-13 10:06:12 +0000 | |||
1133 | @@ -0,0 +1,46 @@ | |||
1134 | 1 | # -*- coding: utf-8 -*- | ||
1135 | 2 | ############################################################################### | ||
1136 | 3 | # # | ||
1137 | 4 | # Author: Leonardo Pistone | ||
1138 | 5 | # Copyright 2014 Camptocamp SA | ||
1139 | 6 | # # | ||
1140 | 7 | # This program is free software: you can redistribute it and/or modify # | ||
1141 | 8 | # it under the terms of the GNU Affero General Public License as # | ||
1142 | 9 | # published by the Free Software Foundation, either version 3 of the # | ||
1143 | 10 | # License, or (at your option) any later version. # | ||
1144 | 11 | # # | ||
1145 | 12 | # This program is distributed in the hope that it will be useful, # | ||
1146 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # | ||
1147 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # | ||
1148 | 15 | # GNU Affero General Public License for more details. # | ||
1149 | 16 | # # | ||
1150 | 17 | # You should have received a copy of the GNU Affero General Public License # | ||
1151 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. # | ||
1152 | 19 | # # | ||
1153 | 20 | ############################################################################### | ||
1154 | 21 | """Wizard to Cancel a Statement Line.""" | ||
1155 | 22 | |||
1156 | 23 | from openerp.osv import orm | ||
1157 | 24 | |||
1158 | 25 | |||
1159 | 26 | class wizard_cancel_statement_line(orm.TransientModel): | ||
1160 | 27 | |||
1161 | 28 | """Wizard to Cancel a Statement Line.""" | ||
1162 | 29 | |||
1163 | 30 | _name = "wizard.cancel.statement.line" | ||
1164 | 31 | _description = "Cancel Statement Line" | ||
1165 | 32 | _columns = { | ||
1166 | 33 | } | ||
1167 | 34 | |||
1168 | 35 | def unreconcile(self, cr, uid, ids, context=None): | ||
1169 | 36 | """Proceed and cancel the statement line, return Action. | ||
1170 | 37 | |||
1171 | 38 | This will delete the move.line and the reconciliation. | ||
1172 | 39 | |||
1173 | 40 | """ | ||
1174 | 41 | return self.pool['account.bank.statement.line'].cancel( | ||
1175 | 42 | cr, | ||
1176 | 43 | uid, | ||
1177 | 44 | context['active_ids'], | ||
1178 | 45 | context=context | ||
1179 | 46 | ) | ||
1180 | 0 | 47 | ||
1181 | === added file 'account_statement_cancel_line/wizard/cancel_statement_line_view.xml' | |||
1182 | --- account_statement_cancel_line/wizard/cancel_statement_line_view.xml 1970-01-01 00:00:00 +0000 | |||
1183 | +++ account_statement_cancel_line/wizard/cancel_statement_line_view.xml 2014-06-13 10:06:12 +0000 | |||
1184 | @@ -0,0 +1,22 @@ | |||
1185 | 1 | <?xml version="1.0" encoding="utf-8"?> | ||
1186 | 2 | <openerp> | ||
1187 | 3 | <data> | ||
1188 | 4 | |||
1189 | 5 | <record id="view_wizard_cancel_statement_line_form" model="ir.ui.view"> | ||
1190 | 6 | <field name="name">view.wizard.cancel.statement.line.form</field> | ||
1191 | 7 | <field name="model">wizard.cancel.statement.line</field> | ||
1192 | 8 | <field name="arch" type="xml"> | ||
1193 | 9 | <form string="Reconciled Entries" version="7.0"> | ||
1194 | 10 | <separator string="Unreconciliation"/> | ||
1195 | 11 | <label string="Some entries are already reconciled. Do you want to unreconcile them and proceed?"/> | ||
1196 | 12 | <footer> | ||
1197 | 13 | <button name="unreconcile" string="Unreconcile" type="object" class="oe_highlight"/> | ||
1198 | 14 | or | ||
1199 | 15 | <button string="Cancel" class="oe_link" special="cancel"/> | ||
1200 | 16 | </footer> | ||
1201 | 17 | </form> | ||
1202 | 18 | </field> | ||
1203 | 19 | </record> | ||
1204 | 20 | |||
1205 | 21 | </data> | ||
1206 | 22 | </openerp> | ||
1207 | 0 | 23 | ||
1208 | === added file 'account_statement_cancel_line/wizard/cancel_statement_view.xml' | |||
1209 | --- account_statement_cancel_line/wizard/cancel_statement_view.xml 1970-01-01 00:00:00 +0000 | |||
1210 | +++ account_statement_cancel_line/wizard/cancel_statement_view.xml 2014-06-13 10:06:12 +0000 | |||
1211 | @@ -0,0 +1,24 @@ | |||
1212 | 1 | <?xml version="1.0" encoding="utf-8"?> | ||
1213 | 2 | <openerp> | ||
1214 | 3 | <data> | ||
1215 | 4 | |||
1216 | 5 | <record id="view_wizard_cancel_statement_form" model="ir.ui.view"> | ||
1217 | 6 | <field name="name">view.wizard.cancel.statement.form</field> | ||
1218 | 7 | <field name="model">wizard.cancel.statement</field> | ||
1219 | 8 | <field name="arch" type="xml"> | ||
1220 | 9 | <form string="Reconciled Entries" version="7.0"> | ||
1221 | 10 | <separator string="Cancel statement"/> | ||
1222 | 11 | <field name="reconcile_warning" invisible="1" /> | ||
1223 | 12 | <label attrs="{'invisible': [('reconcile_warning', '=', False)]}" string="Some entries are already reconciled. Do you want to unreconcile them and proceed?"/> | ||
1224 | 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?"/> | ||
1225 | 14 | <footer> | ||
1226 | 15 | <button name="do_cancel_button" string="Proceed" type="object" class="oe_highlight"/> | ||
1227 | 16 | or | ||
1228 | 17 | <button string="Cancel" class="oe_link" special="cancel"/> | ||
1229 | 18 | </footer> | ||
1230 | 19 | </form> | ||
1231 | 20 | </field> | ||
1232 | 21 | </record> | ||
1233 | 22 | |||
1234 | 23 | </data> | ||
1235 | 24 | </openerp> |
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.