Add module for French LCR.

This commit is contained in:
Alexis de Lattre
2014-03-12 23:11:58 +01:00
parent 977dfff7a2
commit 034e5732b4
12 changed files with 1046 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# French LCR module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from . import account_banking_lcr
from . import wizard

View File

@@ -0,0 +1,53 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# French LCR module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': 'French LCR',
'summary': 'Create French LCR CFONB files',
'version': '0.1',
'license': 'AGPL-3',
'author': 'Akretion',
'website': 'http://www.akretion.com',
'category': 'Banking addons',
'depends': ['account_direct_debit'],
'external_dependencies': {
'python': ['unidecode'],
},
'data': [
'account_banking_lcr_view.xml',
'wizard/export_lcr_view.xml',
'data/payment_type_lcr.xml',
'security/ir.model.access.csv',
],
'demo': ['lcr_demo.xml'],
'description': '''
French LCR
==========
This modules adds support for French LCR (Lettre de Change Relevés). This payment type is still in use in France and it is *not* replaced by SEPA one-off Direct Debits. With this module, you can generate a CFNOB file to send to your bank.
This module uses the framework provided by the banking addons, cf https://launchpad.net/banking-addons
Please contact Alexis de Lattre from Akretion <alexis.delattre@akretion.com> for any help or question about this module.
''',
'active': False,
}

View File

