mirror of
https://github.com/OCA/bank-payment.git
synced 2025-02-02 10:37:31 +02:00
2 modifications following a real-life SDD with a French bank:
- convert accented chars to ascii chars (via the unidecode lib) - use "PrvtId" instead of "OrgId" in the XML Use the sequence of payment.order as the "Message identification" of the XML file (advantages : it is unique, users can easily customize the sequence and users can easily find the payment corresponding to the "Message Identification" in OpenERP). It is also used as the Payment Identification, combined with the sequence type. Use the sequence of payment.line in the "EndtoEnd Identification" field. Reduce flake8 warnings.
This commit is contained in:
@@ -23,4 +23,3 @@
|
||||
from . import company
|
||||
from . import wizard
|
||||
from . import account_banking_sdd
|
||||
|
||||
|
||||
@@ -22,18 +22,19 @@
|
||||
from openerp.osv import orm, fields
|
||||
from openerp.tools.translate import _
|
||||
from openerp.addons.decimal_precision import decimal_precision as dp
|
||||
from unidecode import unidecode
|
||||
|
||||
|
||||
class banking_export_sdd(orm.Model):
|
||||
'''SEPA Direct Debit export'''
|
||||
_name = 'banking.export.sdd'
|
||||
_description = __doc__
|
||||
_rec_name = 'msg_identification'
|
||||
_rec_name = 'filename'
|
||||
|
||||
def _generate_filename(self, cr, uid, ids, name, arg, context=None):
|
||||
res = {}
|
||||
for sepa_file in self.browse(cr, uid, ids, context=context):
|
||||
res[sepa_file.id] = 'sdd_' + (sepa_file.msg_identification or '') + '.xml'
|
||||
res[sepa_file.id] = 'sdd_%s.xml' % (sepa_file.payment_order_ids[0].reference and unidecode(sepa_file.payment_order_ids[0].reference.replace('/', '-')) or 'error')
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
@@ -43,13 +44,15 @@ class banking_export_sdd(orm.Model):
|
||||
'banking_export_sepa_id', 'account_order_id',
|
||||
'Payment orders',
|
||||
readonly=True),
|
||||
'requested_collec_date': fields.date('Requested collection date', readonly=True),
|
||||
'nb_transactions': fields.integer('Number of transactions', readonly=True),
|
||||
'total_amount': fields.float('Total amount',
|
||||
digits_compute=dp.get_precision('Account'), readonly=True),
|
||||
'msg_identification': fields.char('Message identification', size=35,
|
||||
'requested_collec_date': fields.date(
|
||||
'Requested collection date', readonly=True),
|
||||
'nb_transactions': fields.integer(
|
||||
'Number of transactions', readonly=True),
|
||||
'total_amount': fields.float(
|
||||
'Total amount', digits_compute=dp.get_precision('Account'),
|
||||
readonly=True),
|
||||
'batch_booking': fields.boolean('Batch booking', readonly=True,
|
||||
'batch_booking': fields.boolean(
|
||||
'Batch booking', readonly=True,
|
||||
help="If true, the bank statement will display only one credit line for all the direct debits of the SEPA XML file ; if false, the bank statement will display one credit line per direct debit of the SEPA XML file."),
|
||||
'charge_bearer': fields.selection([
|
||||
('SHAR', 'Shared'),
|
||||
@@ -58,15 +61,15 @@ class banking_export_sdd(orm.Model):
|
||||
('SLEV', 'Following service level'),
|
||||
], 'Charge bearer', readonly=True,
|
||||
help='Shared : transaction charges on the sender side are to be borne by the debtor, transaction charges on the receiver side are to be borne by the creditor (most transfers use this). Borne by creditor : all transaction charges are to be borne by the creditor. Borne by debtor : all transaction charges are to be borne by the debtor. Following service level : transaction charges are to be applied following the rules agreed in the service level and/or scheme.'),
|
||||
'generation_date': fields.datetime('Generation date',
|
||||
readonly=True),
|
||||
'generation_date': fields.datetime('Generation date', readonly=True),
|
||||
'file': fields.binary('SEPA XML file', readonly=True),
|
||||
'filename': fields.function(_generate_filename, type='char', size=256,
|
||||
method=True, string='Filename', readonly=True),
|
||||
'filename': fields.function(
|
||||
_generate_filename, type='char', size=256,
|
||||
string='Filename', readonly=True, store=True),
|
||||
'state': fields.selection([
|
||||
('draft', 'Draft'),
|
||||
('sent', 'Sent'),
|
||||
('done', 'Reconciled'),
|
||||
('draft', 'Draft'),
|
||||
('sent', 'Sent'),
|
||||
('done', 'Reconciled'),
|
||||
], 'State', readonly=True),
|
||||
}
|
||||
|
||||
@@ -97,7 +100,8 @@ class sdd_mandate(orm.Model):
|
||||
], 'Type of Mandate', required=True),
|
||||
'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',
|
||||
'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."),
|
||||
'state': fields.selection([
|
||||
('valid', 'Valid'),
|
||||
@@ -113,10 +117,10 @@ class sdd_mandate(orm.Model):
|
||||
)]
|
||||
|
||||
_defaults = {
|
||||
'company_id': lambda self, cr, uid, context: \
|
||||
'company_id': lambda self, cr, uid, context:
|
||||
self.pool['res.users'].browse(cr, uid, uid, context=context).\
|
||||
company_id.id,
|
||||
'unique_mandate_reference': lambda self, cr, uid, context: \
|
||||
'unique_mandate_reference': lambda self, cr, uid, context:
|
||||
self.pool['ir.sequence'].get(cr, uid, 'sdd.mandate.reference'),
|
||||
'state': 'valid',
|
||||
}
|
||||
@@ -143,15 +147,13 @@ class payment_line(orm.Model):
|
||||
for payline in self.browse(cr, uid, ids):
|
||||
if payline.sdd_mandate_id and not payline.bank_id:
|
||||
raise orm.except_orm(
|
||||
_('Error :'),
|
||||
_("Missing bank account on the payment line with SEPA\
|
||||
Direct Debit Mandate '%s'."
|
||||
% payline.sdd_mandate_id.unique_mandate_reference))
|
||||
_('Error:'),
|
||||
_("Missing bank account on the payment line with SEPA Direct Debit Mandate '%s'.")
|
||||
% payline.sdd_mandate_id.unique_mandate_reference)
|
||||
elif payline.sdd_mandate_id and payline.bank_id and payline.sdd_mandate_id.partner_bank_id != payline.bank_id.id:
|
||||
raise orm.except_orm(
|
||||
_('Error :'),
|
||||
_('Error:'),
|
||||
_("The SEPA Direct Debit Mandate '%s' is not related??"))
|
||||
|
||||
return True
|
||||
|
||||
# _constraints = [
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
<form string="SEPA Direct Debit">
|
||||
<notebook>
|
||||
<page string="General Information">
|
||||
<field name="msg_identification" />
|
||||
<field name="total_amount" />
|
||||
<field name="nb_transactions" />
|
||||
<field name="requested_collec_date" />
|
||||
@@ -47,7 +46,7 @@
|
||||
<field name="model">banking.export.sdd</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="SEPA Direct Debit">
|
||||
<field name="msg_identification"/>
|
||||
<field name="filename"/>
|
||||
<field name="requested_collec_date"/>
|
||||
<field name="generation_date"/>
|
||||
<field name="nb_transactions"/>
|
||||
|
||||
@@ -34,9 +34,11 @@ class res_company(orm.Model):
|
||||
help="Enter the Creditor Identifier that has been attributed to your company to make SEPA Direct Debits. This identifier is composed of :\n- your country ISO code (2 letters)\n- a 2-digits checkum\n- a 3-letters business code\n- a country-specific identifier"),
|
||||
}
|
||||
|
||||
def is_sepa_creditor_identifier_valid(self, cr, uid, sepa_creditor_identifier, context=None):
|
||||
def is_sepa_creditor_identifier_valid(
|
||||
self, cr, uid, sepa_creditor_identifier, context=None):
|
||||
"""Check if SEPA Creditor Identifier is valid
|
||||
@param sepa_creditor_identifier: SEPA Creditor Identifier as str or unicode
|
||||
@param sepa_creditor_identifier: SEPA Creditor Identifier as str
|
||||
or unicode
|
||||
@return: True if valid, False otherwise
|
||||
"""
|
||||
if not isinstance(sepa_creditor_identifier, (str, unicode)):
|
||||
@@ -44,20 +46,23 @@ class res_company(orm.Model):
|
||||
try:
|
||||
sci_str = str(sepa_creditor_identifier)
|
||||
except:
|
||||
logger.warning("SEPA Creditor ID should contain only ASCII caracters.")
|
||||
logger.warning(
|
||||
"SEPA Creditor ID should contain only ASCII caracters.")
|
||||
return False
|
||||
sci = sci_str.lower()
|
||||
if len(sci) < 9:
|
||||
return False
|
||||
before_replacement = sci[7:] + sci[0:2] + '00'
|
||||
logger.debug("SEPA ID check before_replacement = %s" % before_replacement)
|
||||
logger.debug(
|
||||
"SEPA ID check before_replacement = %s" % before_replacement)
|
||||
after_replacement = ''
|
||||
for char in before_replacement:
|
||||
if char.isalpha():
|
||||
after_replacement += str(ord(char)-87)
|
||||
else:
|
||||
after_replacement += char
|
||||
logger.debug("SEPA ID check after_replacement = %s" % after_replacement)
|
||||
logger.debug(
|
||||
"SEPA ID check after_replacement = %s" % after_replacement)
|
||||
if int(sci[2:4]) == (98 - (int(after_replacement) % 97)):
|
||||
return True
|
||||
else:
|
||||
@@ -66,10 +71,13 @@ class res_company(orm.Model):
|
||||
def _check_sepa_creditor_identifier(self, cr, uid, ids):
|
||||
for company in self.browse(cr, uid, ids):
|
||||
if company.sepa_creditor_identifier:
|
||||
if not self.is_sepa_creditor_identifier_valid(cr, uid, company.sepa_creditor_identifier):
|
||||
if not self.is_sepa_creditor_identifier_valid(
|
||||
cr, uid, company.sepa_creditor_identifier):
|
||||
return False
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
(_check_sepa_creditor_identifier, "Invalid SEPA Creditor Identifier.", ['sepa_creditor_identifier']),
|
||||
(_check_sepa_creditor_identifier,
|
||||
"Invalid SEPA Creditor Identifier.",
|
||||
['sepa_creditor_identifier']),
|
||||
]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data noupdate="0"> <!-- TODO : put to 1 when dev of the module is finished -->
|
||||
<data noupdate="1">
|
||||
|
||||
|
||||
<record id="sdd_mandate_seq_type" model="ir.sequence.type">
|
||||
|
||||
@@ -0,0 +1,494 @@
|
||||
# Translation of OpenERP Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * account_banking_sepa_direct_debit
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 7.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-10-21 21:21+0000\n"
|
||||
"PO-Revision-Date: 2013-10-21 21:21+0000\n"
|
||||
"Last-Translator: <>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:banking.export.sdd,file:0
|
||||
msgid "SEPA XML file"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:banking.export.sdd,nb_transactions:0
|
||||
#: field:banking.export.sdd.wizard,nb_transactions:0
|
||||
msgid "Number of transactions"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:79
|
||||
#, python-format
|
||||
msgid "This IBAN is not valid : %s"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:132
|
||||
#, python-format
|
||||
msgid "Payment Type Code '%s' is not supported. The only Payment Type Code supported for SEPA Direct Debit are 'pain.008.001.02', 'pain.008.001.03' and 'pain.008.001.04'."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: selection:banking.export.sdd.wizard,state:0
|
||||
msgid "Create"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: selection:sdd.mandate,type:0
|
||||
msgid "Recurrent"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:sdd.mandate,type:0
|
||||
msgid "Type of Mandate"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:192
|
||||
#, python-format
|
||||
msgid "Missing signature date on SEPA Direct Debit mandate with reference '%s' for partner '%s'."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:banking.export.sdd,filename:0
|
||||
#: field:banking.export.sdd.wizard,filename:0
|
||||
msgid "Filename"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: model:ir.actions.act_window,name:account_banking_sepa_direct_debit.act_banking_export_sdd_payment_order
|
||||
msgid "Generated SEPA Direct Debit files"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:banking.export.sdd,state:0
|
||||
#: field:banking.export.sdd.wizard,state:0
|
||||
msgid "State"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: selection:sdd.mandate,state:0
|
||||
msgid "Valid"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: selection:banking.export.sdd,state:0
|
||||
msgid "Draft"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:185
|
||||
#, python-format
|
||||
msgid "The SEPA Direct Debit mandate with reference '%s' for partner '%s' has expired."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:100
|
||||
#, python-format
|
||||
msgid "Cannot compute the '%s' of the Payment Line with Invoice Reference '%s'."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: view:res.partner.bank:0
|
||||
#: field:res.partner.bank,sdd_mandate_ids:0
|
||||
msgid "SEPA Direct Debit Mandates"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:banking.export.sdd,total_amount:0
|
||||
#: field:banking.export.sdd.wizard,total_amount:0
|
||||
msgid "Total amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: view:banking.export.sdd:0
|
||||
msgid "SEPA Direct Debit"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: view:sdd.mandate:0
|
||||
msgid "Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:banking.export.sdd,generation_date:0
|
||||
msgid "Generation date"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: selection:banking.export.sdd,state:0
|
||||
msgid "Sent"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:sdd.mandate,scan:0
|
||||
msgid "Scan of the mandate"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: help:banking.export.sdd.wizard,requested_collec_date:0
|
||||
msgid "This is the date on which the collection should be made by the bank. Please keep in mind that banks only execute on working days."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: model:ir.actions.act_window,name:account_banking_sepa_direct_debit.action_account_banking_sdd
|
||||
#: model:ir.ui.menu,name:account_banking_sepa_direct_debit.menu_account_banking_sdd
|
||||
msgid "Generated SEPA Direct Debit XML files"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: selection:banking.export.sdd.wizard,state:0
|
||||
msgid "Finish"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: view:res.partner:0
|
||||
#: view:res.partner.bank:0
|
||||
msgid "SDD Mandates"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:198
|
||||
#, python-format
|
||||
msgid "The signature date on SEPA Direct Debit mandate with reference '%s' for partner '%s' is '%s', which is in the future !"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:res.company,sepa_creditor_identifier:0
|
||||
msgid "SEPA Creditor Identifier"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:sdd.mandate,company_id:0
|
||||
msgid "Company"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: selection:banking.export.sdd,charge_bearer:0
|
||||
#: selection:banking.export.sdd.wizard,charge_bearer:0
|
||||
msgid "Shared"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:sdd.mandate,unique_mandate_reference:0
|
||||
msgid "Unique Mandate Reference"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:102
|
||||
#, python-format
|
||||
msgid "Cannot compute the '%s'."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:104
|
||||
#, python-format
|
||||
msgid "The type of the field '%s' is %s. It should be a string or unicode."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: model:ir.model,name:account_banking_sepa_direct_debit.model_banking_export_sdd
|
||||
msgid "SEPA Direct Debit export"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: model:ir.model,name:account_banking_sepa_direct_debit.model_payment_line
|
||||
msgid "Payment Line"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: view:payment.order:0
|
||||
msgid "SDD Mandate"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: code:addons/account_banking_sepa_direct_debit/account_banking_sdd.py:156
|
||||
#, python-format
|
||||
msgid "The SEPA Direct Debit Mandate '%s' is not related??"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: selection:sdd.mandate,state:0
|
||||
msgid "Expired"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: view:banking.export.sdd.wizard:0
|
||||
msgid "Generate"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: model:ir.actions.act_window,name:account_banking_sepa_direct_debit.sdd_mandate_action
|
||||
#: model:ir.model,name:account_banking_sepa_direct_debit.model_sdd_mandate
|
||||
#: model:ir.ui.menu,name:account_banking_sepa_direct_debit.sdd_mandate_menu
|
||||
#: field:payment.line,sdd_mandate_id:0
|
||||
#: view:sdd.mandate:0
|
||||
msgid "SEPA Direct Debit Mandate"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: help:res.company,sepa_creditor_identifier:0
|
||||
msgid "Enter the Creditor Identifier that has been attributed to your company to make SEPA Direct Debits. This identifier is composed of :\n"
|
||||
"- your country ISO code (2 letters)\n"
|
||||
"- a 2-digits checkum\n"
|
||||
"- a 3-letters business code\n"
|
||||
"- a country-specific identifier"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: code:addons/account_banking_sepa_direct_debit/account_banking_sdd.py:151
|
||||
#, python-format
|
||||
msgid "Missing bank account on the payment line with SEPA Direct Debit Mandate '%s'."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: view:sdd.mandate:0
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:385
|
||||
#, python-format
|
||||
msgid "The generated XML file is not valid against the official XML Schema Definition. The generated XML file and the full error have been written in the server logs. Here is the error, which may give you an idea on the cause of the problem : %s"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: sql_constraint:sdd.mandate:0
|
||||
msgid "A Mandate with the same reference already exists for this company !"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:106
|
||||
#, python-format
|
||||
msgid "The '%s' is empty or 0. It should have a non-null value."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: code:addons/account_banking_sepa_direct_debit/account_banking_sdd.py:150
|
||||
#: code:addons/account_banking_sepa_direct_debit/account_banking_sdd.py:155
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:79
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:100
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:102
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:106
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:132
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:178
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:184
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:191
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:197
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:211
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:385
|
||||
#, python-format
|
||||
msgid "Error:"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:sdd.mandate,partner_bank_id:0
|
||||
msgid "Bank Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: model:ir.model,name:account_banking_sepa_direct_debit.model_res_company
|
||||
msgid "Companies"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: help:banking.export.sdd,charge_bearer:0
|
||||
#: help:banking.export.sdd.wizard,charge_bearer:0
|
||||
msgid "Shared : transaction charges on the sender side are to be borne by the debtor, transaction charges on the receiver side are to be borne by the creditor (most transfers use this). Borne by creditor : all transaction charges are to be borne by the creditor. Borne by debtor : all transaction charges are to be borne by the debtor. Following service level : transaction charges are to be applied following the rules agreed in the service level and/or scheme."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: selection:banking.export.sdd,charge_bearer:0
|
||||
#: selection:banking.export.sdd.wizard,charge_bearer:0
|
||||
msgid "Borne by creditor"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:banking.export.sdd,payment_order_ids:0
|
||||
#: field:banking.export.sdd.wizard,payment_order_ids:0
|
||||
msgid "Payment orders"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: view:sdd.mandate:0
|
||||
msgid "Signature Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: help:banking.export.sdd,batch_booking:0
|
||||
msgid "If true, the bank statement will display only one credit line for all the direct debits of the SEPA XML file ; if false, the bank statement will display one credit line per direct debit of the SEPA XML file."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: view:banking.export.sdd.wizard:0
|
||||
msgid "Processing details"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:banking.export.sdd.wizard,file_id:0
|
||||
msgid "SDD XML file"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: model:ir.model,name:account_banking_sepa_direct_debit.model_banking_export_sdd_wizard
|
||||
msgid "Export SEPA Direct Debit XML file"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:104
|
||||
#, python-format
|
||||
msgid "Field type error:"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: model:ir.actions.act_window,help:account_banking_sepa_direct_debit.sdd_mandate_action
|
||||
msgid "<p class=\"oe_view_nocontent_create\">\n"
|
||||
" Click to create a new SEPA Direct Debit Mandate.\n"
|
||||
" </p><p>\n"
|
||||
" The 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.\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: selection:sdd.mandate,type:0
|
||||
msgid "One-Off"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:179
|
||||
#, python-format
|
||||
msgid "Missing SEPA Direct Debit mandate on the payment line with partner '%s' and Invoice ref '%s'."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: view:banking.export.sdd.wizard:0
|
||||
msgid "Validate"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: code:addons/account_banking_sepa_direct_debit/wizard/export_sdd.py:212
|
||||
#, python-format
|
||||
msgid "The mandate with reference '%s' for partner '%s' has type set to 'One-Off' and it has a last debit date set to '%s', so we can't use it."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: help:sdd.mandate,last_debit_date:0
|
||||
msgid "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."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:sdd.mandate,signature_date:0
|
||||
msgid "Date of Signature of the Mandate"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:sdd.mandate,last_debit_date:0
|
||||
msgid "Date of the Last Debit"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: view:sdd.mandate:0
|
||||
msgid "Reference"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: constraint:res.company:0
|
||||
msgid "Invalid SEPA Creditor Identifier."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:banking.export.sdd,requested_collec_date:0
|
||||
#: field:banking.export.sdd.wizard,requested_collec_date:0
|
||||
msgid "Requested collection date"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: selection:banking.export.sdd,charge_bearer:0
|
||||
#: selection:banking.export.sdd.wizard,charge_bearer:0
|
||||
msgid "Borne by debtor"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: model:ir.model,name:account_banking_sepa_direct_debit.model_res_partner_bank
|
||||
msgid "Bank Accounts"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: selection:banking.export.sdd,charge_bearer:0
|
||||
#: selection:banking.export.sdd.wizard,charge_bearer:0
|
||||
msgid "Following service level"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: view:banking.export.sdd:0
|
||||
msgid "Payment Orders"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: view:banking.export.sdd.wizard:0
|
||||
msgid "SEPA Direct Debit XML file generation"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: view:banking.export.sdd:0
|
||||
msgid "General Information"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:banking.export.sdd,charge_bearer:0
|
||||
#: field:banking.export.sdd.wizard,charge_bearer:0
|
||||
msgid "Charge bearer"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:sdd.mandate,state:0
|
||||
msgid "Mandate Status"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: help:banking.export.sdd.wizard,batch_booking:0
|
||||
msgid "If true, the bank statement will display only one debit line for all the wire transfers of the SEPA XML file ; if false, the bank statement will display one debit line per wire transfer of the SEPA XML file."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:banking.export.sdd.wizard,file:0
|
||||
msgid "File"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: view:banking.export.sdd.wizard:0
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:sdd.mandate,partner_id:0
|
||||
msgid "Partner"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: help:sdd.mandate,state:0
|
||||
msgid "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."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: field:banking.export.sdd,batch_booking:0
|
||||
#: field:banking.export.sdd.wizard,batch_booking:0
|
||||
msgid "Batch booking"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: selection:banking.export.sdd,state:0
|
||||
msgid "Reconciled"
|
||||
msgstr ""
|
||||
|
||||
@@ -28,6 +28,7 @@ import base64
|
||||
from datetime import datetime, timedelta
|
||||
from lxml import etree
|
||||
import logging
|
||||
from unidecode import unidecode
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -38,10 +39,6 @@ class banking_export_sdd_wizard(orm.TransientModel):
|
||||
_columns = {
|
||||
'state': fields.selection([('create', 'Create'), ('finish', 'Finish')],
|
||||
'State', readonly=True),
|
||||
'msg_identification': fields.char('Message identification', size=35,
|
||||
# Can't set required=True on the field because it blocks
|
||||
# the launch of the wizard -> I set it as required in the view
|
||||
help='This is the message identification of the entire SEPA XML file. 35 characters max.'),
|
||||
'batch_booking': fields.boolean('Batch booking',
|
||||
help="If true, the bank statement will display only one debit line for all the wire transfers of the SEPA XML file ; if false, the bank statement will display one debit line per wire transfer of the SEPA XML file."),
|
||||
'requested_collec_date': fields.date('Requested collection date',
|
||||
@@ -72,22 +69,6 @@ class banking_export_sdd_wizard(orm.TransientModel):
|
||||
'state': 'create',
|
||||
}
|
||||
|
||||
|
||||
def _check_msg_identification(self, cr, uid, ids):
|
||||
'''Check that the msg_identification is unique'''
|
||||
for export_sdd in self.browse(cr, uid, ids):
|
||||
res = self.pool.get('banking.export.sdd').search(cr, uid,
|
||||
[('msg_identification', '=', export_sdd.msg_identification)])
|
||||
if len(res) > 1:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
_constraints = [
|
||||
(_check_msg_identification, "The field 'Message Identification' should be uniue. Another SEPA Direct Debit file already exists with the same 'Message Identification'.", ['msg_identification'])
|
||||
]
|
||||
|
||||
|
||||
def _validate_iban(self, cr, uid, iban, context=None):
|
||||
'''if IBAN is valid, returns IBAN
|
||||
if IBAN is NOT valid, raises an error message'''
|
||||
@@ -95,7 +76,7 @@ class banking_export_sdd_wizard(orm.TransientModel):
|
||||
if partner_bank_obj.is_iban_valid(cr, uid, iban, context=context):
|
||||
return iban.replace(' ', '')
|
||||
else:
|
||||
raise orm.except_orm(_('Error :'), _("This IBAN is not valid : %s") % iban)
|
||||
raise orm.except_orm(_('Error:'), _("This IBAN is not valid : %s") % iban)
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
payment_order_ids = context.get('active_ids', [])
|
||||
@@ -105,24 +86,27 @@ class banking_export_sdd_wizard(orm.TransientModel):
|
||||
return super(banking_export_sdd_wizard, self).create(cr, uid,
|
||||
vals, context=context)
|
||||
|
||||
|
||||
def _prepare_field(self, cr, uid, field_name, field_value, max_size=0, sepa_export=False, line=False, context=None):
|
||||
def _prepare_field(self, cr, uid, field_name, field_value, max_size=0, sepa_export=False, line=False, sequence_type=False, context=None):
|
||||
try:
|
||||
value = eval(field_value)
|
||||
# SEPA uses XML, and XML = UTF-8 with support for all characters...
|
||||
# But we are dealing with banks
|
||||
# and many banks don't want non-ASCCI characters !
|
||||
# cf section 1.4 "Character set" of the SEPA Core Direct Debit
|
||||
# Customer-to-bank implementation guidelines version 6.0
|
||||
value = unidecode(eval(field_value))
|
||||
except:
|
||||
if line:
|
||||
raise orm.except_orm(_('Error :'), _("Cannot compute the '%s' of the Payment Line with Invoice Reference '%s'.") % (field_name, self.pool['account.invoice'].name_get(cr, uid, [line.ml_inv_ref.id], context=context)[0][1]))
|
||||
raise orm.except_orm(_('Error:'), _("Cannot compute the '%s' of the Payment Line with Invoice Reference '%s'.") % (field_name, self.pool['account.invoice'].name_get(cr, uid, [line.ml_inv_ref.id], context=context)[0][1]))
|
||||
else:
|
||||
raise orm.except_orm(_('Error :'), _("Cannot compute the '%s'.") % field_name)
|
||||
raise orm.except_orm(_('Error:'), _("Cannot compute the '%s'.") % field_name)
|
||||
if not isinstance(value, (str, unicode)):
|
||||
raise orm.except_orm(_('Field type error :'), _("The type of the field '%s' is %s. It should be a string or unicode.") % (field_name, type(value)))
|
||||
raise orm.except_orm(_('Field type error:'), _("The type of the field '%s' is %s. It should be a string or unicode.") % (field_name, type(value)))
|
||||
if not value:
|
||||
raise orm.except_orm(_('Error :'), _("The '%s' is empty or 0. It should have a non-null value.") % field_name)
|
||||
raise orm.except_orm(_('Error:'), _("The '%s' is empty or 0. It should have a non-null value.") % field_name)
|
||||
if max_size and len(value) > max_size:
|
||||
value = value[0:max_size]
|
||||
return value
|
||||
|
||||
|
||||
def create_sepa(self, cr, uid, ids, context=None):
|
||||
'''
|
||||
Creates the SEPA Direct Debit file. That's the important code !
|
||||
@@ -143,7 +127,7 @@ class banking_export_sdd_wizard(orm.TransientModel):
|
||||
name_maxsize = 140
|
||||
root_xml_tag = 'CstmrDrctDbtInitn'
|
||||
else:
|
||||
raise orm.except_orm(_('Error :'), _("Payment Type Code '%s' is not supported. The only Payment Type Code supported for SEPA Direct Debit are 'pain.008.001.02', 'pain.008.001.03' and 'pain.008.001.04'.") % pain_flavor)
|
||||
raise orm.except_orm(_('Error:'), _("Payment Type Code '%s' is not supported. The only Payment Type Code supported for SEPA Direct Debit are 'pain.008.001.02', 'pain.008.001.03' and 'pain.008.001.04'.") % pain_flavor)
|
||||
if sepa_export.requested_collec_date:
|
||||
my_requested_collec_date = sepa_export.requested_collec_date
|
||||
else:
|
||||
@@ -158,13 +142,16 @@ class banking_export_sdd_wizard(orm.TransientModel):
|
||||
pain_root = etree.SubElement(root, root_xml_tag)
|
||||
|
||||
my_company_name = self._prepare_field(cr, uid, 'Company Name',
|
||||
'sepa_export.payment_order_ids[0].company_id.name',
|
||||
name_maxsize, sepa_export, context=context)
|
||||
'sepa_export.payment_order_ids[0].company_id.partner_id.name',
|
||||
name_maxsize, sepa_export=sepa_export, context=context)
|
||||
|
||||
# A. Group header
|
||||
group_header_1_0 = etree.SubElement(pain_root, 'GrpHdr')
|
||||
message_identification_1_1 = etree.SubElement(group_header_1_0, 'MsgId')
|
||||
message_identification_1_1.text = sepa_export.msg_identification
|
||||
message_identification_1_1.text = self._prepare_field(cr, uid,
|
||||
'Message Identification',
|
||||
'sepa_export.payment_order_ids[0].reference', 35,
|
||||
sepa_export=sepa_export, context=context)
|
||||
creation_date_time_1_2 = etree.SubElement(group_header_1_0, 'CreDtTm')
|
||||
creation_date_time_1_2.text = datetime.strftime(datetime.today(), '%Y-%m-%dT%H:%M:%S')
|
||||
nb_of_transactions_1_6 = etree.SubElement(group_header_1_0, 'NbOfTxs')
|
||||
@@ -219,7 +206,7 @@ class banking_export_sdd_wizard(orm.TransientModel):
|
||||
first_recur_lines['OOFF'] = [line]
|
||||
else:
|
||||
raise orm.except_orm(
|
||||
_('Error :'),
|
||||
_('Error:'),
|
||||
_("The mandate with reference '%s' for partner '%s' has type set to 'One-Off' and it has a last debit date set to '%s', so we can't use it.")
|
||||
% (line.sdd_mandate_id.unique_mandate_reference,
|
||||
line.sdd_mandate_id.partner_id.name,
|
||||
@@ -240,7 +227,11 @@ class banking_export_sdd_wizard(orm.TransientModel):
|
||||
# B. Payment info
|
||||
payment_info_2_0 = etree.SubElement(pain_root, 'PmtInf')
|
||||
payment_info_identification_2_1 = etree.SubElement(payment_info_2_0, 'PmtInfId')
|
||||
payment_info_identification_2_1.text = sepa_export.msg_identification
|
||||
payment_info_identification_2_1.text = self._prepare_field(
|
||||
cr, uid, 'Payment Information Identification',
|
||||
"sequence_type + '-' + sepa_export.payment_order_ids[0].reference",
|
||||
35, sepa_export=sepa_export, sequence_type=sequence_type,
|
||||
context=context)
|
||||
payment_method_2_2 = etree.SubElement(payment_info_2_0, 'PmtMtd')
|
||||
payment_method_2_2.text = 'DD'
|
||||
# batch_booking is in "Payment Info" with pain.008.001.02/03
|
||||
@@ -292,8 +283,8 @@ class banking_export_sdd_wizard(orm.TransientModel):
|
||||
|
||||
creditor_scheme_identification_2_27 = etree.SubElement(payment_info_2_0, 'CdtrSchmeId')
|
||||
csi_id = etree.SubElement(creditor_scheme_identification_2_27, 'Id')
|
||||
csi_orgid = csi_id = etree.SubElement(csi_id, 'OrgId')
|
||||
csi_other = etree.SubElement(csi_orgid, 'Othr')
|
||||
csi_privateid = csi_id = etree.SubElement(csi_id, 'PrvtId')
|
||||
csi_other = etree.SubElement(csi_privateid, 'Othr')
|
||||
csi_other_id = etree.SubElement(csi_other, 'Id')
|
||||
csi_other_id.text = self._prepare_field(cr, uid,
|
||||
'SEPA Creditor Identifier',
|
||||
@@ -313,9 +304,8 @@ class banking_export_sdd_wizard(orm.TransientModel):
|
||||
# Instruction identification (2.30) is not mandatory, so we don't use it
|
||||
end2end_identification_2_31 = etree.SubElement(payment_identification_2_29, 'EndToEndId')
|
||||
end2end_identification_2_31.text = self._prepare_field(cr, uid,
|
||||
'End to End Identification', 'line.communication', 35,
|
||||
'End to End Identification', 'line.name', 35,
|
||||
line=line, context=context)
|
||||
payment_type_2_32 = etree.SubElement(dd_transaction_info_2_28, 'PmtTpInf')
|
||||
currency_name = self._prepare_field(cr, uid, 'Currency Code',
|
||||
'line.currency.name', 3, line=line, context=context)
|
||||
instructed_amount_2_44 = etree.SubElement(dd_transaction_info_2_28, 'InstdAmt', Ccy=currency_name)
|
||||
@@ -389,12 +379,11 @@ class banking_export_sdd_wizard(orm.TransientModel):
|
||||
_logger.warning("The XML file is invalid against the XML Schema Definition")
|
||||
_logger.warning(xml_string)
|
||||
_logger.warning(e)
|
||||
raise orm.except_orm(_('Error :'), _('The generated XML file is not valid against the official XML Schema Definition. The generated XML file and the full error have been written in the server logs. Here is the error, which may give you an idea on the cause of the problem : %s') % str(e))
|
||||
raise orm.except_orm(_('Error:'), _('The generated XML file is not valid against the official XML Schema Definition. The generated XML file and the full error have been written in the server logs. Here is the error, which may give you an idea on the cause of the problem : %s') % str(e))
|
||||
|
||||
# CREATE the banking.export.sepa record
|
||||
file_id = self.pool.get('banking.export.sdd').create(cr, uid,
|
||||
{
|
||||
'msg_identification': sepa_export.msg_identification,
|
||||
'batch_booking': sepa_export.batch_booking,
|
||||
'charge_bearer': sepa_export.charge_bearer,
|
||||
'requested_collec_date': sepa_export.requested_collec_date,
|
||||
@@ -422,7 +411,6 @@ class banking_export_sdd_wizard(orm.TransientModel):
|
||||
}
|
||||
return action
|
||||
|
||||
|
||||
def cancel_sepa(self, cr, uid, ids, context=None):
|
||||
'''
|
||||
Cancel the SEPA Direct Debit file: just drop the file
|
||||
@@ -432,7 +420,6 @@ class banking_export_sdd_wizard(orm.TransientModel):
|
||||
cr, uid, sepa_export.file_id.id, context=context)
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
|
||||
def save_sepa(self, cr, uid, ids, context=None):
|
||||
'''
|
||||
Save the SEPA Direct Debit file: mark all payments in the file as 'sent'.
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
<field name="batch_booking" />
|
||||
<field name="requested_collec_date" />
|
||||
<field name="charge_bearer" />
|
||||
<separator colspan="4" string="Reference for further communication" />
|
||||
<field name="msg_identification" required="True" />
|
||||
</group>
|
||||
<group states="finish">
|
||||
<field name="total_amount" />
|
||||
|
||||
Reference in New Issue
Block a user