mirror of
https://github.com/OCA/bank-payment.git
synced 2025-02-02 10:37:31 +02:00
New field "recurrent_sequence_type" on mandate with tracking. The field "last_debit_date" is not used to compute the sequence type any more. When the bank account changes, the sequence type is set back to first FIX xml_id of expired mandate mail.message.subtype
This commit is contained in:
committed by
Enric Tobella
parent
1c7c1069d2
commit
90c3dc1ab9
@@ -105,6 +105,17 @@ class sdd_mandate(orm.Model):
|
||||
lambda self, cr, uid, obj, ctx=None: obj['state'] == 'expired',
|
||||
'account_banking_sepa_direct_debit.mandate_cancel':
|
||||
lambda self, cr, uid, obj, ctx=None: obj['state'] == 'cancel',
|
||||
},
|
||||
'recurrent_sequence_type': {
|
||||
'account_banking_sepa_direct_debit.recurrent_sequence_type_first':
|
||||
lambda self, cr, uid, obj, ctx=None:
|
||||
obj['recurrent_sequence_type'] == 'first',
|
||||
'account_banking_sepa_direct_debit.recurrent_sequence_type_recurring':
|
||||
lambda self, cr, uid, obj, ctx=None:
|
||||
obj['recurrent_sequence_type'] == 'recurring',
|
||||
'account_banking_sepa_direct_debit.recurrent_sequence_type_final':
|
||||
lambda self, cr, uid, obj, ctx=None:
|
||||
obj['recurrent_sequence_type'] == 'final',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,17 +131,22 @@ class sdd_mandate(orm.Model):
|
||||
('recurrent', 'Recurrent'),
|
||||
('oneoff', 'One-Off'),
|
||||
], 'Type of Mandate', required=True),
|
||||
'recurrent_sequence_type': fields.selection([
|
||||
('first', 'First'),
|
||||
('recurring', 'Recurring'),
|
||||
('final', 'Final'),
|
||||
], 'Sequence Type for Next Debit',
|
||||
help="This field is only used for Recurrent mandates, not for One-Off mandates."),
|
||||
'signature_date': fields.date('Date of Signature of the Mandate'),
|
||||
'scan': fields.binary('Scan of the mandate'),
|
||||
'last_debit_date': fields.date(
|
||||
'Date of the Last Debit',
|
||||
help="For recurrent mandates, this field is used to know if the SDD will be of type 'First' or 'Recurring'. For one-off mandates, this field is used to know if the SDD has already been used or not."),
|
||||
'Date of the Last Debit', readonly=True),
|
||||
'state': fields.selection([
|
||||
('draft', 'Draft'),
|
||||
('valid', 'Valid'),
|
||||
('expired', 'Expired'),
|
||||
('cancel', 'Cancelled'),
|
||||
], 'Mandate Status',
|
||||
], 'Status',
|
||||
help="For a recurrent mandate, this field indicate if the mandate is still valid or if it has expired (a recurrent mandate expires if it's not used during 36 months). For a one-off mandate, it expires after its first use."), # TODO : update help
|
||||
'payment_line_ids': fields.one2many(
|
||||
'payment.line', 'sdd_mandate_id', "Related Payment Lines"),
|
||||
@@ -154,7 +170,8 @@ class sdd_mandate(orm.Model):
|
||||
def _check_sdd_mandate(self, cr, uid, ids, context=None):
|
||||
for mandate in self.read(cr, uid, ids, [
|
||||
'last_debit_date', 'signature_date',
|
||||
'unique_mandate_reference', 'state', 'partner_bank_id'
|
||||
'unique_mandate_reference', 'state', 'partner_bank_id',
|
||||
'type', 'recurrent_sequence_type',
|
||||
], context=context):
|
||||
if (mandate['signature_date'] and
|
||||
mandate['signature_date'] >
|
||||
@@ -171,7 +188,7 @@ class sdd_mandate(orm.Model):
|
||||
if mandate['state'] == 'valid' and not mandate['partner_bank_id']:
|
||||
raise orm.except_orm(
|
||||
_('Error:'),
|
||||
_("Cannot validate the mandate '%s' because it is not linked to a bank account.")
|
||||
_("Cannot validate the mandate '%s' because it is not attached to a bank account.")
|
||||
% mandate['unique_mandate_reference'])
|
||||
|
||||
if (mandate['signature_date'] and mandate['last_debit_date'] and
|
||||
@@ -180,13 +197,45 @@ class sdd_mandate(orm.Model):
|
||||
_('Error:'),
|
||||
_("The mandate '%s' can't have a date of last debit before the date of signature.")
|
||||
% mandate['unique_mandate_reference'])
|
||||
if (mandate['type'] == 'recurrent'
|
||||
and not mandate['recurrent_sequence_type']):
|
||||
raise orm.except_orm(
|
||||
_('Error:'),
|
||||
_("The recurrent mandate '%s' must have a sequence type.")
|
||||
% mandate['unique_mandate_reference'])
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
(_check_sdd_mandate, "Error msg in raise",
|
||||
['last_debit_date', 'signature_date', 'state', 'partner_bank_id']),
|
||||
(_check_sdd_mandate, "Error msg in raise", [
|
||||
'last_debit_date', 'signature_date', 'state', 'partner_bank_id',
|
||||
'type', 'recurrent_sequence_type',
|
||||
]),
|
||||
]
|
||||
|
||||
def mandate_type_change(self, cr, uid, ids, type):
|
||||
if type == 'recurrent':
|
||||
recurrent_sequence_type = 'first'
|
||||
else:
|
||||
recurrent_sequence_type = False
|
||||
res = {'value': {'recurrent_sequence_type': recurrent_sequence_type}}
|
||||
return res
|
||||
|
||||
def mandate_partner_bank_change(
|
||||
self, cr, uid, ids, partner_bank_id, type, recurrent_sequence_type,
|
||||
last_debit_date, state):
|
||||
if (state == 'valid' and partner_bank_id
|
||||
and type == 'recurrent'
|
||||
and recurrent_sequence_type != 'first'):
|
||||
return {
|
||||
'value': {'recurrent_sequence_type': first},
|
||||
'warning': {
|
||||
'title': _('Mandate update'),
|
||||
'message': _("As you changed the bank account attached to this mandate, the 'Sequence Type' has been set back to 'First'."),
|
||||
}
|
||||
}
|
||||
else:
|
||||
return True
|
||||
|
||||
def validate(self, cr, uid, ids, context=None):
|
||||
to_validate_ids = []
|
||||
for mandate in self.browse(cr, uid, ids, context=context):
|
||||
|
||||
@@ -97,11 +97,12 @@
|
||||
<group name="main">
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<field name="partner_id" invisible="not context.get('sdd_mandate_main_view')"/>
|
||||
<field name="type"/>
|
||||
<field name="type" on_change="mandate_type_change(type)"/>
|
||||
<field name="recurrent_sequence_type" attrs="{'invisible': [('type', '=', 'oneoff')], 'required': [('type', '=', 'recurrent')]}"/>
|
||||
<field name="signature_date"/>
|
||||
<field name="scan"/>
|
||||
<field name="last_debit_date"/>
|
||||
<field name="partner_bank_id" invisible="not context.get('sdd_mandate_main_view')"/>
|
||||
<field name="partner_bank_id" on_change="mandate_partner_bank_change(partner_bank_id, type, recurrent_sequence_type, last_debit_date, state)" invisible="not context.get('sdd_mandate_main_view')"/>
|
||||
</group>
|
||||
<group name="payment_lines" string="Related Payment Lines">
|
||||
<field name="payment_line_ids" nolabel="1"/>
|
||||
@@ -119,14 +120,14 @@
|
||||
<field name="name">sdd.mandate.tree</field>
|
||||
<field name="model">sdd.mandate</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="SEPA Direct Debit Mandate" colors="blue:state=='draft';black:state=='expired'">
|
||||
<tree string="SEPA Direct Debit Mandate" colors="blue:state=='draft';black:state in ('expired', 'cancel')">
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<field name="partner_id" invisible="not context.get('sdd_mandate_main_view')"/>
|
||||
<field name="unique_mandate_reference" string="Reference"/>
|
||||
<field name="type" string="Type"/>
|
||||
<field name="signature_date" string="Signature Date"/>
|
||||
<field name="last_debit_date"/>
|
||||
<field name="state" string="Status"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -139,6 +140,7 @@
|
||||
<field name="partner_id"/>
|
||||
<filter name="draft" string="Draft" domain="[('state', '=', 'draft')]" />
|
||||
<filter name="valid" string="Valid" domain="[('state', '=', 'valid')]" />
|
||||
<filter name="cancel" string="Cancelled" domain="[('state', '=', 'cancel')]" />
|
||||
<filter name="expired" string="Expired" domain="[('state', '=', 'expired')]" />
|
||||
<filter name="oneoff" string="One-Off" domain="[('type', '=', 'oneoff')]" />
|
||||
<filter name="recurrent" string="Recurrent" domain="[('type', '=', 'recurrent')]" />
|
||||
@@ -175,7 +177,7 @@
|
||||
<field name="description">SEPA Direct Debit Mandate Validated</field>
|
||||
</record>
|
||||
|
||||
<record id="mandate_expire" model="mail.message.subtype">
|
||||
<record id="mandate_expired" model="mail.message.subtype">
|
||||
<field name="name">Mandate Expired</field>
|
||||
<field name="res_model">sdd.mandate</field>
|
||||
<field name="default" eval="False"/>
|
||||
@@ -189,6 +191,27 @@
|
||||
<field name="description">SEPA Direct Debit Mandate Cancelled</field>
|
||||
</record>
|
||||
|
||||
<record id="recurrent_sequence_type_first" model="mail.message.subtype">
|
||||
<field name="name">Sequence Type set to First</field>
|
||||
<field name="res_model">sdd.mandate</field>
|
||||
<field name="default" eval="False"/>
|
||||
<field name="description">Sequence Type set to First</field>
|
||||
</record>
|
||||
|
||||
<record id="recurrent_sequence_type_recurring" model="mail.message.subtype">
|
||||
<field name="name">Sequence Type set to Recurring</field>
|
||||
<field name="res_model">sdd.mandate</field>
|
||||
<field name="default" eval="False"/>
|
||||
<field name="description">Sequence Type set to Recurring</field>
|
||||
</record>
|
||||
|
||||
<record id="recurrent_sequence_type_final" model="mail.message.subtype">
|
||||
<field name="name">Sequence Type set to Final</field>
|
||||
<field name="res_model">sdd.mandate</field>
|
||||
<field name="default" eval="False"/>
|
||||
<field name="description">Sequence Type set to Final</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="sdd_mandate_partner_bank_form" model="ir.ui.view">
|
||||
<field name="name">sdd.mandate.res.partner.bank.form</field>
|
||||
|
||||
@@ -233,7 +233,7 @@ class banking_export_sdd_wizard(orm.TransientModel):
|
||||
transactions_count_1_6 = 0
|
||||
total_amount = 0.0
|
||||
amount_control_sum_1_7 = 0.0
|
||||
first_recur_lines = {}
|
||||
lines_per_seq_type = {}
|
||||
# key = sequence type ; value = list of lines as objects
|
||||
# Iterate on payment orders
|
||||
for payment_order in sepa_export.payment_order_ids:
|
||||
@@ -253,7 +253,6 @@ class banking_export_sdd_wizard(orm.TransientModel):
|
||||
_("The SEPA Direct Debit mandate with reference '%s' for partner '%s' has expired.")
|
||||
% (line.sdd_mandate_id.unique_mandate_reference,
|
||||
line.sdd_mandate_id.partner_id.name))
|
||||
|
||||
if not line.sdd_mandate_id.signature_date:
|
||||
raise orm.except_orm(
|
||||
_('Error:'),
|
||||
@@ -268,13 +267,12 @@ class banking_export_sdd_wizard(orm.TransientModel):
|
||||
% (line.sdd_mandate_id.unique_mandate_reference,
|
||||
line.sdd_mandate_id.partner_id.name,
|
||||
line.sdd_mandate_id.signature_date))
|
||||
|
||||
if line.sdd_mandate_id.type == 'oneoff':
|
||||
if not line.sdd_mandate_id.last_debit_date:
|
||||
if first_recur_lines.get('OOFF'):
|
||||
first_recur_lines['OOFF'].append(line)
|
||||
if lines_per_seq_type.get('OOFF'):
|
||||
lines_per_seq_type['OOFF'].append(line)
|
||||
else:
|
||||
first_recur_lines['OOFF'] = [line]
|
||||
lines_per_seq_type['OOFF'] = [line]
|
||||
else:
|
||||
raise orm.except_orm(
|
||||
_('Error:'),
|
||||
@@ -283,18 +281,20 @@ class banking_export_sdd_wizard(orm.TransientModel):
|
||||
line.sdd_mandate_id.partner_id.name,
|
||||
line.sdd_mandate_id.last_debit_date))
|
||||
elif line.sdd_mandate_id.type == 'recurrent':
|
||||
if line.sdd_mandate_id.last_debit_date:
|
||||
if first_recur_lines.get('RCUR'):
|
||||
first_recur_lines['RCUR'].append(line)
|
||||
else:
|
||||
first_recur_lines['RCUR'] = [line]
|
||||
seq_type_map = {
|
||||
'recurring': 'RCUR',
|
||||
'first': 'FRST',
|
||||
'final': 'FNAL',
|
||||
}
|
||||
seq_type_label = line.sdd_mandate_id.recurrent_sequence_type
|
||||
assert seq_type_label is not False
|
||||
seq_type = seq_type_map[seq_type_label]
|
||||
if lines_per_seq_type.get(seq_type):
|
||||
lines_per_seq_type[seq_type].append(line)
|
||||
else:
|
||||
if first_recur_lines.get('FRST'):
|
||||
first_recur_lines['FRST'].append(line)
|
||||
else:
|
||||
first_recur_lines['FRST'] = [line]
|
||||
lines_per_seq_type[seq_type] = [line]
|
||||
|
||||
for sequence_type, lines in first_recur_lines.items():
|
||||
for sequence_type, lines in lines_per_seq_type.items():
|
||||
# B. Payment info
|
||||
payment_info_2_0 = etree.SubElement(pain_root, 'PmtInf')
|
||||
payment_info_identification_2_1 = etree.SubElement(
|
||||
@@ -516,14 +516,23 @@ class banking_export_sdd_wizard(orm.TransientModel):
|
||||
wf_service.trg_validate(uid, 'payment.order', order.id, 'done', cr)
|
||||
mandate_ids = [line.sdd_mandate_id.id for line in order.line_ids]
|
||||
self.pool['sdd.mandate'].write(
|
||||
cr, uid, mandate_ids, {
|
||||
'last_debit_date': datetime.today().strftime('%Y-%m-%d')
|
||||
},
|
||||
cr, uid, mandate_ids,
|
||||
{'last_debit_date': datetime.today().strftime('%Y-%m-%d')},
|
||||
context=context)
|
||||
oneoff_mandate_ids = \
|
||||
[line.sdd_mandate_id.id for line in order.line_ids
|
||||
if line.sdd_mandate_id.type == 'oneoff']
|
||||
to_expire_ids = []
|
||||
first_mandate_ids = []
|
||||
for line in order.line_ids:
|
||||
if line.sdd_mandate_id.type == 'oneoff':
|
||||
to_expire_ids.append(line.sdd_mandate_id.id)
|
||||
elif line.sdd_mandate_id.type == 'recurrent':
|
||||
seq_type = line.sdd_mandate_id.recurrent_sequence_type
|
||||
if seq_type == 'final':
|
||||
to_expire_ids.append(line.sdd_mandate_id.id)
|
||||
elif seq_type == 'first':
|
||||
first_mandate_ids.append(line.sdd_mandate_id.id)
|
||||
self.pool['sdd.mandate'].write(
|
||||
cr, uid, oneoff_mandate_ids, {'state': 'expired'},
|
||||
context=context)
|
||||
cr, uid, to_expire_ids, {'state': 'expired'}, context=context)
|
||||
self.pool['sdd.mandate'].write(
|
||||
cr, uid, first_mandate_ids,
|
||||
{'recurrent_sequence_type': 'recurring'}, context=context)
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
Reference in New Issue
Block a user