@@ -0,0 +1,70 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# French LCR module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import orm, fields
from openerp.addons.decimal_precision import decimal_precision as dp
from unidecode import unidecode
class banking_export_lcr(orm.Model):
'''French LCR'''
_name = 'banking.export.lcr'
_description = __doc__
_rec_name = 'filename'
def _generate_filename(self, cr, uid, ids, name, arg, context=None):
res = {}
for lcr_file in self.browse(cr, uid, ids, context=context):
ref = lcr_file.payment_order_ids[0].reference
if ref:
label = unidecode(ref.replace('/', '-'))
else:
label = 'error'
res[lcr_file.id] = 'lcr_%s.txt' % label
return res
_columns = {
'payment_order_ids': fields.many2many(
'payment.order',
'account_payment_order_lcr_rel',
'banking_export_lcr_id', 'account_order_id',
'Payment Orders',
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),
'create_date': fields.datetime('Generation Date', readonly=True),
'file': fields.binary('CFONB File', readonly=True),
'filename': fields.function(
_generate_filename, type='char', size=256,
string='Filename', readonly=True, store=True),
'state': fields.selection([
('draft', 'Draft'),
('sent', 'Sent'),
], 'State', readonly=True),
}
_defaults = {
'state': 'draft',
}

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2014 Akretion (http://www.akretion.com)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __openerp__.py
-->
<openerp>
<data>
<record id="banking_export_lcr_form" model="ir.ui.view">
<field name="name">banking.export.lcr.form</field>
<field name="model">banking.export.lcr</field>
<field name="arch" type="xml">
<form string="LCR File" version="7.0">
<header>
<field name="state" widget="statusbar"/>
</header>
<notebook>
<page string="General Information">
<group name="main">
<field name="total_amount" />
<field name="nb_transactions" />
<field name="create_date" />
<field name="file" filename="filename"/>
<field name="filename" invisible="True"/>
</group>
</page>
<page string="Payment Orders">
<field name="payment_order_ids" nolabel="1"/>
</page>
</notebook>
</form>
</field>
</record>
<record id="banking_export_lcr_tree" model="ir.ui.view">
<field name="name">banking.export.lcr.tree</field>
<field name="model">banking.export.lcr</field>
<field name="arch" type="xml">
<tree string="LCR Files">
<field name="filename"/>
<field name="create_date"/>
<field name="nb_transactions"/>
<field name="state"/>
</tree>
</field>
</record>
<record id="banking_export_lcr_action" model="ir.actions.act_window">
<field name="name">LCR Files</field>
<field name="res_model">banking.export.lcr</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="banking_export_lcr_menu"
parent="account_payment.menu_main_payment"
action="banking_export_lcr_action"
sequence="50"
/>
<act_window id="act_banking_export_lcr_payment_order"
name="Generated LCR Files"
domain="[('payment_order_ids', '=', active_id)]"
res_model="banking.export.lcr"
src_model="payment.order"
view_type="form"
view_mode="tree,form"
/>
</data>
</openerp>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record id="payment_mode_type_lcr" model="payment.mode.type">
<field name="name">Lettre de Change Relevé</field>
<field name="code">LCR</field>
<field name="suitable_bank_types"
eval="[(6,0,[ref('base_iban.bank_iban')])]" />
<field name="ir_model_id" ref="model_banking_export_lcr_wizard"/>
<field name="payment_order_type">debit</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,187 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * account_banking_fr_lcr
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 7.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-03-12 21:33+0000\n"
"PO-Revision-Date: 2014-03-12 21:33+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_fr_lcr
#: selection:banking.export.lcr.wizard,state:0
msgid "Create"
msgstr ""
#. module: account_banking_fr_lcr
#: field:banking.export.lcr,nb_transactions:0
#: field:banking.export.lcr.wizard,nb_transactions:0
msgid "Number of Transactions"
msgstr ""
#. module: account_banking_fr_lcr
#: field:banking.export.lcr,filename:0
#: field:banking.export.lcr.wizard,filename:0
msgid "Filename"
msgstr ""
#. module: account_banking_fr_lcr
#: field:banking.export.lcr,state:0
#: field:banking.export.lcr.wizard,state:0
msgid "State"
msgstr ""
#. module: account_banking_fr_lcr
#: view:banking.export.lcr:0
msgid "LCR File"
msgstr ""
#. module: account_banking_fr_lcr
#: selection:banking.export.lcr,state:0
msgid "Draft"
msgstr ""
#. module: account_banking_fr_lcr
#: selection:banking.export.lcr,state:0
msgid "Sent"
msgstr ""
#. module: account_banking_fr_lcr
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:90
#, python-format
msgid "The field '%s' is empty or 0. It should have a non-null value."
msgstr ""
#. module: account_banking_fr_lcr
#: selection:banking.export.lcr.wizard,state:0
msgid "Finish"
msgstr ""
#. module: account_banking_fr_lcr
#: view:banking.export.lcr.wizard:0
msgid "LCR File Generation"
msgstr ""
#. module: account_banking_fr_lcr
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:294
#, python-format
msgid "The currency of payment line '%s' is '%s'. To be included in a French LCR, the currency must be EUR."
msgstr ""
#. module: account_banking_fr_lcr
#: model:ir.model,name:account_banking_fr_lcr.model_banking_export_lcr_wizard
msgid "Export French LCR File"
msgstr ""
#. module: account_banking_fr_lcr
#: model:ir.model,name:account_banking_fr_lcr.model_banking_export_lcr
msgid "French LCR"
msgstr ""
#. module: account_banking_fr_lcr
#: view:banking.export.lcr.wizard:0
msgid "Validate"
msgstr ""
#. module: account_banking_fr_lcr
#: view:banking.export.lcr.wizard:0
msgid "Generate"
msgstr ""
#. module: account_banking_fr_lcr
#: model:ir.actions.act_window,name:account_banking_fr_lcr.act_banking_export_lcr_payment_order
msgid "Generated LCR Files"
msgstr ""
#. module: account_banking_fr_lcr
#: field:banking.export.lcr.wizard,file_id:0
msgid "LCR CFONB File"
msgstr ""
#. module: account_banking_fr_lcr
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:123
#, python-format
msgid "For the bank account '%s' of partner '%s', the Bank Account Type is 'RIB and optional IBAN' and the IBAN field is empty, but, starting from 2014, we consider that the IBAN is required. Please write the IBAN on this bank account."
msgstr ""
#. module: account_banking_fr_lcr
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:143
#, python-format
msgid "LCR are only for French bank accounts. The IBAN '%s' of partner '%s' is not a French IBAN."
msgstr ""
#. module: account_banking_fr_lcr
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:89
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:103
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:122
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:133
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:142
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:293
#, python-format
msgid "Error:"
msgstr ""
#. module: account_banking_fr_lcr
#: field:banking.export.lcr,total_amount:0
#: field:banking.export.lcr.wizard,total_amount:0
msgid "Total Amount"
msgstr ""
#. module: account_banking_fr_lcr
#: view:banking.export.lcr:0
#: model:ir.actions.act_window,name:account_banking_fr_lcr.banking_export_lcr_action
#: model:ir.ui.menu,name:account_banking_fr_lcr.banking_export_lcr_menu
msgid "LCR Files"
msgstr ""
#. module: account_banking_fr_lcr
#: field:banking.export.lcr,file:0
msgid "CFONB File"
msgstr ""
#. module: account_banking_fr_lcr
#: view:banking.export.lcr:0
#: field:banking.export.lcr,payment_order_ids:0
#: field:banking.export.lcr.wizard,payment_order_ids:0
msgid "Payment Orders"
msgstr ""
#. module: account_banking_fr_lcr
#: view:banking.export.lcr:0
msgid "General Information"
msgstr ""
#. module: account_banking_fr_lcr
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:134
#, python-format
msgid "For the bank account '%s' of partner '%s', the Bank Account Type should be 'IBAN'."
msgstr ""
#. module: account_banking_fr_lcr
#: field:banking.export.lcr.wizard,file:0
msgid "File"
msgstr ""
#. module: account_banking_fr_lcr
#: view:banking.export.lcr.wizard:0
msgid "Cancel"
msgstr ""
#. module: account_banking_fr_lcr
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:104
#, python-format
msgid "Cannot convert the field '%s' to ASCII"
msgstr ""
#. module: account_banking_fr_lcr
#: field:banking.export.lcr,create_date:0
msgid "Generation Date"
msgstr ""

View File

@@ -0,0 +1,187 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * account_banking_fr_lcr
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 7.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-03-12 21:33+0000\n"
"PO-Revision-Date: 2014-03-12 21:33+0000\n"
"Last-Translator: Alexis de Lattre <alexis.delattre@akretion.com>\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_fr_lcr
#: selection:banking.export.lcr.wizard,state:0
msgid "Create"
msgstr "Créer"
#. module: account_banking_fr_lcr
#: field:banking.export.lcr,nb_transactions:0
#: field:banking.export.lcr.wizard,nb_transactions:0
msgid "Number of Transactions"
msgstr "Nombre de transactions"
#. module: account_banking_fr_lcr
#: field:banking.export.lcr,filename:0
#: field:banking.export.lcr.wizard,filename:0
msgid "Filename"
msgstr "Nom du fichier"
#. module: account_banking_fr_lcr
#: field:banking.export.lcr,state:0
#: field:banking.export.lcr.wizard,state:0
msgid "State"
msgstr "État"
#. module: account_banking_fr_lcr
#: view:banking.export.lcr:0
msgid "LCR File"
msgstr "Fichier LCR"
#. module: account_banking_fr_lcr
#: selection:banking.export.lcr,state:0
msgid "Draft"
msgstr "Brouillon"
#. module: account_banking_fr_lcr
#: selection:banking.export.lcr,state:0
msgid "Sent"
msgstr "Envoyé"
#. module: account_banking_fr_lcr
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:90
#, python-format
msgid "The field '%s' is empty or 0. It should have a non-null value."
msgstr "Le champ '%s' est vide ou égal à 0. Il devrait avoir une valeur non nulle."
#. module: account_banking_fr_lcr
#: selection:banking.export.lcr.wizard,state:0
msgid "Finish"
msgstr "Finir"
#. module: account_banking_fr_lcr
#: view:banking.export.lcr.wizard:0
msgid "LCR File Generation"
msgstr "Génération du fichier LCR"
#. module: account_banking_fr_lcr
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:294
#, python-format
msgid "The currency of payment line '%s' is '%s'. To be included in a French LCR, the currency must be EUR."
msgstr "La monnaie de la ligne de paiement '%s' est '%s'. Pour être intégrée dans une LCR, la monnaie doit être EUR."
#. module: account_banking_fr_lcr
#: model:ir.model,name:account_banking_fr_lcr.model_banking_export_lcr_wizard
msgid "Export French LCR File"
msgstr "Export du fichier LCR"
#. module: account_banking_fr_lcr
#: model:ir.model,name:account_banking_fr_lcr.model_banking_export_lcr
msgid "French LCR"
msgstr "LCR"
#. module: account_banking_fr_lcr
#: view:banking.export.lcr.wizard:0
msgid "Validate"
msgstr "Valider"
#. module: account_banking_fr_lcr
#: view:banking.export.lcr.wizard:0
msgid "Generate"
msgstr "Générer"
#. module: account_banking_fr_lcr
#: model:ir.actions.act_window,name:account_banking_fr_lcr.act_banking_export_lcr_payment_order
msgid "Generated LCR Files"
msgstr "Fichiers LCR générés"
#. module: account_banking_fr_lcr
#: field:banking.export.lcr.wizard,file_id:0
msgid "LCR CFONB File"
msgstr "Fichier CFONB LCR"
#. module: account_banking_fr_lcr
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:123
#, python-format
msgid "For the bank account '%s' of partner '%s', the Bank Account Type is 'RIB and optional IBAN' and the IBAN field is empty, but, starting from 2014, we consider that the IBAN is required. Please write the IBAN on this bank account."
msgstr "Pour le compte bancaire '%s' du partenaire '%s', le type de compte bancaire est 'RIB et IBAN optionel' et le champ IBAN est vide, or, à compter de 2014, nous considérons que l'IBAN est obligatoire. Vous devez renseigner l'IBAN de ce compte bancaire."
#. module: account_banking_fr_lcr
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:143
#, python-format
msgid "LCR are only for French bank accounts. The IBAN '%s' of partner '%s' is not a French IBAN."
msgstr "Les LCR ne fonctionnent qu'avec des comptes bancaires français. L'IBAN '%s' du partenaire '%s' n'est pas un IBAN français."
#. module: account_banking_fr_lcr
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:89
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:103
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:122
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:133
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:142
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:293
#, python-format
msgid "Error:"
msgstr "Erreur :"
#. module: account_banking_fr_lcr
#: field:banking.export.lcr,total_amount:0
#: field:banking.export.lcr.wizard,total_amount:0
msgid "Total Amount"
msgstr "Montant total"
#. module: account_banking_fr_lcr
#: view:banking.export.lcr:0
#: model:ir.actions.act_window,name:account_banking_fr_lcr.banking_export_lcr_action
#: model:ir.ui.menu,name:account_banking_fr_lcr.banking_export_lcr_menu
msgid "LCR Files"
msgstr "Fichiers LCR"
#. module: account_banking_fr_lcr
#: field:banking.export.lcr,file:0
msgid "CFONB File"
msgstr "Fichier CFONB"
#. module: account_banking_fr_lcr
#: view:banking.export.lcr:0
#: field:banking.export.lcr,payment_order_ids:0
#: field:banking.export.lcr.wizard,payment_order_ids:0
msgid "Payment Orders"
msgstr "Ordre de paiement"
#. module: account_banking_fr_lcr
#: view:banking.export.lcr:0
msgid "General Information"
msgstr "Informations générales"
#. module: account_banking_fr_lcr
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:134
#, python-format
msgid "For the bank account '%s' of partner '%s', the Bank Account Type should be 'IBAN'."
msgstr "Pour le compte bancaire '%s' du partenaire '%s', le type de compte bancaire devrait être 'IBAN'."
#. module: account_banking_fr_lcr
#: field:banking.export.lcr.wizard,file:0
msgid "File"
msgstr "Fichier"
#. module: account_banking_fr_lcr
#: view:banking.export.lcr.wizard:0
msgid "Cancel"
msgstr "Annuler"
#. module: account_banking_fr_lcr
#: code:addons/account_banking_fr_lcr/wizard/export_lcr.py:104
#, python-format
msgid "Cannot convert the field '%s' to ASCII"
msgstr "Impossible de convertir le champ '%s' en ASCII"
#. module: account_banking_fr_lcr
#: field:banking.export.lcr,create_date:0
msgid "Generation Date"
msgstr "Date de génération"

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record id="payment_mode_lcr" model="payment.mode">
<field name="name">LCR La Banque Postale</field>
<field name="journal" ref="account.bank_journal"/>
<field name="bank_id" ref="account_banking_payment_export.main_company_iban"/>
<field name="company_id" ref="base.main_company"/>
<field name="type" ref="payment_mode_type_lcr"/>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_banking_export_lcr,Full access on banking.export.lcr to Account Payment grp,model_banking_export_lcr,account_payment.group_account_payment,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_banking_export_lcr Full access on banking.export.lcr to Account Payment grp model_banking_export_lcr account_payment.group_account_payment 1 1 1 1

View File

@@ -0,0 +1,23 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# French LCR module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from . import export_lcr

View File

@@ -0,0 +1,357 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# French LCR module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import orm, fields
from openerp.tools.translate import _
from openerp import netsvc
from datetime import datetime
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT
from unidecode import unidecode
import base64
LCR_DATE_FORMAT = '%d%m%y'
class banking_export_lcr_wizard(orm.TransientModel):
_name = 'banking.export.lcr.wizard'
_description = 'Export French LCR File'
_columns = {
'state': fields.selection([
('create', 'Create'),
('finish', 'Finish'),
], 'State', readonly=True),
'nb_transactions': fields.related(
'file_id', 'nb_transactions', type='integer',
string='Number of Transactions', readonly=True),
'total_amount': fields.related(
'file_id', 'total_amount', type='float', string='Total Amount',
readonly=True),
'file_id': fields.many2one(
'banking.export.lcr', 'LCR CFONB File', readonly=True),
'file': fields.related(
'file_id', 'file', string="File", type='binary', readonly=True),
'filename': fields.related(
'file_id', 'filename', string="Filename", type='char', size=256,
readonly=True),
'payment_order_ids': fields.many2many(
'payment.order', 'wiz_lcr_payorders_rel', 'wizard_id',
'payment_order_id', 'Payment Orders', readonly=True),
}
_defaults = {
'state': 'create',
}
def create(self, cr, uid, vals, context=None):
payment_order_ids = context.get('active_ids', [])
vals.update({
'payment_order_ids': [[6, 0, payment_order_ids]],
})
return super(banking_export_lcr_wizard, self).create(
cr, uid, vals, context=context)
def _prepare_export_lcr(
self, cr, uid, lcr_export, total_amount, transactions_count,
cfonb_string, context=None):
return {
'total_amount': total_amount,
'nb_transactions': transactions_count,
'file': base64.encodestring(cfonb_string),
'payment_order_ids': [(
6, 0, [x.id for x in lcr_export.payment_order_ids]
)],
}
def _prepare_field(
self, cr, uid, field_name, field_value, size, context=None):
if not field_value:
raise orm.except_orm(
_('Error:'),
_("The field '%s' is empty or 0. It should have a non-null "
"value.")
% field_name)
try:
value = unidecode(field_value)
unallowed_ascii_chars = [
'"', '#', '$', '%', '&', ';', '<', '>', '=', '@',
'[', ']', '^', '_', '`', '{', '}', '|', '~', '\\', '!',
]
for unallowed_ascii_char in unallowed_ascii_chars:
value = value.replace(unallowed_ascii_char, '-')
except:
raise orm.except_orm(
_('Error:'),
_("Cannot convert the field '%s' to ASCII")
% field_name)
value = value.upper()
# Cut if too long
value = value[0:size]
# enlarge if too small
if len(value) < size:
value = '%s%s' % (value, ' ' * (size - len(value)))
assert len(value) == size, 'The lenght of the field is wrong'
return value
def _get_rib_from_iban(self, cr, uid, partner_bank, context=None):
# I do NOT want to add a dependancy on l10n_fr_rib, because
# we plan to remove the module in the near future
# So I consider that IBAN MUST be given in the res.partner.bank
# of type 'rib'
if partner_bank.state == 'rib' and not partner_bank.acc_number:
raise orm.except_orm(
_('Error:'),
_("For the bank account '%s' of partner '%s', the Bank "
"Account Type is 'RIB and optional IBAN' and the IBAN "
"field is empty, but, starting from 2014, we consider "
"that the IBAN is required. Please write the IBAN on "
"this bank account.")
% (self.pool['res.partner.bank'].name_get(
cr, uid, [partner_bank.id], context=context)[0][1],
partner_bank.partner_id.name))
elif partner_bank.state != 'iban':
raise orm.except_orm(
_('Error:'),
_("For the bank account '%s' of partner '%s', the Bank "
"Account Type should be 'IBAN'.")
% (self.pool['res.partner.bank'].name_get(
cr, uid, [partner_bank.id], context=context)[0][1],
partner_bank.partner_id.name))
iban = partner_bank.acc_number.replace(' ', '')
if iban[0:2] != 'FR':
raise orm.except_orm(
_('Error:'),
_("LCR are only for French bank accounts. The IBAN '%s' "
"of partner '%s' is not a French IBAN.")
% (partner_bank.acc_number, partner_bank.partner_id.name))
assert len(iban) == 27, 'French IBANs must have 27 caracters'
return {
'code_banque': iban[4:9],
'code_guichet': iban[9:14],
'numero_compte': iban[14:25],
'cle_rib': iban[25:27],
}
def _prepare_first_cfonb_line(
self, cr, uid, lcr_export, context=None):
code_enregistrement = '03'
code_operation = '60'
numero_enregistrement = '00000001'
numero_emetteur = '000000' # It is not needed for LCR
# this number is only required for old national direct debits
today_str = fields.date.context_today(self, cr, uid, context=context)
today_dt = datetime.strptime(today_str, DEFAULT_SERVER_DATE_FORMAT)
date_remise = today_dt.strftime(LCR_DATE_FORMAT)
raison_sociale_cedant = self._prepare_field(
cr, uid, u'Raison sociale du cédant',
lcr_export.payment_order_ids[0].company_id.name, 24,
context=context)
domiciliation_bancaire_cedant = self._prepare_field(
cr, uid, u'Domiciliation bancaire du cédant',
lcr_export.payment_order_ids[0].mode.bank_id.bank.name, 24,
context=context)
code_entree = '3'
code_dailly = ' '
code_monnaie = 'E'
rib = self._get_rib_from_iban(
cr, uid, lcr_export.payment_order_ids[0].mode.bank_id,
context=context)
ref_remise = self._prepare_field(
cr, uid, u'Référence de la remise',
lcr_export.payment_order_ids[0].reference, 11, context=context)
cfonb_line = '%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s' % (
code_enregistrement,
code_operation,
numero_enregistrement,
numero_emetteur,
' ' * 6,
date_remise,
raison_sociale_cedant,
domiciliation_bancaire_cedant,
code_entree,
code_dailly,
code_monnaie,
rib['code_banque'],
rib['code_guichet'],
rib['numero_compte'],
' ' * (16 + 6 + 10 + 15),
# Date de valeur is left empty because it is only for
# "remise à l'escompte" and we do
# "Encaissement, crédit forfaitaire après léchéance"
ref_remise,
)
assert len(cfonb_line) == 160, 'LCR CFONB line must have 160 chars'
cfonb_line += '\r\n'
return cfonb_line
def _prepare_cfonb_line(
self, cr, uid, line, requested_date, transactions_count,
context=None):
# I use French variable names because the specs are in French
code_enregistrement = '06'
code_operation = '60'
numero_enregistrement = '%08d' % (transactions_count + 1)
reference_tire = self._prepare_field(
cr, uid, u'Référence tiré', line.communication, 10,
context=context)
rib = self._get_rib_from_iban(cr, uid, line.bank_id, context=context)
nom_tire = self._prepare_field(
cr, uid, u'Nom tiré', line.partner_id.name, 24, context=context)
nom_banque = self._prepare_field(
cr, uid, u'Nom banque', line.bank_id.bank.name, 24,
context=context)
code_acceptation = '0'
montant_centimes = int(line.amount_currency * 100)
zero_montant_centimes = ('%012d' % montant_centimes)
today_str = fields.date.context_today(self, cr, uid, context=context)
today_dt = datetime.strptime(today_str, DEFAULT_SERVER_DATE_FORMAT)
date_creation = today_dt.strftime(LCR_DATE_FORMAT)
requested_date_dt = datetime.strptime(
requested_date, DEFAULT_SERVER_DATE_FORMAT)
date_echeance = requested_date_dt.strftime(LCR_DATE_FORMAT)
reference_tireur = reference_tire
cfonb_line = '%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s' % (
code_enregistrement,
code_operation,
numero_enregistrement,
' ' * (6 + 2),
reference_tire,
nom_tire,
nom_banque,
code_acceptation,
' ' * 2,
rib['code_banque'],
rib['code_guichet'],
rib['numero_compte'],
zero_montant_centimes,
' ' * 4,
date_echeance,
date_creation,
' ' * (4 + 1 + 3 + 3 + 9),
reference_tireur
)
assert len(cfonb_line) == 160, 'LCR CFONB line must have 160 chars'
cfonb_line += '\r\n'
return cfonb_line
def _prepare_final_cfonb_line(
self, cr, uid, total_amount, transactions_count, context=None):
code_enregistrement = '08'
code_operation = '60'
numero_enregistrement = '%08d' % (transactions_count + 2)
montant_total_centimes = int(total_amount * 100)
zero_montant_total_centimes = ('%012d' % montant_total_centimes)
cfonb_line = '%s%s%s%s%s%s' % (
code_enregistrement,
code_operation,
numero_enregistrement,
' ' * (6 + 12 + 24 + 24 + 1 + 2 + 5 + 5 + 11),
zero_montant_total_centimes,
' ' * (4 + 6 + 10 + 15 + 5 + 6)
)
assert len(cfonb_line) == 160, 'LCR CFONB line must have 160 chars'
return cfonb_line
def create_lcr(self, cr, uid, ids, context=None):
'''
Creates the LCR CFONB file.
'''
lcr_export = self.browse(cr, uid, ids[0], context=context)
today = fields.date.context_today(self, cr, uid, context=context)
cfonb_string = self._prepare_first_cfonb_line(
cr, uid, lcr_export, context=context)
transactions_count = 0
total_amount = 0.0
for payment_order in lcr_export.payment_order_ids:
total_amount = total_amount + payment_order.total
# Iterate each payment lines
for line in payment_order.line_ids:
if line.currency.name != 'EUR':
raise orm.except_orm(
_('Error:'),
_("The currency of payment line '%s' is '%s'. "
"To be included in a French LCR, the currency "
"must be EUR.")
% (line.name, line.currency.name))
transactions_count += 1
if payment_order.date_prefered == 'due':
requested_date = line.ml_maturity_date or today
elif payment_order.date_prefered == 'fixed':
requested_date = payment_order.date_scheduled or today
else:
requested_date = today
cfonb_string += self._prepare_cfonb_line(
cr, uid, line, requested_date, transactions_count,
context=context)
cfonb_string += self._prepare_final_cfonb_line(
cr, uid, total_amount, transactions_count,
context=context)
file_id = self.pool['banking.export.lcr'].create(
cr, uid, self._prepare_export_lcr(
cr, uid, lcr_export, total_amount, transactions_count,
cfonb_string, context=context),
context=context)
self.write(
cr, uid, ids, {
'file_id': file_id,
'state': 'finish',
}, context=context)
action = {
'name': 'LCR File',
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'form,tree',
'res_model': self._name,
'res_id': ids[0],
'target': 'new',
}
return action
def cancel_lcr(self, cr, uid, ids, context=None):
'''
Cancel the CFONB file: just drop the file
'''
lcr_export = self.browse(cr, uid, ids[0], context=context)
self.pool['banking.export.lcr'].unlink(
cr, uid, lcr_export.file_id.id, context=context)
return {'type': 'ir.actions.act_window_close'}
def save_lcr(self, cr, uid, ids, context=None):
'''
Mark the LCR file as 'sent' and the payment order as 'done'.
'''
lcr_export = self.browse(cr, uid, ids[0], context=context)
self.pool['banking.export.lcr'].write(
cr, uid, lcr_export.file_id.id, {'state': 'sent'},
context=context)
wf_service = netsvc.LocalService('workflow')
for order in lcr_export.payment_order_ids:
wf_service.trg_validate(uid, 'payment.order', order.id, 'done', cr)
return {'type': 'ir.actions.act_window_close'}

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2014 Akretion (http://www.akretion.com)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __openerp__.py
-->
<openerp>
<data>
<record id="banking_export_lcr_wizard_form" model="ir.ui.view">
<field name="name">banking.export.lcr.wizard.form</field>
<field name="model">banking.export.lcr.wizard</field>
<field name="arch" type="xml">
<form string="LCR File Generation" version="7.0">
<field name="state" invisible="1"/>
<group states="finish">
<field name="total_amount" />
<field name="nb_transactions" />
<field name="file" filename="filename" />
<field name="filename" invisible="True"/>
</group>
<footer>
<button string="Generate" name="create_lcr" type="object"
class="oe_highlight" states="create"/>
<button string="Cancel" special="cancel"
class="oe_link" states="create"/>
<button string="Validate" name="save_lcr" type="object"
class="oe_highlight" states="finish"/>
<button string="Cancel" name="cancel_lcr" type="object"
class="oe_link" states="finish"/>
</footer>
</form>
</field>
</record>
</data>
</openerp>