Merge lp:~compassion/banking-addons/banking-addons-mandate into lp:banking-addons

Proposed by Nicolas Bessi - Camptocamp
Status: Work in progress
Proposed branch: lp:~compassion/banking-addons/banking-addons-mandate
Merge into: lp:banking-addons
Diff against target: 1483 lines (+704/-333)
21 files modified
account_banking_mandate/__init__.py (+22/-0)
account_banking_mandate/__openerp__.py (+46/-0)
account_banking_mandate/data/mandate_reference_sequence.xml (+6/-6)
account_banking_mandate/model/__init__.py (+26/-0)
account_banking_mandate/model/account_banking_mandate.py (+185/-0)
account_banking_mandate/model/account_invoice.py (+34/-0)
account_banking_mandate/model/partner_bank.py (+33/-0)
account_banking_mandate/model/payment_line.py (+100/-0)
account_banking_mandate/view/account_banking_mandate_view.xml (+31/-59)
account_banking_mandate/view/account_invoice_view.xml (+2/-2)
account_banking_mandate/view/account_payment_view.xml (+4/-4)
account_banking_mandate/view/res_partner_bank_view.xml (+11/-12)
account_banking_payment_export/model/payment_order_create.py (+6/-0)
account_banking_sepa_direct_debit/__openerp__.py (+2/-5)
account_banking_sepa_direct_debit/account_banking_sdd.py (+13/-212)
account_banking_sepa_direct_debit/data/sdd_mandate_sequence.xml (+17/-0)
account_banking_sepa_direct_debit/mandate_expire_cron.xml (+1/-1)
account_banking_sepa_direct_debit/sdd_mandate_view.xml (+133/-0)
account_banking_sepa_direct_debit/security/ir.model.access.csv (+2/-2)
account_banking_sepa_direct_debit/sepa_direct_debit_demo.xml (+1/-1)
account_banking_sepa_direct_debit/wizard/export_sdd.py (+29/-29)
To merge this branch: bzr merge lp:~compassion/banking-addons/banking-addons-mandate
Reviewer Review Type Date Requested Status
Cyril Sester (community) Needs Resubmitting
Nicolas Bessi - Camptocamp (community) Needs Fixing
Review via email: mp+224428@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote :

Temporary MP to help review

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

See my comments inline

review: Needs Fixing
262. By Cyril Sester

Refactoring, fixed auto add for mandate

263. By Cyril Sester

Fixed initial author. Add SDD ref sequence to stay consistent with previous code.

264. By Cyril Sester

Merged trunk modifs

265. By Cyril Sester

Merge changes

Revision history for this message
Cyril Sester (cyril-sester) wrote :

> See my comments inline

Code has be fixed accordly to comments.

review: Needs Resubmitting

Unmerged revisions

265. By Cyril Sester

Merge changes

264. By Cyril Sester

Merged trunk modifs

263. By Cyril Sester

Fixed initial author. Add SDD ref sequence to stay consistent with previous code.

262. By Cyril Sester

Refactoring, fixed auto add for mandate

261. By Cyril Sester

Merged trunk changes into branch

260. By Cyril Sester

Some comments and refactorings

259. By Cyril Sester <email address hidden>

SEPA demo install correction. Mandate bank onchange method corrected (wrong parent call fixed)

258. By Cyril Sester <email address hidden>

Add SEPA to menuitem/action name/forms titles

257. By Cyril Sester <email address hidden>

