diff --git a/account_banking_pain_base/models/account_payment_line.py b/account_banking_pain_base/models/account_payment_line.py
index c430b5cff..a460b9551 100644
--- a/account_banking_pain_base/models/account_payment_line.py
+++ b/account_banking_pain_base/models/account_payment_line.py
@@ -15,10 +15,47 @@ class AccountPaymentLine(models.Model):
string='Priority', default='NORM',
help="This field will be used as 'Instruction Priority' in "
"the generated PAIN file.")
- # local_instrument is used in some countries, for example
- # switzerland, cf l10n_ch_sepa that adds some entries in
- # the selection field
+ # local_instrument is used for instant credit transfers which
+ # will begin on November 2017, cf account_banking_sepa_credit_transfer
+ # It is also used in some countries such as switzerland,
+ # cf l10n_ch_pain_base that adds some entries in the selection field
local_instrument = fields.Selection([], string='Local Instrument')
+ category_purpose = fields.Selection([
+ # Full category purpose list found on:
+ # https://www.iso20022.org/external_code_list.page
+ # Document "External Code Sets spreadsheet" version Feb 8th 2017
+ ('BONU', 'Bonus Payment'),
+ ('CASH', 'Cash Management Transfer'),
+ ('CBLK', 'Card Bulk Clearing'),
+ ('CCRD', 'Credit Card Payment'),
+ ('CORT', 'Trade Settlement Payment'),
+ ('DCRD', 'Debit Card Payment'),
+ ('DIVI', 'Dividend'),
+ ('DVPM', 'Deliver Against Payment'),
+ ('EPAY', 'ePayment'),
+ ('FCOL', 'Fee Collection'),
+ ('GOVT', 'Government Payment'),
+ ('HEDG', 'Hedging'),
+ ('ICCP', 'Irrevocable Credit Card Payment'),
+ ('IDCP', 'Irrevocable Debit Card Payment'),
+ ('INTC', 'Intra-Company Payment'),
+ ('INTE', 'Interest'),
+ ('LOAN', 'Loan'),
+ ('OTHR', 'Other Payment'),
+ ('PENS', 'Pension Payment'),
+ ('RVPM', 'Receive Against Payment'),
+ ('SALA', 'Salary Payment'),
+ ('SECU', 'Securities'),
+ ('SSBE', 'Social Security Benefit'),
+ ('SUPP', 'Supplier Payment'),
+ ('TAXS', 'Tax Payment'),
+ ('TRAD', 'Trade'),
+ ('TREA', 'Treasury Payment'),
+ ('VATX', 'VAT Payment'),
+ ('WHLD', 'WithHolding'),
+ ], string="Category Purpose",
+ help="If neither your bank nor your local regulations oblige you to "
+ "set the category purpose, leave the field empty.")
# PAIN allows 140 characters
communication = fields.Char(size=140)
# The field struct_communication_type has been dropped in v9
diff --git a/account_banking_pain_base/models/account_payment_order.py b/account_banking_pain_base/models/account_payment_order.py
index 4e62f6a99..751096e22 100644
--- a/account_banking_pain_base/models/account_payment_order.py
+++ b/account_banking_pain_base/models/account_payment_order.py
@@ -203,8 +203,8 @@ class AccountPaymentOrder(models.Model):
@api.model
def generate_start_payment_info_block(
self, parent_node, payment_info_ident,
- priority, local_instrument, sequence_type, requested_date,
- eval_ctx, gen_args):
+ priority, local_instrument, category_purpose, sequence_type,
+ requested_date, eval_ctx, gen_args):
payment_info = etree.SubElement(parent_node, 'PmtInf')
payment_info_identification = etree.SubElement(
payment_info, 'PmtInfId')
@@ -249,7 +249,12 @@ class AccountPaymentOrder(models.Model):
sequence_type_node = etree.SubElement(
payment_type_info, 'SeqTp')
sequence_type_node.text = sequence_type
-
+ if category_purpose:
+ category_purpose_node = etree.SubElement(
+ payment_type_info, 'CtgyPurp')
+ category_purpose_code = etree.SubElement(
+ category_purpose_node, 'Cd')
+ category_purpose_code.text = category_purpose
if gen_args['payment_method'] == 'DD':
request_date_tag = 'ReqdColltnDt'
else:
diff --git a/account_banking_pain_base/models/bank_payment_line.py b/account_banking_pain_base/models/bank_payment_line.py
index dde080637..c055ac5b4 100644
--- a/account_banking_pain_base/models/bank_payment_line.py
+++ b/account_banking_pain_base/models/bank_payment_line.py
@@ -13,10 +13,12 @@ class BankPaymentLine(models.Model):
local_instrument = fields.Selection(
related='payment_line_ids.local_instrument',
string='Local Instrument')
+ category_purpose = fields.Selection(
+ related='payment_line_ids.category_purpose', string='Category Purpose')
@api.model
def same_fields_payment_line_and_bank_payment_line(self):
res = super(BankPaymentLine, self).\
same_fields_payment_line_and_bank_payment_line()
- res += ['priority', 'local_instrument']
+ res += ['priority', 'local_instrument', 'category_purpose']
return res
diff --git a/account_banking_pain_base/views/account_payment_line.xml b/account_banking_pain_base/views/account_payment_line.xml
index e84958e63..925f43e49 100644
--- a/account_banking_pain_base/views/account_payment_line.xml
+++ b/account_banking_pain_base/views/account_payment_line.xml
@@ -13,7 +13,8 @@
-
+
+
diff --git a/account_banking_pain_base/views/bank_payment_line_view.xml b/account_banking_pain_base/views/bank_payment_line_view.xml
index f9496dffd..d6d05a9b3 100644
--- a/account_banking_pain_base/views/bank_payment_line_view.xml
+++ b/account_banking_pain_base/views/bank_payment_line_view.xml
@@ -13,7 +13,8 @@
-
+
+
diff --git a/account_banking_sepa_credit_transfer/models/__init__.py b/account_banking_sepa_credit_transfer/models/__init__.py
index 105896fa3..3475860d2 100644
--- a/account_banking_sepa_credit_transfer/models/__init__.py
+++ b/account_banking_sepa_credit_transfer/models/__init__.py
@@ -2,3 +2,4 @@
from . import account_payment_method
from . import account_payment_order
+from . import account_payment_line
diff --git a/account_banking_sepa_credit_transfer/models/account_payment_line.py b/account_banking_sepa_credit_transfer/models/account_payment_line.py
new file mode 100644
index 000000000..009887250
--- /dev/null
+++ b/account_banking_sepa_credit_transfer/models/account_payment_line.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# © 2017 Akretion - Alexis de Lattre
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+from odoo import models, fields
+
+
+class AccountPaymentLine(models.Model):
+ _inherit = 'account.payment.line'
+
+ # local_instrument 'INST' used for instant credit transfers
+ # which will begin on November 21st 2017, cf
+ # https://www.europeanpaymentscouncil.eu/document-library/
+ # rulebooks/2017-sepa-instant-credit-transfer-rulebook
+ local_instrument = fields.Selection(
+ selection_add=[('INST', 'Instant Transfer')])
diff --git a/account_banking_sepa_credit_transfer/models/account_payment_order.py b/account_banking_sepa_credit_transfer/models/account_payment_order.py
index 6e629112d..f656a3bb9 100644
--- a/account_banking_sepa_credit_transfer/models/account_payment_order.py
+++ b/account_banking_sepa_credit_transfer/models/account_payment_order.py
@@ -78,34 +78,37 @@ class AccountPaymentOrder(models.Model):
transactions_count_a = 0
amount_control_sum_a = 0.0
lines_per_group = {}
- # key = (requested_date, priority, local_instrument)
+ # key = (requested_date, priority, local_instrument, categ_purpose)
# values = list of lines as object
for line in self.bank_line_ids:
priority = line.priority
local_instrument = line.local_instrument
+ categ_purpose = line.category_purpose
# The field line.date is the requested payment date
# taking into account the 'date_prefered' setting
# cf account_banking_payment_export/models/account_payment.py
# in the inherit of action_open()
- key = (line.date, priority, local_instrument)
+ key = (line.date, priority, local_instrument, categ_purpose)
if key in lines_per_group:
lines_per_group[key].append(line)
else:
lines_per_group[key] = [line]
- for (requested_date, priority, local_instrument), lines in\
- lines_per_group.items():
+ for (requested_date, priority, local_instrument, categ_purpose),\
+ lines in lines_per_group.items():
# B. Payment info
payment_info, nb_of_transactions_b, control_sum_b = \
self.generate_start_payment_info_block(
pain_root,
"self.name + '-' "
"+ requested_date.replace('-', '') + '-' + priority + "
- "'-' + local_instrument",
- priority, local_instrument, False, requested_date, {
+ "'-' + local_instrument + '-' + category_purpose",
+ priority, local_instrument, categ_purpose,
+ False, requested_date, {
'self': self,
'priority': priority,
'requested_date': requested_date,
'local_instrument': local_instrument or 'NOinstr',
+ 'category_purpose': categ_purpose or 'NOcateg',
}, gen_args)
self.generate_party_block(
payment_info, 'Dbtr', 'B',
diff --git a/account_banking_sepa_direct_debit/models/account_payment_order.py b/account_banking_sepa_direct_debit/models/account_payment_order.py
index 116c2e6db..3592437fe 100644
--- a/account_banking_sepa_direct_debit/models/account_payment_order.py
+++ b/account_banking_sepa_direct_debit/models/account_payment_order.py
@@ -68,6 +68,7 @@ class AccountPaymentOrder(models.Model):
for line in self.bank_line_ids:
transactions_count_a += 1
priority = line.priority
+ categ_purpose = line.category_purpose
# The field line.date is the requested payment date
# taking into account the 'date_prefered' setting
# cf account_banking_payment_export/models/account_payment.py
@@ -106,25 +107,27 @@ class AccountPaymentOrder(models.Model):
line.mandate_id.recurrent_sequence_type
assert seq_type_label is not False
seq_type = seq_type_map[seq_type_label]
- key = (line.date, priority, seq_type, scheme)
+ key = (line.date, priority, categ_purpose, seq_type, scheme)
if key in lines_per_group:
lines_per_group[key].append(line)
else:
lines_per_group[key] = [line]
- for (requested_date, priority, sequence_type, scheme), lines in \
- lines_per_group.items():
+ for (requested_date, priority, categ_purpose, sequence_type, scheme),\
+ lines in lines_per_group.items():
# B. Payment info
payment_info, nb_of_transactions_b, control_sum_b = \
self.generate_start_payment_info_block(
pain_root,
"self.name + '-' + "
"sequence_type + '-' + requested_date.replace('-', '') "
- "+ '-' + priority",
- priority, scheme, sequence_type, requested_date, {
+ "+ '-' + priority + '-' + category_purpose",
+ priority, scheme, categ_purpose,
+ sequence_type, requested_date, {
'self': self,
'sequence_type': sequence_type,
'priority': priority,
+ 'category_purpose': categ_purpose or 'NOcateg',
'requested_date': requested_date,
}, gen_args)