101
100
class sdd_mandate(orm.Model):
102
101
'''SEPA Direct Debit Mandate'''
103
_name = 'sdd.mandate'
104
102
_description = __doc__
105
_rec_name = 'unique_mandate_reference'
106
_inherit = ['mail.thread']
107
_order = 'signature_date desc'
103
_name = 'account.banking.mandate'
104
_inherit = 'account.banking.mandate'
110
'account_banking_sepa_direct_debit.mandate_valid':
111
lambda self, cr, uid, obj, ctx=None:
112
obj['state'] == 'valid',
113
'account_banking_sepa_direct_debit.mandate_expired':
114
lambda self, cr, uid, obj, ctx=None:
115
obj['state'] == 'expired',
116
'account_banking_sepa_direct_debit.mandate_cancel':
117
lambda self, cr, uid, obj, ctx=None:
118
obj['state'] == 'cancel',
120
106
'recurrent_sequence_type': {
121
107
'account_banking_sepa_direct_debit.recurrent_sequence_type_first':
122
108
lambda self, cr, uid, obj, ctx=None:
135
'partner_bank_id': fields.many2one(
136
'res.partner.bank', 'Bank Account', track_visibility='onchange'),
137
'partner_id': fields.related(
138
'partner_bank_id', 'partner_id', type='many2one',
139
relation='res.partner', string='Partner', readonly=True),
140
'company_id': fields.many2one('res.company', 'Company', required=True),
141
'unique_mandate_reference': fields.char(
142
'Unique Mandate Reference', size=35, readonly=True,
143
track_visibility='always'),
144
121
'type': fields.selection([
145
122
('recurrent', 'Recurrent'),
146
123
('oneoff', 'One-Off'),
152
129
], 'Sequence Type for Next Debit', track_visibility='onchange',
153
130
help="This field is only used for Recurrent mandates, not for "
154
131
"One-Off mandates."),
155
'signature_date': fields.date(
156
'Date of Signature of the Mandate', track_visibility='onchange'),
157
'scan': fields.binary('Scan of the Mandate'),
158
'last_debit_date': fields.date(
159
'Date of the Last Debit', readonly=True),
160
'state': fields.selection([
163
('expired', 'Expired'),
164
('cancel', 'Cancelled'),
166
help="Only valid mandates can be used in a payment line. A "
167
"cancelled mandate is a mandate that has been cancelled by "
168
"the customer. A one-off mandate expires after its first use. "
169
"A recurrent mandate expires after it's final use or if it "
170
"hasn't been used for 36 months."),
171
'payment_line_ids': fields.one2many(
172
'payment.line', 'sdd_mandate_id', "Related Payment Lines"),
173
132
'sepa_migrated': fields.boolean(
174
133
'Migrated to SEPA', track_visibility='onchange',
175
134
help="If this field is not active, the mandate section of the "
191
'company_id': lambda self, cr, uid, context:
192
self.pool['res.company']._company_default_get(
193
cr, uid, 'sdd.mandate', context=context),
194
'unique_mandate_reference': lambda self, cr, uid, ctx:
195
self.pool['ir.sequence'].get(cr, uid, 'sdd.mandate.reference'),
197
150
'sepa_migrated': True,
200
_sql_constraints = [(
201
'mandate_ref_company_uniq',
202
'unique(unique_mandate_reference, company_id)',
203
'A Mandate with the same reference already exists for this company !'
206
153
def _check_sdd_mandate(self, cr, uid, ids):
207
154
for mandate in self.browse(cr, uid, ids):
208
if (mandate.signature_date and
209
mandate.signature_date >
210
datetime.today().strftime('%Y-%m-%d')):
211
raise orm.except_orm(
213
_("The date of signature of mandate '%s' is in the "
215
% mandate.unique_mandate_reference)
216
if mandate.state == 'valid' and not mandate.signature_date:
217
raise orm.except_orm(
219
_("Cannot validate the mandate '%s' without a date of "
221
% mandate.unique_mandate_reference)
222
if mandate.state == 'valid' and not mandate.partner_bank_id:
223
raise orm.except_orm(
225
_("Cannot validate the mandate '%s' because it is not "
226
"attached to a bank account.")
227
% mandate.unique_mandate_reference)
229
if (mandate.signature_date and mandate.last_debit_date and
230
mandate.signature_date > mandate.last_debit_date):
231
raise orm.except_orm(
233
_("The mandate '%s' can't have a date of last debit "
234
"before the date of signature.")
235
% mandate.unique_mandate_reference)
236
155
if (mandate.type == 'recurrent'
237
156
and not mandate.recurrent_sequence_type):
238
157
raise orm.except_orm(
276
194
def mandate_partner_bank_change(
277
195
self, cr, uid, ids, partner_bank_id, type, recurrent_sequence_type,
278
196
last_debit_date, state):
281
partner_bank_read = self.pool['res.partner.bank'].read(
282
cr, uid, partner_bank_id, ['partner_id'])['partner_id']
283
if partner_bank_read:
284
res['value']['partner_id'] = partner_bank_read[0]
197
res = super(sdd_mandate, self).mandate_partner_bank_change(self, cr, uid,
198
ids, partner_bank_id, last_debit_date, state)
285
199
if (state == 'valid' and partner_bank_id
286
200
and type == 'recurrent'
287
201
and recurrent_sequence_type != 'first'):
298
def validate(self, cr, uid, ids, context=None):
300
for mandate in self.browse(cr, uid, ids, context=context):
301
assert mandate.state == 'draft', 'Mandate should be in draft state'
302
to_validate_ids.append(mandate.id)
304
cr, uid, to_validate_ids, {'state': 'valid'}, context=context)
307
def cancel(self, cr, uid, ids, context=None):
309
for mandate in self.browse(cr, uid, ids, context=context):
310
assert mandate.state in ('draft', 'valid'),\
311
'Mandate should be in draft or valid state'
312
to_cancel_ids.append(mandate.id)
314
cr, uid, to_cancel_ids, {'state': 'cancel'}, context=context)
317
212
def _sdd_mandate_set_state_to_expired(self, cr, uid, context=None):
318
213
logger.info('Searching for SDD Mandates that must be set to Expired')
319
214
expire_limit_date = datetime.today() + \
335
230
% expired_mandate_ids)
337
232
logger.info('0 SDD Mandates must be set to Expired')
341
class res_partner_bank(orm.Model):
342
_inherit = 'res.partner.bank'
345
'sdd_mandate_ids': fields.one2many(
346
'sdd.mandate', 'partner_bank_id', 'SEPA Direct Debit Mandates'),
350
class payment_line(orm.Model):
351
_inherit = 'payment.line'
354
'sdd_mandate_id': fields.many2one(
355
'sdd.mandate', 'SEPA Direct Debit Mandate',
356
domain=[('state', '=', 'valid')]),
359
def create(self, cr, uid, vals, context=None):
360
'''If the customer invoice has a mandate, take it
361
otherwise, take the first valid mandate of the bank account'''
366
partner_bank_id = vals.get('bank_id')
367
move_line_id = vals.get('move_line_id')
368
if (context.get('default_payment_order_type') == 'debit'
369
and 'sdd_mandate_id' not in vals):
371
line = self.pool['account.move.line'].browse(
372
cr, uid, move_line_id, context=context)
373
if (line.invoice and line.invoice.type == 'out_invoice'
374
and line.invoice.sdd_mandate_id):
376
'sdd_mandate_id': line.invoice.sdd_mandate_id.id,
378
line.invoice.sdd_mandate_id.partner_bank_id.id,
380
if partner_bank_id and 'sdd_mandate_id' not in vals:
381
mandate_ids = self.pool['sdd.mandate'].search(cr, uid, [
382
('partner_bank_id', '=', partner_bank_id),
383
('state', '=', 'valid'),
386
vals['sdd_mandate_id'] = mandate_ids[0]
387
return super(payment_line, self).create(cr, uid, vals, context=context)
389
def _check_mandate_bank_link(self, cr, uid, ids):
390
for payline in self.browse(cr, uid, ids):
391
if (payline.sdd_mandate_id and payline.bank_id
392
and payline.sdd_mandate_id.partner_bank_id.id !=
394
raise orm.except_orm(
396
_("The payment line with reference '%s' has the bank "
397
"account '%s' which is not attached to the mandate "
398
"'%s' (this mandate is attached to the bank account "
401
self.pool['res.partner.bank'].name_get(
402
cr, uid, [payline.bank_id.id])[0][1],
403
payline.sdd_mandate_id.unique_mandate_reference,
404
self.pool['res.partner.bank'].name_get(
406
[payline.sdd_mandate_id.partner_bank_id.id])[0][1],
411
(_check_mandate_bank_link, 'Error msg in raise',
412
['sdd_mandate_id', 'bank_id']),
416
class account_invoice(orm.Model):
417
_inherit = 'account.invoice'
420
'sdd_mandate_id': fields.many2one(
421
'sdd.mandate', 'SEPA Direct Debit Mandate',
422
domain=[('state', '=', 'valid')], readonly=True,
423
states={'draft': [('readonly', False)]})
b'\\ No newline at end of file'