sepa mandate splitted to get a generic mandate

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'account_banking_mandate'
2=== added file 'account_banking_mandate/__init__.py'
3--- account_banking_mandate/__init__.py 1970-01-01 00:00:00 +0000
4+++ account_banking_mandate/__init__.py 2014-07-29 07:49:30 +0000
5@@ -0,0 +1,22 @@
6+# -*- encoding: utf-8 -*-
7+##############################################################################
8+#
9+# Mandate module for openERP
10+# Copyright (C) 2014 Compassion CH (http://www.compassion.ch)
11+# @author: Cyril Sester <csester@compassion.ch>
12+#
13+# This program is free software: you can redistribute it and/or modify
14+# it under the terms of the GNU Affero General Public License as
15+# published by the Free Software Foundation, either version 3 of the
16+# License, or (at your option) any later version.
17+#
18+# This program is distributed in the hope that it will be useful,
19+# but WITHOUT ANY WARRANTY; without even the implied warranty of
20+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21+# GNU Affero General Public License for more details.
22+#
23+# You should have received a copy of the GNU Affero General Public License
24+# along with this program. If not, see <http://www.gnu.org/licenses/>.
25+#
26+##############################################################################
27+import model
28\ No newline at end of file
29
30=== added file 'account_banking_mandate/__openerp__.py'
31--- account_banking_mandate/__openerp__.py 1970-01-01 00:00:00 +0000
32+++ account_banking_mandate/__openerp__.py 2014-07-29 07:49:30 +0000
33@@ -0,0 +1,46 @@
34+# -*- encoding: utf-8 -*-
35+##############################################################################
36+#
37+# Mandate module for openERP
38+# Copyright (C) 2014 Compassion CH (http://www.compassion.ch)
39+# @author: Cyril Sester <csester@compassion.ch>,
40+# Alexis de Lattre <alexis.delattre@akretion.com>
41+#
42+# This program is free software: you can redistribute it and/or modify
43+# it under the terms of the GNU Affero General Public License as
44+# published by the Free Software Foundation, either version 3 of the
45+# License, or (at your option) any later version.
46+#
47+# This program is distributed in the hope that it will be useful,
48+# but WITHOUT ANY WARRANTY; without even the implied warranty of
49+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
50+# GNU Affero General Public License for more details.
51+#
52+# You should have received a copy of the GNU Affero General Public License
53+# along with this program. If not, see <http://www.gnu.org/licenses/>.
54+#
55+##############################################################################
56+{
57+ 'name': 'Account Banking Mandate',
58+ 'summary': 'Direct Debit mandate',
59+ 'version': '0.1',
60+ 'license': 'AGPL-3',
61+ 'author': 'Compassion CH',
62+ 'website': 'http://www.compassion.ch',
63+ 'category': 'Banking addons',
64+ 'depends': ['account_payment'],
65+ 'external_dependencies': {},
66+ 'data': [
67+ 'view/account_banking_mandate_view.xml',
68+ 'view/account_invoice_view.xml',
69+ 'view/account_payment_view.xml',
70+ 'view/res_partner_bank_view.xml',
71+ 'data/mandate_reference_sequence.xml',
72+ ],
73+ 'demo': [],
74+ 'description': '''This module adds a generic model for banking mandates. These mandates can be specialized to
75+fit any banking mandates (such as sepa or lsv).
76+''',
77+ 'active': False,
78+ 'installable': True,
79+}
80
81=== added directory 'account_banking_mandate/data'
82=== renamed file 'account_banking_sepa_direct_debit/data/mandate_reference_sequence.xml' => 'account_banking_mandate/data/mandate_reference_sequence.xml'
83--- account_banking_sepa_direct_debit/data/mandate_reference_sequence.xml 2013-10-22 22:25:06 +0000
84+++ account_banking_mandate/data/mandate_reference_sequence.xml 2014-07-29 07:49:30 +0000
85@@ -3,14 +3,14 @@
86 <data noupdate="1">
87
88
89-<record id="sdd_mandate_seq_type" model="ir.sequence.type">
90- <field name="name">SDD Mandate Reference</field>
91- <field name="code">sdd.mandate.reference</field>
92+<record id="dd_mandate_seq_type" model="ir.sequence.type">
93+ <field name="name">DD Mandate Reference</field>
94+ <field name="code">account.banking.mandate</field>
95 </record>
96
97-<record id="sdd_mandate_seq" model="ir.sequence">
98- <field name="name">SDD Mandate Reference</field>
99- <field name="code">sdd.mandate.reference</field>
100+<record id="dd_mandate_seq" model="ir.sequence">
101+ <field name="name">DD Mandate Reference</field>
102+ <field name="code">account.banking.mandate</field>
103 <field name="prefix">RUM</field>
104 <field name="padding" eval="7"/>
105 <!-- remember that max size for the mandate ref is 35 -->
106
107=== added directory 'account_banking_mandate/model'
108=== added file 'account_banking_mandate/model/__init__.py'
109--- account_banking_mandate/model/__init__.py 1970-01-01 00:00:00 +0000
110+++ account_banking_mandate/model/__init__.py 2014-07-29 07:49:30 +0000
111@@ -0,0 +1,26 @@
112+# -*- encoding: utf-8 -*-
113+##############################################################################
114+#
115+# Mandate module for openERP
116+# Copyright (C) 2014 Compassion CH (http://www.compassion.ch)
117+# @author: Cyril Sester <csester@compassion.ch>,
118+# Alexis de Lattre <alexis.delattre@akretion.com>
119+#
120+# This program is free software: you can redistribute it and/or modify
121+# it under the terms of the GNU Affero General Public License as
122+# published by the Free Software Foundation, either version 3 of the
123+# License, or (at your option) any later version.
124+#
125+# This program is distributed in the hope that it will be useful,
126+# but WITHOUT ANY WARRANTY; without even the implied warranty of
127+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
128+# GNU Affero General Public License for more details.
129+#
130+# You should have received a copy of the GNU Affero General Public License
131+# along with this program. If not, see <http://www.gnu.org/licenses/>.
132+#
133+##############################################################################
134+from . import account_banking_mandate
135+from . import account_invoice
136+from . import partner_bank
137+from . import payment_line
138\ No newline at end of file
139
140=== added file 'account_banking_mandate/model/account_banking_mandate.py'
141--- account_banking_mandate/model/account_banking_mandate.py 1970-01-01 00:00:00 +0000
142+++ account_banking_mandate/model/account_banking_mandate.py 2014-07-29 07:49:30 +0000
143@@ -0,0 +1,185 @@
144+# -*- encoding: utf-8 -*-
145+##############################################################################
146+#
147+# Mandate module for openERP
148+# Copyright (C) 2014 Compassion CH (http://www.compassion.ch)
149+# @author: Cyril Sester <csester@compassion.ch>,
150+# Alexis de Lattre <alexis.delattre@akretion.com>
151+#
152+# This program is free software: you can redistribute it and/or modify
153+# it under the terms of the GNU Affero General Public License as
154+# published by the Free Software Foundation, either version 3 of the
155+# License, or (at your option) any later version.
156+#
157+# This program is distributed in the hope that it will be useful,
158+# but WITHOUT ANY WARRANTY; without even the implied warranty of
159+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
160+# GNU Affero General Public License for more details.
161+#
162+# You should have received a copy of the GNU Affero General Public License
163+# along with this program. If not, see <http://www.gnu.org/licenses/>.
164+#
165+##############################################################################
166+
167+from datetime import datetime
168+import logging
169+from openerp.osv import orm, fields
170+from openerp.tools.translate import _
171+
172+logger = logging.getLogger(__name__)
173+
174+class mandate(orm.Model):
175+ ''' The banking mandate is attached to a bank account and represents an
176+ authorization that the bank account owner gives to a company for a specific operation
177+ (such as direct debit)
178+ '''
179+ _name = 'account.banking.mandate'
180+ _description = "A generic banking mandate"
181+ _rec_name = 'unique_mandate_reference'
182+ _inherit = ['mail.thread']
183+ _order = 'signature_date desc'
184+ _track = {
185+ 'state': {
186+ 'account_banking_mandate.mandate_valid':
187+ lambda self, cr, uid, obj, ctx=None:
188+ obj['state'] == 'valid',
189+ 'account_banking_mandate.mandate_expired':
190+ lambda self, cr, uid, obj, ctx=None:
191+ obj['state'] == 'expired',
192+ 'account_banking_mandate.mandate_cancel':
193+ lambda self, cr, uid, obj, ctx=None:
194+ obj['state'] == 'cancel',
195+ },
196+ }
197+
198+ def _get_states(self, cr, uid, context=None):
199+ return (
200+ ('draft', 'Draft'),
201+ ('valid', 'Valid'),
202+ ('expired', 'Expired'),
203+ ('cancel', 'Cancelled'),)
204+
205+ _columns = {
206+ 'partner_bank_id': fields.many2one(
207+ 'res.partner.bank', 'Bank Account', track_visibility='onchange'),
208+ 'partner_id': fields.related(
209+ 'partner_bank_id', 'partner_id', type='many2one',
210+ relation='res.partner', string='Partner', readonly=True),
211+ 'company_id': fields.many2one('res.company', 'Company', required=True),
212+ 'unique_mandate_reference': fields.char(
213+ 'Unique Mandate Reference', size=35, readonly=True,
214+ track_visibility='always'),
215+ 'signature_date': fields.date(
216+ 'Date of Signature of the Mandate', track_visibility='onchange'),
217+ 'scan': fields.binary('Scan of the Mandate'),
218+ 'last_debit_date': fields.date(
219+ 'Date of the Last Debit', readonly=True),
220+ 'state': fields.selection(_get_states, 'Status',
221+ help="Only valid mandates can be used in a payment line. A "
222+ "cancelled mandate is a mandate that has been cancelled by "
223+ "the customer. "),
224+ 'payment_line_ids': fields.one2many(
225+ 'payment.line', 'mandate_id', "Related Payment Lines"),
226+ }
227+
228+ _defaults = {
229+ 'company_id': lambda self, cr, uid, context:
230+ self.pool['res.company']._company_default_get(
231+ cr, uid, 'account.banking.mandate', context=context),
232+ 'state': 'draft',
233+ 'unique_mandate_reference': '/',
234+ }
235+
236+ _sql_constraints = [(
237+ 'mandate_ref_company_uniq',
238+ 'unique(unique_mandate_reference, company_id)',
239+ 'A Mandate with the same reference already exists for this company !'
240+ )]
241+
242+ def create(self, cr, uid, vals, context=None):
243+ if vals.get('unique_mandate_reference', '/') == '/':
244+ sequence = self.pool['ir.sequence']
245+ next_value = sequence.next_by_code(cr, uid, 'account.banking.mandate', context=context)
246+ vals['unique_mandate_reference'] = next_value
247+
248+ return super(mandate, self).create(cr, uid, vals, context=context)
249+
250+ def _check_dates(self, cr, uid, ids):
251+ for mandate in self.browse(cr, uid, ids):
252+ if (mandate.signature_date and
253+ mandate.signature_date >
254+ datetime.today().strftime('%Y-%m-%d')):
255+ raise orm.except_orm(
256+ _('Error:'),
257+ _("The date of signature of mandate '%s' is in the "
258+ "future !")
259+ % mandate.unique_mandate_reference)
260+
261+ if (mandate.signature_date and mandate.last_debit_date and
262+ mandate.signature_date > mandate.last_debit_date):
263+ raise orm.except_orm(
264+ _('Error:'),
265+ _("The mandate '%s' can't have a date of last debit "
266+ "before the date of signature.")
267+ % mandate.unique_mandate_reference)
268+ return True
269+
270+ def _check_valid_state(self, cr, uid, ids):
271+ for mandate in self.browse(cr, uid, ids):
272+ if mandate.state == 'valid' and not mandate.signature_date:
273+ raise orm.except_orm(
274+ _('Error:'),
275+ _("Cannot validate the mandate '%s' without a date of "
276+ "signature.")
277+ % mandate.unique_mandate_reference)
278+ if mandate.state == 'valid' and not mandate.partner_bank_id:
279+ raise orm.except_orm(
280+ _('Error:'),
281+ _("Cannot validate the mandate '%s' because it is not "
282+ "attached to a bank account.")
283+ % mandate.unique_mandate_reference)
284+ return True
285+
286+ _constraints = [
287+ (_check_dates, "Error msg in raise", ['signature_date', 'last_debit_date']),
288+ (_check_valid_state, "Error msg in raise", ['state', 'partner_bank_id']),
289+ ]
290+
291+ def mandate_partner_bank_change(
292+ self, cr, uid, ids, partner_bank_id, last_debit_date, state, context=None):
293+ res = {'value': {}}
294+ if partner_bank_id:
295+ partner_bank_read = self.pool['res.partner.bank'].read(
296+ cr, uid, partner_bank_id, ['partner_id'])['partner_id']
297+ if partner_bank_read:
298+ res['value']['partner_id'] = partner_bank_read[0]
299+ return res
300+
301+ def validate(self, cr, uid, ids, context=None):
302+ to_validate_ids = []
303+ for mandate in self.browse(cr, uid, ids, context=context):
304+ assert mandate.state == 'draft', 'Mandate should be in draft state'
305+ to_validate_ids.append(mandate.id)
306+ self.write(
307+ cr, uid, to_validate_ids, {'state': 'valid'}, context=context)
308+ return True
309+
310+ def cancel(self, cr, uid, ids, context=None):
311+ to_cancel_ids = []
312+ for mandate in self.browse(cr, uid, ids, context=context):
313+ assert mandate.state in ('draft', 'valid'),\
314+ 'Mandate should be in draft or valid state'
315+ to_cancel_ids.append(mandate.id)
316+ self.write(
317+ cr, uid, to_cancel_ids, {'state': 'cancel'}, context=context)
318+ return True
319+
320+ def back2draft(self, cr, uid, ids, context=None):
321+ to_draft_ids = []
322+ for mandate in self.browse(cr, uid, ids, context=context):
323+ assert mandate.state == 'cancel',\
324+ 'Mandate should be in cancel state'
325+ to_draft_ids.append(mandate.id)
326+ self.write(
327+ cr, uid, to_draft_ids, {'state': 'draft'}, context=context)
328+ return True
329\ No newline at end of file
330
331=== added file 'account_banking_mandate/model/account_invoice.py'
332--- account_banking_mandate/model/account_invoice.py 1970-01-01 00:00:00 +0000
333+++ account_banking_mandate/model/account_invoice.py 2014-07-29 07:49:30 +0000
334@@ -0,0 +1,34 @@
335+# -*- encoding: utf-8 -*-
336+##############################################################################
337+#
338+# Mandate module for openERP
339+# Copyright (C) 2014 Compassion CH (http://www.compassion.ch)
340+# @author: Cyril Sester <csester@compassion.ch>,
341+# Alexis de Lattre <alexis.delattre@akretion.com>
342+#
343+# This program is free software: you can redistribute it and/or modify
344+# it under the terms of the GNU Affero General Public License as
345+# published by the Free Software Foundation, either version 3 of the
346+# License, or (at your option) any later version.
347+#
348+# This program is distributed in the hope that it will be useful,
349+# but WITHOUT ANY WARRANTY; without even the implied warranty of
350+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
351+# GNU Affero General Public License for more details.
352+#
353+# You should have received a copy of the GNU Affero General Public License
354+# along with this program. If not, see <http://www.gnu.org/licenses/>.
355+#
356+##############################################################################
357+
358+from openerp.osv import orm, fields
359+
360+class account_invoice(orm.Model):
361+ _inherit = 'account.invoice'
362+
363+ _columns = {
364+ 'mandate_id': fields.many2one(
365+ 'account.banking.mandate', 'Direct Debit Mandate',
366+ domain=[('state', '=', 'valid')], readonly=True,
367+ states={'draft': [('readonly', False)]})
368+ }
369\ No newline at end of file
370
371=== added file 'account_banking_mandate/model/partner_bank.py'
372--- account_banking_mandate/model/partner_bank.py 1970-01-01 00:00:00 +0000
373+++ account_banking_mandate/model/partner_bank.py 2014-07-29 07:49:30 +0000
374@@ -0,0 +1,33 @@
375+# -*- encoding: utf-8 -*-
376+##############################################################################
377+#
378+# Mandate module for openERP
379+# Copyright (C) 2014 Compassion CH (http://www.compassion.ch)
380+# @author: Cyril Sester <csester@compassion.ch>,
381+# Alexis de Lattre <alexis.delattre@akretion.com>
382+#
383+# This program is free software: you can redistribute it and/or modify
384+# it under the terms of the GNU Affero General Public License as
385+# published by the Free Software Foundation, either version 3 of the
386+# License, or (at your option) any later version.
387+#
388+# This program is distributed in the hope that it will be useful,
389+# but WITHOUT ANY WARRANTY; without even the implied warranty of
390+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
391+# GNU Affero General Public License for more details.
392+#
393+# You should have received a copy of the GNU Affero General Public License
394+# along with this program. If not, see <http://www.gnu.org/licenses/>.
395+#
396+##############################################################################
397+
398+from openerp.osv import orm, fields
399+
400+class res_partner_bank(orm.Model):
401+ _inherit = 'res.partner.bank'
402+
403+ #Add mandate references on bank account (a bank account can have several mandates)
404+ _columns = {
405+ 'mandate_ids': fields.one2many(
406+ 'account.banking.mandate', 'partner_bank_id', 'Banking Mandates'),
407+ }
408\ No newline at end of file
409
410=== added file 'account_banking_mandate/model/payment_line.py'
411--- account_banking_mandate/model/payment_line.py 1970-01-01 00:00:00 +0000
412+++ account_banking_mandate/model/payment_line.py 2014-07-29 07:49:30 +0000
413@@ -0,0 +1,100 @@
414+# -*- encoding: utf-8 -*-
415+##############################################################################
416+#
417+# Mandate module for openERP
418+# Copyright (C) 2014 Compassion CH (http://www.compassion.ch)
419+# @author: Cyril Sester <csester@compassion.ch>,
420+# Alexis de Lattre <alexis.delattre@akretion.com>
421+#
422+# This program is free software: you can redistribute it and/or modify
423+# it under the terms of the GNU Affero General Public License as
424+# published by the Free Software Foundation, either version 3 of the
425+# License, or (at your option) any later version.
426+#
427+# This program is distributed in the hope that it will be useful,
428+# but WITHOUT ANY WARRANTY; without even the implied warranty of
429+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
430+# GNU Affero General Public License for more details.
431+#
432+# You should have received a copy of the GNU Affero General Public License
433+# along with this program. If not, see <http://www.gnu.org/licenses/>.
434+#
435+##############################################################################
436+
437+from openerp.osv import orm, fields
438+
439+import logging
440+
441+logger = logging.getLogger(__name__)
442+
443+class payment_line(orm.Model):
444+ _inherit = 'payment.line'
445+
446+ #Add mandate reference on payment line (several payment line can referer to same mandate)
447+ _columns = {
448+ 'mandate_id': fields.many2one(
449+ 'account.banking.mandate', 'Direct Debit Mandate',
450+ domain=[('state', '=', 'valid')]),
451+ }
452+
453+ def create(self, cr, uid, vals, context=None):
454+ '''If the customer invoice has a mandate, take it
455+ otherwise, take the first valid mandate of the bank account.
456+ This is done here and not in _defaults because we need the context.
457+ '''
458+ if context is None:
459+ context = {}
460+ if not vals:
461+ vals = {}
462+ partner_bank_id = vals.get('bank_id')
463+ move_line_id = vals.get('move_line_id')
464+ logger.info("partner_bank_id: %s" % partner_bank_id)
465+ logger.info("move_line_id: %s" % move_line_id)
466+ logger.info("context: %s" % context)
467+ logger.info("vals : %s" % vals)
468+ if (context.get('search_payment_order_type') == 'debit'
469+ and 'mandate_id' not in vals):
470+ if move_line_id:
471+ line = self.pool['account.move.line'].browse(
472+ cr, uid, move_line_id, context=context)
473+ if (line.invoice and line.invoice.type == 'out_invoice'
474+ and line.invoice.mandate_id):
475+ vals.update({
476+ 'mandate_id': line.invoice.mandate_id.id,
477+ 'bank_id':
478+ line.invoice.mandate_id.partner_bank_id.id,
479+ })
480+ if partner_bank_id and 'mandate_id' not in vals:
481+ mandate_ids = self.pool['account.banking.mandate'].search(cr, uid, [
482+ ('partner_bank_id', '=', partner_bank_id),
483+ ('state', '=', 'valid'),
484+ ], context=context)
485+ if mandate_ids:
486+ vals['mandate_id'] = mandate_ids[0]
487+ return super(payment_line, self).create(cr, uid, vals, context=context)
488+
489+ def _check_mandate_bank_link(self, cr, uid, ids):
490+ for payline in self.browse(cr, uid, ids):
491+ if (payline.mandate_id and payline.bank_id
492+ and payline.mandate_id.partner_bank_id.id !=
493+ payline.bank_id.id):
494+ raise orm.except_orm(
495+ _('Error:'),
496+ _("The payment line with reference '%s' has the bank "
497+ "account '%s' which is not attached to the mandate "
498+ "'%s' (this mandate is attached to the bank account "
499+ "'%s').") % (
500+ payline.name,
501+ self.pool['res.partner.bank'].name_get(
502+ cr, uid, [payline.bank_id.id])[0][1],
503+ payline.mandate_id.unique_mandate_reference,
504+ self.pool['res.partner.bank'].name_get(
505+ cr, uid,
506+ [payline.mandate_id.partner_bank_id.id])[0][1],
507+ ))
508+ return True
509+
510+ _constraints = [
511+ (_check_mandate_bank_link, 'Error msg in raise',
512+ ['mandate_id', 'bank_id']),
513+ ]
514\ No newline at end of file
515
516=== added directory 'account_banking_mandate/view'
517=== renamed file 'account_banking_sepa_direct_debit/sdd_mandate_view.xml' => 'account_banking_mandate/view/account_banking_mandate_view.xml'
518--- account_banking_sepa_direct_debit/sdd_mandate_view.xml 2014-06-11 22:03:21 +0000
519+++ account_banking_mandate/view/account_banking_mandate_view.xml 2014-07-29 07:49:30 +0000
520@@ -7,11 +7,11 @@
521 <openerp>
522 <data>
523
524-<record id="sdd_mandate_form" model="ir.ui.view">
525- <field name="name">sdd.mandate.form</field>
526- <field name="model">sdd.mandate</field>
527+<record id="dd_mandate_form" model="ir.ui.view">
528+ <field name="name">dd.mandate.form</field>
529+ <field name="model">account.banking.mandate</field>
530 <field name="arch" type="xml">
531- <form string="SEPA Direct Debit Mandate" version="7.0">
532+ <form string="Banking Mandate" version="7.0">
533 <header>
534 <button name="validate" type="object" string="Validate" states="draft" class="oe_highlight"/>
535 <button name="cancel" type="object" string="Cancel" states="draft,valid"/>
536@@ -29,17 +29,13 @@
537 <group name="main">
538 <field name="company_id" groups="base.group_multi_company"/>
539 <field name="partner_bank_id"
540- on_change="mandate_partner_bank_change(partner_bank_id, type, recurrent_sequence_type, last_debit_date, state)"
541- invisible="context.get('sdd_mandate_bank_partner_view')"
542+ on_change="mandate_partner_bank_change(partner_bank_id, last_debit_date, state)"
543+ invisible="context.get('dd_mandate_bank_partner_view')"
544 />
545- <field name="partner_id" invisible="context.get('sdd_mandate_bank_partner_view')"/>
546- <field name="type" on_change="mandate_type_change(type)"/>
547- <field name="recurrent_sequence_type" attrs="{'invisible': [('type', '=', 'oneoff')], 'required': [('type', '=', 'recurrent')]}"/>
548+ <field name="partner_id" invisible="context.get('dd_mandate_bank_partner_view')"/>
549 <field name="signature_date"/>
550 <field name="scan"/>
551 <field name="last_debit_date"/>
552- <field name="sepa_migrated" groups="account_banking_sepa_direct_debit.group_original_mandate_required"/>
553- <field name="original_mandate_identification" attrs="{'invisible': [('sepa_migrated', '=', True)], 'required': [('sepa_migrated', '=', False)]}" groups="account_banking_sepa_direct_debit.group_original_mandate_required"/>
554 </group>
555 <group name="payment_lines" string="Related Payment Lines">
556 <field name="payment_line_ids" nolabel="1"/>
557@@ -53,15 +49,14 @@
558 </field>
559 </record>
560
561-<record id="sdd_mandate_tree" model="ir.ui.view">
562- <field name="name">sdd.mandate.tree</field>
563- <field name="model">sdd.mandate</field>
564+<record id="dd_mandate_tree" model="ir.ui.view">
565+ <field name="name">dd.mandate.tree</field>
566+ <field name="model">account.banking.mandate</field>
567 <field name="arch" type="xml">
568- <tree string="SEPA Direct Debit Mandate" colors="blue:state=='draft';black:state in ('expired', 'cancel')">
569+ <tree string="Banking Mandate" colors="blue:state=='draft';black:state in ('expired', 'cancel')">
570 <field name="company_id" groups="base.group_multi_company"/>
571- <field name="partner_id" invisible="context.get('sdd_mandate_bank_partner_view')"/>
572+ <field name="partner_id" invisible="context.get('dd_mandate_bank_partner_view')"/>
573 <field name="unique_mandate_reference" string="Reference"/>
574- <field name="type" string="Type"/>
575 <field name="signature_date" string="Signature Date"/>
576 <field name="last_debit_date"/>
577 <field name="state"/>
578@@ -69,83 +64,60 @@
579 </field>
580 </record>
581
582-<record id="sdd_mandate_search" model="ir.ui.view">
583- <field name="name">sdd.mandate.search</field>
584- <field name="model">sdd.mandate</field>
585+<record id="dd_mandate_search" model="ir.ui.view">
586+ <field name="name">dd.mandate.search</field>
587+ <field name="model">account.banking.mandate</field>
588 <field name="arch" type="xml">
589- <search string="Search SEPA Direct Debit Mandates">
590+ <search string="Search Banking Mandates">
591 <field name="partner_id"/>
592 <filter name="draft" string="Draft" domain="[('state', '=', 'draft')]" />
593 <filter name="valid" string="Valid" domain="[('state', '=', 'valid')]" />
594 <filter name="cancel" string="Cancelled" domain="[('state', '=', 'cancel')]" />
595 <filter name="expired" string="Expired" domain="[('state', '=', 'expired')]" />
596- <filter name="oneoff" string="One-Off" domain="[('type', '=', 'oneoff')]" />
597- <filter name="recurrent" string="Recurrent" domain="[('type', '=', 'recurrent')]" />
598 </search>
599 </field>
600 </record>
601
602-<record id="sdd_mandate_action" model="ir.actions.act_window">
603- <field name="name">SEPA Direct Debit Mandates</field>
604- <field name="res_model">sdd.mandate</field>
605+<record id="dd_mandate_action" model="ir.actions.act_window">
606+ <field name="name">Banking Mandates</field>
607+ <field name="res_model">account.banking.mandate</field>
608 <field name="view_type">form</field>
609 <field name="view_mode">tree,form</field>
610 <field name="help" type="html">
611 <p class="oe_view_nocontent_create">
612- Click to create a new SEPA Direct Debit Mandate.
613+ Click to create a new Banking Mandate.
614 </p><p>
615- A SEPA Direct Debit Mandate is a document signed by your customer that gives you the autorization to do one or several direct debits on his bank account.
616+ A banking mandate is a document signed by your customer that gives you the autorization to do one or several operations on his bank account.
617 </p>
618 </field>
619 </record>
620
621-<menuitem id="sdd_mandate_menu"
622+<menuitem id="dd_mandate_menu"
623 parent="account_payment.menu_main_payment"
624- action="sdd_mandate_action"
625+ action="dd_mandate_action"
626 sequence="20"
627 />
628
629-<!-- notifications in the chatter -->
630+<!-- notifications statuses in the chatter -->
631 <record id="mandate_valid" model="mail.message.subtype">
632 <field name="name">Mandate Validated</field>
633- <field name="res_model">sdd.mandate</field>
634+ <field name="res_model">account.banking.mandate</field>
635 <field name="default" eval="False"/>
636- <field name="description">SEPA Direct Debit Mandate Validated</field>
637+ <field name="description">Direct Debit Mandate Validated</field>
638 </record>
639
640 <record id="mandate_expired" model="mail.message.subtype">
641 <field name="name">Mandate Expired</field>
642- <field name="res_model">sdd.mandate</field>
643+ <field name="res_model">account.banking.mandate</field>
644 <field name="default" eval="False"/>
645- <field name="description">SEPA Direct Debit Mandate has Expired</field>
646+ <field name="description">Direct Debit Mandate has Expired</field>
647 </record>
648
649 <record id="mandate_cancel" model="mail.message.subtype">
650 <field name="name">Mandate Cancelled</field>
651- <field name="res_model">sdd.mandate</field>
652- <field name="default" eval="False"/>
653- <field name="description">SEPA Direct Debit Mandate Cancelled</field>
654-</record>
655-
656-<record id="recurrent_sequence_type_first" model="mail.message.subtype">
657- <field name="name">Sequence Type set to First</field>
658- <field name="res_model">sdd.mandate</field>
659- <field name="default" eval="False"/>
660- <field name="description">Sequence Type set to First</field>
661-</record>
662-
663-<record id="recurrent_sequence_type_recurring" model="mail.message.subtype">
664- <field name="name">Sequence Type set to Recurring</field>
665- <field name="res_model">sdd.mandate</field>
666- <field name="default" eval="False"/>
667- <field name="description">Sequence Type set to Recurring</field>
668-</record>
669-
670-<record id="recurrent_sequence_type_final" model="mail.message.subtype">
671- <field name="name">Sequence Type set to Final</field>
672- <field name="res_model">sdd.mandate</field>
673- <field name="default" eval="False"/>
674- <field name="description">Sequence Type set to Final</field>
675+ <field name="res_model">account.banking.mandate</field>
676+ <field name="default" eval="False"/>
677+ <field name="description">Direct Debit Mandate Cancelled</field>
678 </record>
679
680 </data>
681
682=== renamed file 'account_banking_sepa_direct_debit/account_invoice_view.xml' => 'account_banking_mandate/view/account_invoice_view.xml'
683--- account_banking_sepa_direct_debit/account_invoice_view.xml 2013-11-09 14:05:07 +0000
684+++ account_banking_mandate/view/account_invoice_view.xml 2014-07-29 07:49:30 +0000
685@@ -8,12 +8,12 @@
686 <data>
687
688 <record id="invoice_form" model="ir.ui.view">
689- <field name="name">add.sdd.mandate.on.customer.invoice.form</field>
690+ <field name="name">add.dd.mandate.on.customer.invoice.form</field>
691 <field name="model">account.invoice</field>
692 <field name="inherit_id" ref="account.invoice_form"/>
693 <field name="arch" type="xml">
694 <field name="partner_bank_id" position="after">
695- <field name="sdd_mandate_id" domain="[('partner_id', '=', partner_id), ('state', '=', 'valid')]" attrs="{'invisible': [('type', '=', 'out_refund')]}"/>
696+ <field name="mandate_id" domain="[('partner_id', '=', partner_id), ('state', '=', 'valid')]" attrs="{'invisible': [('type', '=', 'out_refund')]}"/>
697 </field>
698 </field>
699 </record>
700
701=== renamed file 'account_banking_sepa_direct_debit/account_payment_view.xml' => 'account_banking_mandate/view/account_payment_view.xml'
702--- account_banking_sepa_direct_debit/account_payment_view.xml 2013-11-11 10:56:49 +0000
703+++ account_banking_mandate/view/account_payment_view.xml 2014-07-29 07:49:30 +0000
704@@ -7,17 +7,17 @@
705 <openerp>
706 <data>
707
708-<record id="sdd_view_payment_order_form" model="ir.ui.view">
709- <field name="name">sdd.payment.order.form</field>
710+<record id="dd_view_payment_order_form" model="ir.ui.view">
711+ <field name="name">dd.payment.order.form</field>
712 <field name="model">payment.order</field>
713 <field name="inherit_id" ref="account_payment.view_payment_order_form"/>
714 <field name="arch" type="xml">
715 <xpath expr="//field[@name='line_ids']/form/notebook/page/group/field[@name='bank_id']" position="after">
716- <field name="sdd_mandate_id" domain="[('partner_bank_id', '=', bank_id), ('state', '=', 'valid')]" invisible="context.get('default_payment_order_type')!='debit'" context="{'default_partner_bank_id': bank_id}"/>
717+ <field name="mandate_id" domain="[('partner_bank_id', '=', bank_id), ('state', '=', 'valid')]" invisible="context.get('default_payment_order_type')!='debit'" context="{'default_partner_bank_id': bank_id}"/>
718 <newline />
719 </xpath>
720 <xpath expr="//field[@name='line_ids']/tree/field[@name='bank_id']" position="after">
721- <field name="sdd_mandate_id" string="SDD Mandate" invisible="context.get('default_payment_order_type')!='debit'"/>
722+ <field name="mandate_id" string="DD Mandate" invisible="context.get('default_payment_order_type')!='debit'"/>
723 </xpath>
724 </field>
725 </record>
726
727=== renamed file 'account_banking_sepa_direct_debit/res_partner_bank_view.xml' => 'account_banking_mandate/view/res_partner_bank_view.xml'
728--- account_banking_sepa_direct_debit/res_partner_bank_view.xml 2013-11-11 10:56:49 +0000
729+++ account_banking_mandate/view/res_partner_bank_view.xml 2014-07-29 07:49:30 +0000
730@@ -7,39 +7,38 @@
731 <openerp>
732 <data>
733
734-<record id="sdd_mandate_partner_bank_form" model="ir.ui.view">
735- <field name="name">sdd.mandate.res.partner.bank.form</field>
736+<record id="dd_mandate_partner_bank_form" model="ir.ui.view">
737+ <field name="name">dd.mandate.res.partner.bank.form</field>
738 <field name="model">res.partner.bank</field>
739 <field name="inherit_id" ref="base.view_partner_bank_form"/>
740 <field name="arch" type="xml">
741 <group name="bank" position="after">
742- <group name="sdd_mandates" string="SEPA Direct Debit Mandates" colspan="4">
743- <field name="sdd_mandate_ids" context="{'default_partner_bank_id': active_id, 'sdd_mandate_bank_partner_view': True}" nolabel="1"/>
744+ <group name="dd_mandates" string="Direct Debit Mandates" colspan="4">
745+ <field name="mandate_ids" context="{'default_partner_bank_id': active_id, 'dd_mandate_bank_partner_view': True}" nolabel="1"/>
746 </group>
747 </group>
748 </field>
749 </record>
750
751-<record id="sdd_mandate_partner_bank_tree" model="ir.ui.view">
752- <field name="name">sdd.mandate.res.partner.bank.tree</field>
753+<record id="dd_mandate_partner_bank_tree" model="ir.ui.view">
754+ <field name="name">dd.mandate.res.partner.bank.tree</field>
755 <field name="model">res.partner.bank</field>
756 <field name="inherit_id" ref="base.view_partner_bank_tree"/>
757 <field name="arch" type="xml">
758 <field name="partner_id" position="after">
759- <field name="sdd_mandate_ids" string="SDD Mandates"/>
760+ <field name="mandate_ids" string="DD Mandates"/>
761 </field>
762 </field>
763 </record>
764
765-<!-- add number of mandates in this list of bank accounts
766-on the partner form -->
767-<record id="sdd_mandate_partner_form" model="ir.ui.view">
768- <field name="name">sdd.mandate.partner.form</field>
769+<!-- add number of mandates in this list of bank accounts on the partner form -->
770+<record id="dd_mandate_partner_form" model="ir.ui.view">
771+ <field name="name">dd.mandate.partner.form</field>
772 <field name="model">res.partner</field>
773 <field name="inherit_id" ref="account.view_partner_property_form"/>
774 <field name="arch" type="xml">
775 <xpath expr="//field[@name='bank_ids']/tree/field[@name='owner_name']" position="after">
776- <field name="sdd_mandate_ids" string="SDD Mandates"/>
777+ <field name="mandate_ids" string="DD Mandates"/>
778 </xpath>
779 </field>
780 </record>
781
782=== modified file 'account_banking_payment_export/model/payment_order_create.py'
783--- account_banking_payment_export/model/payment_order_create.py 2014-03-22 00:53:03 +0000
784+++ account_banking_payment_export/model/payment_order_create.py 2014-07-29 07:49:30 +0000
785@@ -26,6 +26,10 @@
786 from openerp.osv import orm, fields
787 from openerp.tools.translate import _
788
789+import logging
790+
791+logger = logging.getLogger(__name__)
792+
793
794 class payment_order_create(orm.TransientModel):
795 _inherit = 'payment.order.create'
796@@ -48,6 +52,7 @@
797 mod_obj = self.pool.get('ir.model.data')
798 if context is None:
799 context = {}
800+
801 data = self.read(cr, uid, ids, ['duedate'], context=context)[0]
802 search_due_date = data['duedate']
803
804@@ -68,6 +73,7 @@
805 '|', ('date_maturity', '<=', search_due_date),
806 ('date_maturity', '=', False)
807 ]
808+
809 line_ids = line_obj.search(cr, uid, domain, context=context)
810 context.update({'line_ids': line_ids})
811 model_data_ids = mod_obj.search(
812
813=== modified file 'account_banking_sepa_direct_debit/__openerp__.py'
814--- account_banking_sepa_direct_debit/__openerp__.py 2014-03-12 22:18:33 +0000
815+++ account_banking_sepa_direct_debit/__openerp__.py 2014-07-29 07:49:30 +0000
816@@ -27,7 +27,7 @@
817 'author': 'Akretion',
818 'website': 'http://www.akretion.com',
819 'category': 'Banking addons',
820- 'depends': ['account_direct_debit', 'account_banking_pain_base'],
821+ 'depends': ['account_banking_mandate', 'account_banking_pain_base', 'account_direct_debit'],
822 'external_dependencies': {
823 'python': ['unidecode', 'lxml'],
824 },
825@@ -35,14 +35,11 @@
826 'security/original_mandate_required_security.xml',
827 'account_banking_sdd_view.xml',
828 'sdd_mandate_view.xml',
829- 'res_partner_bank_view.xml',
830- 'account_payment_view.xml',
831 'company_view.xml',
832 'mandate_expire_cron.xml',
833- 'account_invoice_view.xml',
834 'wizard/export_sdd_view.xml',
835 'data/payment_type_sdd.xml',
836- 'data/mandate_reference_sequence.xml',
837+ 'data/sdd_mandate_sequence.xml',
838 'security/ir.model.access.csv',
839 ],
840 'demo': ['sepa_direct_debit_demo.xml'],
841
842=== modified file 'account_banking_sepa_direct_debit/account_banking_sdd.py'
843--- account_banking_sepa_direct_debit/account_banking_sdd.py 2014-06-23 09:47:01 +0000
844+++ account_banking_sepa_direct_debit/account_banking_sdd.py 2014-07-29 07:49:30 +0000
845@@ -32,7 +32,6 @@
846
847 logger = logging.getLogger(__name__)
848
849-
850 class banking_export_sdd(orm.Model):
851 '''SEPA Direct Debit export'''
852 _name = 'banking.export.sdd'
853@@ -100,23 +99,10 @@
854
855 class sdd_mandate(orm.Model):
856 '''SEPA Direct Debit Mandate'''
857- _name = 'sdd.mandate'
858 _description = __doc__
859- _rec_name = 'unique_mandate_reference'
860- _inherit = ['mail.thread']
861- _order = 'signature_date desc'
862+ _name = 'account.banking.mandate'
863+ _inherit = 'account.banking.mandate'
864 _track = {
865- 'state': {
866- 'account_banking_sepa_direct_debit.mandate_valid':
867- lambda self, cr, uid, obj, ctx=None:
868- obj['state'] == 'valid',
869- 'account_banking_sepa_direct_debit.mandate_expired':
870- lambda self, cr, uid, obj, ctx=None:
871- obj['state'] == 'expired',
872- 'account_banking_sepa_direct_debit.mandate_cancel':
873- lambda self, cr, uid, obj, ctx=None:
874- obj['state'] == 'cancel',
875- },
876 'recurrent_sequence_type': {
877 'account_banking_sepa_direct_debit.recurrent_sequence_type_first':
878 lambda self, cr, uid, obj, ctx=None:
879@@ -132,15 +118,6 @@
880 }
881
882 _columns = {
883- 'partner_bank_id': fields.many2one(
884- 'res.partner.bank', 'Bank Account', track_visibility='onchange'),
885- 'partner_id': fields.related(
886- 'partner_bank_id', 'partner_id', type='many2one',
887- relation='res.partner', string='Partner', readonly=True),
888- 'company_id': fields.many2one('res.company', 'Company', required=True),
889- 'unique_mandate_reference': fields.char(
890- 'Unique Mandate Reference', size=35, readonly=True,
891- track_visibility='always'),
892 'type': fields.selection([
893 ('recurrent', 'Recurrent'),
894 ('oneoff', 'One-Off'),
895@@ -152,24 +129,6 @@
896 ], 'Sequence Type for Next Debit', track_visibility='onchange',
897 help="This field is only used for Recurrent mandates, not for "
898 "One-Off mandates."),
899- 'signature_date': fields.date(
900- 'Date of Signature of the Mandate', track_visibility='onchange'),
901- 'scan': fields.binary('Scan of the Mandate'),
902- 'last_debit_date': fields.date(
903- 'Date of the Last Debit', readonly=True),
904- 'state': fields.selection([
905- ('draft', 'Draft'),
906- ('valid', 'Valid'),
907- ('expired', 'Expired'),
908- ('cancel', 'Cancelled'),
909- ], 'Status',
910- help="Only valid mandates can be used in a payment line. A "
911- "cancelled mandate is a mandate that has been cancelled by "
912- "the customer. A one-off mandate expires after its first use. "
913- "A recurrent mandate expires after it's final use or if it "
914- "hasn't been used for 36 months."),
915- 'payment_line_ids': fields.one2many(
916- 'payment.line', 'sdd_mandate_id', "Related Payment Lines"),
917 'sepa_migrated': fields.boolean(
918 'Migrated to SEPA', track_visibility='onchange',
919 help="If this field is not active, the mandate section of the "
920@@ -188,57 +147,11 @@
921 }
922
923 _defaults = {
924- 'company_id': lambda self, cr, uid, context:
925- self.pool['res.company']._company_default_get(
926- cr, uid, 'sdd.mandate', context=context),
927- 'unique_mandate_reference': '/',
928- 'state': 'draft',
929 'sepa_migrated': True,
930 }
931
932- _sql_constraints = [(
933- 'mandate_ref_company_uniq',
934- 'unique(unique_mandate_reference, company_id)',
935- 'A Mandate with the same reference already exists for this company !'
936- )]
937-
938- def create(self, cr, uid, vals, context=None):
939- if vals.get('unique_mandate_reference', '/') == '/':
940- vals['unique_mandate_reference'] = \
941- self.pool['ir.sequence'].next_by_code(
942- cr, uid, 'sdd.mandate.reference', context=context)
943- return super(sdd_mandate, self).create(cr, uid, vals, context=context)
944-
945 def _check_sdd_mandate(self, cr, uid, ids):
946 for mandate in self.browse(cr, uid, ids):
947- if (mandate.signature_date and
948- mandate.signature_date >
949- datetime.today().strftime('%Y-%m-%d')):
950- raise orm.except_orm(
951- _('Error:'),
952- _("The date of signature of mandate '%s' is in the "
953- "future !")
954- % mandate.unique_mandate_reference)
955- if mandate.state == 'valid' and not mandate.signature_date:
956- raise orm.except_orm(
957- _('Error:'),
958- _("Cannot validate the mandate '%s' without a date of "
959- "signature.")
960- % mandate.unique_mandate_reference)
961- if mandate.state == 'valid' and not mandate.partner_bank_id:
962- raise orm.except_orm(
963- _('Error:'),
964- _("Cannot validate the mandate '%s' because it is not "
965- "attached to a bank account.")
966- % mandate.unique_mandate_reference)
967-
968- if (mandate.signature_date and mandate.last_debit_date and
969- mandate.signature_date > mandate.last_debit_date):
970- raise orm.except_orm(
971- _('Error:'),
972- _("The mandate '%s' can't have a date of last debit "
973- "before the date of signature.")
974- % mandate.unique_mandate_reference)
975 if (mandate.type == 'recurrent'
976 and not mandate.recurrent_sequence_type):
977 raise orm.except_orm(
978@@ -265,11 +178,18 @@
979
980 _constraints = [
981 (_check_sdd_mandate, "Error msg in raise", [
982- 'last_debit_date', 'signature_date', 'state', 'partner_bank_id',
983 'type', 'recurrent_sequence_type', 'sepa_migrated',
984 'original_mandate_identification',
985 ]),
986 ]
987+
988+ def create(self, cr, uid, vals, context=None):
989+ if vals.get('unique_mandate_reference', '/') == '/':
990+ sequence = self.pool['ir.sequence']
991+ next_value = sequence.next_by_code(cr, uid, 'sdd.mandate.reference', context=context)
992+ vals['unique_mandate_reference'] = next_value
993+
994+ return super(sdd_mandate, self).create(cr, uid, vals, context=context)
995
996 def mandate_type_change(self, cr, uid, ids, type):
997 if type == 'recurrent':
998@@ -282,12 +202,8 @@
999 def mandate_partner_bank_change(
1000 self, cr, uid, ids, partner_bank_id, type, recurrent_sequence_type,
1001 last_debit_date, state):
1002- res = {'value': {}}
1003- if partner_bank_id:
1004- partner_bank_read = self.pool['res.partner.bank'].read(
1005- cr, uid, partner_bank_id, ['partner_id'])['partner_id']
1006- if partner_bank_read:
1007- res['value']['partner_id'] = partner_bank_read[0]
1008+ res = super(sdd_mandate, self).mandate_partner_bank_change(cr, uid,
1009+ ids, partner_bank_id, last_debit_date, state)
1010 if (state == 'valid' and partner_bank_id
1011 and type == 'recurrent'
1012 and recurrent_sequence_type != 'first'):
1013@@ -301,35 +217,6 @@
1014 }
1015 return res
1016
1017- def validate(self, cr, uid, ids, context=None):
1018- to_validate_ids = []
1019- for mandate in self.browse(cr, uid, ids, context=context):
1020- assert mandate.state == 'draft', 'Mandate should be in draft state'
1021- to_validate_ids.append(mandate.id)
1022- self.write(
1023- cr, uid, to_validate_ids, {'state': 'valid'}, context=context)
1024- return True
1025-
1026- def cancel(self, cr, uid, ids, context=None):
1027- to_cancel_ids = []
1028- for mandate in self.browse(cr, uid, ids, context=context):
1029- assert mandate.state in ('draft', 'valid'),\
1030- 'Mandate should be in draft or valid state'
1031- to_cancel_ids.append(mandate.id)
1032- self.write(
1033- cr, uid, to_cancel_ids, {'state': 'cancel'}, context=context)
1034- return True
1035-
1036- def back2draft(self, cr, uid, ids, context=None):
1037- to_draft_ids = []
1038- for mandate in self.browse(cr, uid, ids, context=context):
1039- assert mandate.state == 'cancel',\
1040- 'Mandate should be in cancel state'
1041- to_draft_ids.append(mandate.id)
1042- self.write(
1043- cr, uid, to_draft_ids, {'state': 'draft'}, context=context)
1044- return True
1045-
1046 def _sdd_mandate_set_state_to_expired(self, cr, uid, context=None):
1047 logger.info('Searching for SDD Mandates that must be set to Expired')
1048 expire_limit_date = datetime.today() + \
1049@@ -351,90 +238,4 @@
1050 % expired_mandate_ids)
1051 else:
1052 logger.info('0 SDD Mandates must be set to Expired')
1053- return True
1054-
1055-
1056-class res_partner_bank(orm.Model):
1057- _inherit = 'res.partner.bank'
1058-
1059- _columns = {
1060- 'sdd_mandate_ids': fields.one2many(
1061- 'sdd.mandate', 'partner_bank_id', 'SEPA Direct Debit Mandates'),
1062- }
1063-
1064-
1065-class payment_line(orm.Model):
1066- _inherit = 'payment.line'
1067-
1068- _columns = {
1069- 'sdd_mandate_id': fields.many2one(
1070- 'sdd.mandate', 'SEPA Direct Debit Mandate',
1071- domain=[('state', '=', 'valid')]),
1072- }
1073-
1074- def create(self, cr, uid, vals, context=None):
1075- '''If the customer invoice has a mandate, take it
1076- otherwise, take the first valid mandate of the bank account'''
1077- if context is None:
1078- context = {}
1079- if not vals:
1080- vals = {}
1081- partner_bank_id = vals.get('bank_id')
1082- move_line_id = vals.get('move_line_id')
1083- if (context.get('default_payment_order_type') == 'debit'
1084- and 'sdd_mandate_id' not in vals):
1085- if move_line_id:
1086- line = self.pool['account.move.line'].browse(
1087- cr, uid, move_line_id, context=context)
1088- if (line.invoice and line.invoice.type == 'out_invoice'
1089- and line.invoice.sdd_mandate_id):
1090- vals.update({
1091- 'sdd_mandate_id': line.invoice.sdd_mandate_id.id,
1092- 'bank_id':
1093- line.invoice.sdd_mandate_id.partner_bank_id.id,
1094- })
1095- if partner_bank_id and 'sdd_mandate_id' not in vals:
1096- mandate_ids = self.pool['sdd.mandate'].search(cr, uid, [
1097- ('partner_bank_id', '=', partner_bank_id),
1098- ('state', '=', 'valid'),
1099- ], context=context)
1100- if mandate_ids:
1101- vals['sdd_mandate_id'] = mandate_ids[0]
1102- return super(payment_line, self).create(cr, uid, vals, context=context)
1103-
1104- def _check_mandate_bank_link(self, cr, uid, ids):
1105- for payline in self.browse(cr, uid, ids):
1106- if (payline.sdd_mandate_id and payline.bank_id
1107- and payline.sdd_mandate_id.partner_bank_id.id !=
1108- payline.bank_id.id):
1109- raise orm.except_orm(
1110- _('Error:'),
1111- _("The payment line with reference '%s' has the bank "
1112- "account '%s' which is not attached to the mandate "
1113- "'%s' (this mandate is attached to the bank account "
1114- "'%s').") % (
1115- payline.name,
1116- self.pool['res.partner.bank'].name_get(
1117- cr, uid, [payline.bank_id.id])[0][1],
1118- payline.sdd_mandate_id.unique_mandate_reference,
1119- self.pool['res.partner.bank'].name_get(
1120- cr, uid,
1121- [payline.sdd_mandate_id.partner_bank_id.id])[0][1],
1122- ))
1123- return True
1124-
1125- _constraints = [
1126- (_check_mandate_bank_link, 'Error msg in raise',
1127- ['sdd_mandate_id', 'bank_id']),
1128- ]
1129-
1130-
1131-class account_invoice(orm.Model):
1132- _inherit = 'account.invoice'
1133-
1134- _columns = {
1135- 'sdd_mandate_id': fields.many2one(
1136- 'sdd.mandate', 'SEPA Direct Debit Mandate',
1137- domain=[('state', '=', 'valid')], readonly=True,
1138- states={'draft': [('readonly', False)]})
1139- }
1140+ return True
1141\ No newline at end of file
1142
1143=== added file 'account_banking_sepa_direct_debit/data/sdd_mandate_sequence.xml'
1144--- account_banking_sepa_direct_debit/data/sdd_mandate_sequence.xml 1970-01-01 00:00:00 +0000
1145+++ account_banking_sepa_direct_debit/data/sdd_mandate_sequence.xml 2014-07-29 07:49:30 +0000
1146@@ -0,0 +1,17 @@
1147+<?xml version="1.0" encoding="utf-8"?>
1148+<openerp>
1149+<data noupdate="1">
1150+ <record id="sdd_mandate_seq_type" model="ir.sequence.type">
1151+ <field name="name">SDD Mandate Reference</field>
1152+ <field name="code">sdd.mandate.reference</field>
1153+ </record>
1154+
1155+ <record id="sdd_mandate_seq" model="ir.sequence">
1156+ <field name="name">SDD Mandate Reference</field>
1157+ <field name="code">sdd.mandate.reference</field>
1158+ <field name="prefix">RUM</field>
1159+ <field name="padding" eval="7"/>
1160+ <!-- remember that max size for the mandate ref is 35 -->
1161+ </record>
1162+</data>
1163+</openerp>
1164
1165=== modified file 'account_banking_sepa_direct_debit/mandate_expire_cron.xml'
1166--- account_banking_sepa_direct_debit/mandate_expire_cron.xml 2013-11-07 22:22:19 +0000
1167+++ account_banking_sepa_direct_debit/mandate_expire_cron.xml 2014-07-29 07:49:30 +0000
1168@@ -17,7 +17,7 @@
1169 <field name="interval_type">days</field>
1170 <field name="numbercall">-1</field> <!-- don't limit the number of calls -->
1171 <field name="doall" eval="False"/>
1172- <field name="model" eval="'sdd.mandate'"/>
1173+ <field name="model" eval="'account.banking.mandate'"/>
1174 <field name="function" eval="'_sdd_mandate_set_state_to_expired'" />
1175 <field name="args" eval="'()'"/>
1176 </record>
1177
1178=== added file 'account_banking_sepa_direct_debit/sdd_mandate_view.xml'
1179--- account_banking_sepa_direct_debit/sdd_mandate_view.xml 1970-01-01 00:00:00 +0000
1180+++ account_banking_sepa_direct_debit/sdd_mandate_view.xml 2014-07-29 07:49:30 +0000
1181@@ -0,0 +1,133 @@
1182+<?xml version="1.0" encoding="utf-8"?>
1183+<!--
1184+ Copyright (C) 2013 Akretion (http://www.akretion.com)
1185+ @author: Alexis de Lattre <alexis.delattre@akretion.com>
1186+ The licence is in the file __openerp__.py
1187+-->
1188+<!--
1189+ Customize all mandate views (and actions) to fit SEPA mandate style
1190+-->
1191+<openerp>
1192+<data>
1193+ <record id="sdd_mandate_form" model="ir.ui.view">
1194+ <field name="name">sdd.mandate.form</field>
1195+ <field name="model">account.banking.mandate</field>
1196+ <field name="inherit_id" ref="account_banking_mandate.dd_mandate_form"/>
1197+ <field name="arch" type="xml">
1198+ <data>
1199+ <xpath expr="//field[@name='partner_id']" position="after">
1200+ <field name="type" on_change="mandate_type_change(type)"/>
1201+ <field name="recurrent_sequence_type" attrs="{'invisible': [('type', '=', 'oneoff')], 'required': [('type', '=', 'recurrent')]}"/>
1202+ </xpath>
1203+ <xpath expr="//field[@name='partner_bank_id']" position="attributes">
1204+ <attribute name="on_change">mandate_partner_bank_change(partner_bank_id, type, recurrent_sequence_type, last_debit_date, state)</attribute>
1205+ </xpath>
1206+ <xpath expr="//field[@name='last_debit_date']" position="after">
1207+ <field name="sepa_migrated" groups="account_banking_sepa_direct_debit.group_original_mandate_required"/>
1208+ <field name="original_mandate_identification" attrs="{'invisible': [('sepa_migrated', '=', True)], 'required': [('sepa_migrated', '=', False)]}" groups="account_banking_sepa_direct_debit.group_original_mandate_required"/>
1209+ </xpath>
1210+ </data>
1211+ </field>
1212+ </record>
1213+
1214+ <record id="sdd_mandate_tree" model="ir.ui.view">
1215+ <field name="name">sdd.mandate.tree</field>
1216+ <field name="model">account.banking.mandate</field>
1217+ <field name="inherit_id" ref="account_banking_mandate.dd_mandate_tree"/>
1218+ <field name="arch" type="xml">
1219+ <data>
1220+ <xpath expr="//field[@name='unique_mandate_reference']" position="after">
1221+ <field name="type" string="Type"/>
1222+ </xpath>
1223+ </data>
1224+ </field>
1225+ </record>
1226+
1227+ <record id="sdd_mandate_search" model="ir.ui.view">
1228+ <field name="name">sdd.mandate.search</field>
1229+ <field name="model">account.banking.mandate</field>
1230+ <field name="inherit_id" ref="account_banking_mandate.dd_mandate_search"/>
1231+ <field name="arch" type="xml">
1232+ <xpath expr="//filter[@name='expired']" position="after">
1233+ <filter name="oneoff" string="One-Off" domain="[('type', '=', 'oneoff')]" />
1234+ <filter name="recurrent" string="Recurrent" domain="[('type', '=', 'recurrent')]" />
1235+ </xpath>
1236+ </field>
1237+ </record>
1238+
1239+ <record id="dd_mandate_action" model="ir.actions.act_window">
1240+ <field name="name">SEPA Direct Debit Mandates</field>
1241+ <field name="res_model">account.banking.mandate</field>
1242+ <field name="view_type">form</field>
1243+ <field name="view_mode">tree,form</field>
1244+ <field name="help" type="html">
1245+ <p class="oe_view_nocontent_create">
1246+ Click to create a new SEPA Direct Debit Mandate.
1247+ </p><p>
1248+ A SEPA Direct Debit Mandate is a document signed by your customer that gives you the autorization to do one or several direct debits on his bank account.
1249+ </p>
1250+ </field>
1251+ </record>
1252+
1253+ <menuitem id="account_banking_mandate.dd_mandate_menu"
1254+ parent="account_payment.menu_main_payment"
1255+ action="dd_mandate_action"
1256+ sequence="40"
1257+ />
1258+
1259+ <record id="sdd_mandate_partner_bank_form" model="ir.ui.view">
1260+ <field name="name">sdd.mandate.res.partner.bank.form</field>
1261+ <field name="model">res.partner.bank</field>
1262+ <field name="inherit_id" ref="account_banking_mandate.dd_mandate_partner_bank_form"/>
1263+ <field name="arch" type="xml">
1264+ <xpath expr="//group[@name='dd_mandates']" position="attributes">
1265+ <attribute name="string">SEPA Direct Debit Mandates</attribute>
1266+ </xpath>
1267+ </field>
1268+ </record>
1269+
1270+ <record id="sdd_mandate_partner_bank_tree" model="ir.ui.view">
1271+ <field name="name">sdd.mandate.res.partner.bank.tree</field>
1272+ <field name="model">res.partner.bank</field>
1273+ <field name="inherit_id" ref="account_banking_mandate.dd_mandate_partner_bank_tree"/>
1274+ <field name="arch" type="xml">
1275+ <xpath expr="//field[@name='mandate_ids']" position="attributes">
1276+ <attribute name="string">SDD Mandates</attribute>
1277+ </xpath>
1278+ </field>
1279+ </record>
1280+
1281+ <record id="sdd_mandate_partner_form" model="ir.ui.view">
1282+ <field name="name">sdd.mandate.partner.form</field>
1283+ <field name="model">res.partner</field>
1284+ <field name="inherit_id" ref="account_banking_mandate.dd_mandate_partner_form"/>
1285+ <field name="arch" type="xml">
1286+ <xpath expr="//field[@name='bank_ids']/tree/field[@name='mandate_ids']" position="attributes">
1287+ <attribute name="string">SDD Mandates</attribute>
1288+ </xpath>
1289+ </field>
1290+ </record>
1291+
1292+ <!-- notifications in the chatter -->
1293+ <record id="recurrent_sequence_type_first" model="mail.message.subtype">
1294+ <field name="name">Sequence Type set to First</field>
1295+ <field name="res_model">account.banking.mandate</field>
1296+ <field name="default" eval="False"/>
1297+ <field name="description">Sequence Type set to First</field>
1298+ </record>
1299+
1300+ <record id="recurrent_sequence_type_recurring" model="mail.message.subtype">
1301+ <field name="name">Sequence Type set to Recurring</field>
1302+ <field name="res_model">account.banking.mandate</field>
1303+ <field name="default" eval="False"/>
1304+ <field name="description">Sequence Type set to Recurring</field>
1305+ </record>
1306+
1307+ <record id="recurrent_sequence_type_final" model="mail.message.subtype">
1308+ <field name="name">Sequence Type set to Final</field>
1309+ <field name="res_model">account.banking.mandate</field>
1310+ <field name="default" eval="False"/>
1311+ <field name="description">Sequence Type set to Final</field>
1312+ </record>
1313+</data>
1314+</openerp>
1315
1316=== modified file 'account_banking_sepa_direct_debit/security/ir.model.access.csv'
1317--- account_banking_sepa_direct_debit/security/ir.model.access.csv 2013-10-15 21:29:28 +0000
1318+++ account_banking_sepa_direct_debit/security/ir.model.access.csv 2014-07-29 07:49:30 +0000
1319@@ -1,4 +1,4 @@
1320 "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
1321 "access_banking_export_sdd","Full access on banking.export.sdd","model_banking_export_sdd","account_payment.group_account_payment",1,1,1,1
1322-"access_sdd_mandate","Full access on sdd.mandate","model_sdd_mandate","account_payment.group_account_payment",1,1,1,1
1323-"access_sdd_mandate_read","Read access on sdd.mandate","model_sdd_mandate","base.group_user",1,0,0,0
1324+"access_sdd_mandate","Full access on sdd.mandate","model_account_banking_mandate","account_payment.group_account_payment",1,1,1,1
1325+"access_sdd_mandate_read","Read access on sdd.mandate","model_account_banking_mandate","base.group_user",1,0,0,0
1326
1327=== modified file 'account_banking_sepa_direct_debit/sepa_direct_debit_demo.xml'
1328--- account_banking_sepa_direct_debit/sepa_direct_debit_demo.xml 2014-02-16 14:01:09 +0000
1329+++ account_banking_sepa_direct_debit/sepa_direct_debit_demo.xml 2014-07-29 07:49:30 +0000
1330@@ -15,7 +15,7 @@
1331 <field name="sepa_creditor_identifier">FR78ZZZ424242</field>
1332 </record>
1333
1334-<record id="res_partner_12_mandate" model="sdd.mandate">
1335+<record id="res_partner_12_mandate" model="account.banking.mandate">
1336 <field name="partner_bank_id" ref="account_banking_payment_export.res_partner_12_iban"/>
1337 <field name="type">recurrent</field>
1338 <field name="recurrent_sequence_type">first</field>
1339
1340=== modified file 'account_banking_sepa_direct_debit/wizard/export_sdd.py'
1341--- account_banking_sepa_direct_debit/wizard/export_sdd.py 2014-01-05 23:51:22 +0000
1342+++ account_banking_sepa_direct_debit/wizard/export_sdd.py 2014-07-29 07:49:30 +0000
1343@@ -93,7 +93,7 @@
1344 previous_bank = False
1345 payline_ids = payline_obj.search(
1346 cr, uid, [
1347- ('sdd_mandate_id', '=', payline.sdd_mandate_id.id),
1348+ ('mandate_id', '=', payline.mandate_id.id),
1349 ('bank_id', '!=', payline.bank_id.id),
1350 ],
1351 context=context)
1352@@ -188,22 +188,22 @@
1353 requested_date = payment_order.date_scheduled or today
1354 else:
1355 requested_date = today
1356- if not line.sdd_mandate_id:
1357+ if not line.mandate_id:
1358 raise orm.except_orm(
1359 _('Error:'),
1360 _("Missing SEPA Direct Debit mandate on the payment "
1361 "line with partner '%s' and Invoice ref '%s'.")
1362 % (line.partner_id.name,
1363 line.ml_inv_ref.number))
1364- if line.sdd_mandate_id.state != 'valid':
1365+ if line.mandate_id.state != 'valid':
1366 raise orm.except_orm(
1367 _('Error:'),
1368 _("The SEPA Direct Debit mandate with reference '%s' "
1369 "for partner '%s' has expired.")
1370- % (line.sdd_mandate_id.unique_mandate_reference,
1371- line.sdd_mandate_id.partner_id.name))
1372- if line.sdd_mandate_id.type == 'oneoff':
1373- if not line.sdd_mandate_id.last_debit_date:
1374+ % (line.mandate_id.unique_mandate_reference,
1375+ line.mandate_id.partner_id.name))
1376+ if line.mandate_id.type == 'oneoff':
1377+ if not line.mandate_id.last_debit_date:
1378 seq_type = 'OOFF'
1379 else:
1380 raise orm.except_orm(
1381@@ -212,17 +212,17 @@
1382 "'%s' has type set to 'One-Off' and it has a "
1383 "last debit date set to '%s', so we can't use "
1384 "it.")
1385- % (line.sdd_mandate_id.unique_mandate_reference,
1386- line.sdd_mandate_id.partner_id.name,
1387- line.sdd_mandate_id.last_debit_date))
1388- elif line.sdd_mandate_id.type == 'recurrent':
1389+ % (line.mandate_id.unique_mandate_reference,
1390+ line.mandate_id.partner_id.name,
1391+ line.mandate_id.last_debit_date))
1392+ elif line.mandate_id.type == 'recurrent':
1393 seq_type_map = {
1394 'recurring': 'RCUR',
1395 'first': 'FRST',
1396 'final': 'FNAL',
1397 }
1398 seq_type_label = \
1399- line.sdd_mandate_id.recurrent_sequence_type
1400+ line.mandate_id.recurrent_sequence_type
1401 assert seq_type_label is not False
1402 seq_type = seq_type_map[seq_type_label]
1403
1404@@ -306,22 +306,22 @@
1405 mandate_related_info_2_47, 'MndtId')
1406 mandate_identification_2_48.text = self._prepare_field(
1407 cr, uid, 'Unique Mandate Reference',
1408- 'line.sdd_mandate_id.unique_mandate_reference',
1409+ 'line.mandate_id.unique_mandate_reference',
1410 {'line': line}, 35,
1411 gen_args=gen_args, context=context)
1412 mandate_signature_date_2_49 = etree.SubElement(
1413 mandate_related_info_2_47, 'DtOfSgntr')
1414 mandate_signature_date_2_49.text = self._prepare_field(
1415 cr, uid, 'Mandate Signature Date',
1416- 'line.sdd_mandate_id.signature_date',
1417+ 'line.mandate_id.signature_date',
1418 {'line': line}, 10,
1419 gen_args=gen_args, context=context)
1420 if sequence_type == 'FRST' and (
1421- line.sdd_mandate_id.last_debit_date or
1422- not line.sdd_mandate_id.sepa_migrated):
1423+ line.mandate_id.last_debit_date or
1424+ not line.mandate_id.sepa_migrated):
1425 previous_bank = self._get_previous_bank(
1426 cr, uid, line, context=context)
1427- if previous_bank or not line.sdd_mandate_id.sepa_migrated:
1428+ if previous_bank or not line.mandate_id.sepa_migrated:
1429 amendment_indicator_2_50 = etree.SubElement(
1430 mandate_related_info_2_47, 'AmdmntInd')
1431 amendment_indicator_2_50.text = 'true'
1432@@ -362,13 +362,13 @@
1433 ori_debtor_agent_other, 'Id')
1434 ori_debtor_agent_other_id.text = 'SMNDA'
1435 # SMNDA = Same Mandate New Debtor Agent
1436- elif not line.sdd_mandate_id.sepa_migrated:
1437+ elif not line.mandate_id.sepa_migrated:
1438 ori_mandate_identification_2_52 = etree.SubElement(
1439 amendment_info_details_2_51, 'OrgnlMndtId')
1440 ori_mandate_identification_2_52.text = \
1441 self._prepare_field(
1442 cr, uid, 'Original Mandate Identification',
1443- 'line.sdd_mandate_id.'
1444+ 'line.mandate_id.'
1445 'original_mandate_identification',
1446 {'line': line},
1447 gen_args=gen_args,
1448@@ -425,25 +425,25 @@
1449 wf_service = netsvc.LocalService('workflow')
1450 for order in sepa_export.payment_order_ids:
1451 wf_service.trg_validate(uid, 'payment.order', order.id, 'done', cr)
1452- mandate_ids = [line.sdd_mandate_id.id for line in order.line_ids]
1453- self.pool['sdd.mandate'].write(
1454+ mandate_ids = [line.mandate_id.id for line in order.line_ids]
1455+ self.pool['account.banking.mandate'].write(
1456 cr, uid, mandate_ids,
1457 {'last_debit_date': datetime.today().strftime('%Y-%m-%d')},
1458 context=context)
1459 to_expire_ids = []
1460 first_mandate_ids = []
1461 for line in order.line_ids:
1462- if line.sdd_mandate_id.type == 'oneoff':
1463- to_expire_ids.append(line.sdd_mandate_id.id)
1464- elif line.sdd_mandate_id.type == 'recurrent':
1465- seq_type = line.sdd_mandate_id.recurrent_sequence_type
1466+ if line.mandate_id.type == 'oneoff':
1467+ to_expire_ids.append(line.mandate_id.id)
1468+ elif line.mandate_id.type == 'recurrent':
1469+ seq_type = line.mandate_id.recurrent_sequence_type
1470 if seq_type == 'final':
1471- to_expire_ids.append(line.sdd_mandate_id.id)
1472+ to_expire_ids.append(line.mandate_id.id)
1473 elif seq_type == 'first':
1474- first_mandate_ids.append(line.sdd_mandate_id.id)
1475- self.pool['sdd.mandate'].write(
1476+ first_mandate_ids.append(line.mandate_id.id)
1477+ self.pool['account.banking.mandate'].write(
1478 cr, uid, to_expire_ids, {'state': 'expired'}, context=context)
1479- self.pool['sdd.mandate'].write(
1480+ self.pool['account.banking.mandate'].write(
1481 cr, uid, first_mandate_ids, {
1482 'recurrent_sequence_type': 'recurring',
1483 'sepa_migrated': True,

Subscribers

People subscribed via source and target branches

to status/vote changes: