Store sepa message id and sepa payment info id

issue11052
review389451002
This commit is contained in:
Sergi Almacellas Abellana committed 2022-04-07 10:29:56 +02:00
1 parent 9ca39f5781
commit eb57a814a8
14 files changed
+100 -13

No files matched your search

+1
View File
@@ -1,3 +1,4 @@
* Store sepa message id and sepa payment info id
* Add support for Python 3.10
* Remove support for Python 3.6
* Rename generate_message button to sepa_generate_message
+61 -7
View File
@@ -3,6 +3,7 @@
import datetime
import os
import unicodedata
import uuid
from io import BytesIO
from itertools import groupby
@@ -23,7 +24,8 @@ from trytond.modules.account_payment.exceptions import ProcessError
from trytond.modules.company import CompanyReport
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval, If
from trytond.tools import grouped_slice, reduce_ids, sortable_values
from trytond.tools import (
grouped_slice, lstrip_wildcard, reduce_ids, sortable_values)
from trytond.transaction import Transaction
from .sepa_handler import CAMT054
@@ -189,6 +191,10 @@ class Group(metaclass=PoolMeta):
'invisible': ~Eval('sepa_messages'),
},
depends=['company'])
sepa_id = fields.Char("SEPA ID", readonly=True, size=35,
states={
'invisible': ~Eval('sepa_id'),
})
@classmethod
def __setup__(cls):
@@ -238,6 +244,15 @@ class Group(metaclass=PoolMeta):
gettext('account_payment_sepa'
'.msg_payment_process_no_iban',
payment=payment.rec_name))
to_write = []
for key, payments in self.sepa_payments:
to_write.append(payments)
to_write.append({
'sepa_info_id': self.sepa_group_payment_id(key),
})
if to_write:
Payment.write(*to_write)
self.sepa_id = uuid.uuid4().hex
self.sepa_generate_message(_save=False)
@dualmethod
@@ -267,17 +282,17 @@ class Group(metaclass=PoolMeta):
return self.company.party
def sepa_group_payment_key(self, payment):
key = (('date', payment.date),)
key = (
('payment_info', payment.sepa_info_id),
('date', payment.date),
)
if self.kind == 'receivable':
key += (('sequence_type', payment.sepa_mandate_sequence_type),)
key += (('scheme', payment.sepa_mandate.scheme),)
return key
def sepa_group_payment_id(self, key):
payment_id = str(key['date'].toordinal())
if self.kind == 'receivable':
payment_id += '-' + key['sequence_type']
return payment_id
return key['payment_info'] or uuid.uuid4().hex
@property
def sepa_payments(self):
@@ -292,7 +307,23 @@ class Group(metaclass=PoolMeta):
@property
def sepa_message_id(self):
return self.number
return self.sepa_id or self.number
@classmethod
def search_rec_name(cls, name, clause):
if clause[1].startswith('!') or clause[1].startswith('not '):
bool_op = 'AND'
else:
bool_op = 'OR'
code_value = clause[2]
if clause[1].endswith('like'):
code_value = lstrip_wildcard(clause[2])
domain = super().search_rec_name(name, clause)
return [
bool_op,
domain,
('sepa_id', clause[1], code_value) + tuple(clause[3:]),
]
class Payment(metaclass=PoolMeta):
@@ -335,6 +366,10 @@ class Payment(metaclass=PoolMeta):
'get_sepa_end_to_end_id', searcher='search_end_to_end_id')
sepa_instruction_id = fields.Function(fields.Char('SEPA Instruction ID'),
'get_sepa_instruction_id', searcher='search_sepa_instruction_id')
sepa_info_id = fields.Char("SEPA Info ID", readonly=True, size=35,
states={
'invisible': ~Eval('sepa_info_id'),
})
@classmethod
def copy(cls, payments, default=None):
@@ -417,6 +452,25 @@ class Payment(metaclass=PoolMeta):
}),
]
@classmethod
def search_rec_name(cls, name, clause):
domain = super().search_rec_name(name, clause)
if domain:
if clause[1].startswith('!') or clause[1].startswith('not '):
bool_op = 'AND'
else:
bool_op = 'OR'
domain = [
bool_op,
domain,
]
code_value = clause[2]
if clause[1].endswith('like'):
code_value = lstrip_wildcard(clause[2])
domain.append(
('sepa_info_id', clause[1], code_value) + tuple(clause[3:]))
return domain
class Mandate(Workflow, ModelSQL, ModelView):
'SEPA Mandate'
+10
View File
@@ -14,12 +14,22 @@ this repository contains the full copyright notices and license terms. -->
<field name="inherit" ref="account_payment.payment_group_view_form"/>
<field name="name">payment_group_form</field>
</record>
<record model="ir.ui.view" id="group_list">
<field name="model">account.payment.group</field>
<field name="inherit" ref="account_payment.payment_group_view_list"/>
<field name="name">payment_group_list</field>
</record>
<record model="ir.ui.view" id="payment_view_form">
<field name="model">account.payment</field>
<field name="inherit" ref="account_payment.payment_view_form"/>
<field name="name">payment_form</field>
</record>
<record model="ir.ui.view" id="payment_view_list">
<field name="model">account.payment</field>
<field name="inherit" ref="account_payment.payment_view_list"/>
<field name="name">payment_list</field>
</record>
<record model="ir.ui.view" id="mandate_view_form">
<field name="model">account.payment.sepa.mandate</field>
+1 -1
View File
@@ -41,7 +41,7 @@ this repository contains the full copyright notices and license terms. -->
<!-- FwdgAgt -->
</GrpHdr>
<PmtInf py:for="key, payments in group.sepa_payments">
<PmtInfId>${group.sepa_group_payment_id(key)[:35]}</PmtInfId>
<PmtInfId>${key['payment_info'][:35]}</PmtInfId>
<PmtMtd>TRF</PmtMtd>
<BtchBookg>${'true' if group.journal.sepa_batch_booking else 'false'}</BtchBookg>
<NbOfTxs>${len(payments)}</NbOfTxs>
+1 -1
View File
@@ -22,7 +22,7 @@ this repository contains the full copyright notices and license terms. -->
<!-- FwdgAgt -->
</GrpHdr>
<PmtInf py:for="key, payments in group.sepa_payments">
<PmtInfId>${group.sepa_group_payment_id(key)[:35]}</PmtInfId>
<PmtInfId>${key['payment_info'][:35]}</PmtInfId>
<PmtMtd>TRF</PmtMtd>
<BtchBookg>${'true' if group.journal.sepa_batch_booking else 'false'}</BtchBookg>
<NbOfTxs>${len(payments)}</NbOfTxs>
+1 -1
View File
@@ -21,7 +21,7 @@ this repository contains the full copyright notices and license terms. -->
</InitgPty>
</GrpHdr>
<PmtInf py:for="key, payments in group.sepa_payments">
<PmtInfId>${group.sepa_group_payment_id(key)[:35]}</PmtInfId>
<PmtInfId>${key['payment_info'][:35]}</PmtInfId>
<PmtMtd>TRF</PmtMtd>
<BtchBookg>${'true' if group.journal.sepa_batch_booking else 'false'}</BtchBookg>
<NbOfTxs>${len(payments)}</NbOfTxs>
+1 -1
View File
@@ -41,7 +41,7 @@ this repository contains the full copyright notices and license terms. -->
<!-- FwdgAgt -->
</GrpHdr>
<PmtInf py:for="key, payments in group.sepa_payments">
<PmtInfId>${group.sepa_group_payment_id(key)[:35]}</PmtInfId>
<PmtInfId>${key['payment_info'][:35]}</PmtInfId>
<PmtMtd>DD</PmtMtd>
<BtchBookg>${'true' if group.journal.sepa_batch_booking else 'false'}</BtchBookg>
<NbOfTxs>${len(payments)}</NbOfTxs>
+1 -1
View File
@@ -22,7 +22,7 @@ this repository contains the full copyright notices and license terms. -->
<!-- FwdgAgt -->
</GrpHdr>
<PmtInf py:for="key, payments in group.sepa_payments">
<PmtInfId>${group.sepa_group_payment_id(key)[:35]}</PmtInfId>
<PmtInfId>${key['payment_info'][:35]}</PmtInfId>
<PmtMtd>DD</PmtMtd>
<BtchBookg>${'true' if group.journal.sepa_batch_booking else 'false'}</BtchBookg>
<NbOfTxs>${len(payments)}</NbOfTxs>
+1 -1
View File
@@ -21,7 +21,7 @@ this repository contains the full copyright notices and license terms. -->
</InitgPty>
</GrpHdr>
<PmtInf py:for="key, payments in group.sepa_payments">
<PmtInfId>${group.sepa_group_payment_id(key)[:35]}</PmtInfId>
<PmtInfId>${key['payment_info'][:35]}</PmtInfId>
<PmtMtd>DD</PmtMtd>
<BtchBookg>${'true' if group.journal.sepa_batch_booking else 'false'}</BtchBookg>
<NbOfTxs>${len(payments)}</NbOfTxs>
+2
View File
@@ -355,6 +355,8 @@ class AccountPaymentSepaTestCase(CompanyTestMixin, ModuleTestCase):
for payment in payments:
self.assertEqual(payment.sepa_mandate_sequence_type, 'RCUR')
self.assertTrue(payment.sepa_info_id)
self.assertIsNotNone(payment.group.sepa_id)
@with_transaction()
def handle_camt054(self, flavor):
+2
View File
@@ -5,6 +5,8 @@ this repository contains the full copyright notices and license terms. -->
<xpath expr="//notebook/page[@id='info']" position="inside">
<label name="sepa_mandate"/>
<field name="sepa_mandate"/>
<label name="sepa_info_id"/>
<field name="sepa_info_id"/>
<separator id="sepa_return_reason" string="Return Reason" colspan="4"/>
<label name="sepa_return_reason_code" string="Code"/>
<field name="sepa_return_reason_code"/>
+2
View File
@@ -3,6 +3,8 @@
this repository contains the full copyright notices and license terms. -->
<data>
<xpath expr="/form/field[@name='kind']" position="after">
<label name="sepa_id"/>
<field name="sepa_id" colspan="3"/>
<field name="sepa_messages" colspan="4"/>
<button name="sepa_generate_message" colspan="4"/>
</xpath>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<data>
<xpath expr="/tree/field[@name='kind']" position="after">
<field name="sepa_id" optional="0" expand="1"/>
</xpath>
</data>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<data>
<xpath expr="/tree/field[@name='party']" position="after">
<field name="sepa_info_id" expand="1" optional="0"/>
</xpath>
</data>