[MIG] account_banking_sepa_direct_debit: Migration to 10.0

This commit is contained in:
Alexis de Lattre
2016-10-20 01:41:41 +02:00
committed by Carlos Roca
parent 1f75089fc5
commit afd3aa0f94
23 changed files with 111 additions and 273 deletions

View File

@@ -47,7 +47,7 @@ you created during the configuration step.
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/173/9.0
:target: https://runbot.odoo-community.org/runbot/173/10.0
Known issues / Roadmap
======================

View File

@@ -1,17 +1,16 @@
# -*- coding: utf-8 -*-
# © 2013-2016 Akretion (www.akretion.com)
# © 2014 Serv. Tecnol. Avanzados - Pedro M. Baeza
# © 2016 Antiun Ingenieria S.L. - Antonio Espinosa
# © 2014 Tecnativa - Pedro M. Baeza
# © 2016 Tecnativa - Antonio Espinosa
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
'name': 'Account Banking SEPA Direct Debit',
'summary': 'Create SEPA files for Direct Debit',
'version': '9.0.1.0.0',
'version': '10.0.1.0.0',
'license': 'AGPL-3',
'author': "Akretion, "
"Serv. Tecnol. Avanzados - Pedro M. Baeza, "
"Antiun Ingeniería S.L., "
"Tecnativa, "
"Odoo Community Association (OCA)",
'website': 'https://github.com/OCA/bank-payment',
'category': 'Banking addons',
@@ -21,7 +20,6 @@
],
'data': [
'views/account_banking_mandate_view.xml',
'views/res_company_view.xml',
'views/res_config.xml',
'views/account_payment_mode.xml',
'data/mandate_expire_cron.xml',

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<odoo>
<data noupdate="1">
@@ -14,4 +14,4 @@
</data>
</openerp>
</odoo>

View File

@@ -1,12 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2013-2016 Akretion (http://www.akretion.com/)
@author Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __openerp__.py
© 2013-2016 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<openerp>
<odoo>
<data noupdate="1">
<record id="sdd_mandate_expire_cron" model="ir.cron">
<field name="name">Set SEPA Direct Debit Mandates to Expired</field>
@@ -18,7 +17,7 @@
<field name="doall" eval="False"/>
<field name="model" eval="'account.banking.mandate'"/>
<field name="function" eval="'_sdd_mandate_set_state_to_expired'" />
<field name="args" eval="'(None, )'"/>
<field name="args" eval="'()'"/>
</record>
</data>
</openerp>
</odoo>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<odoo>
<record id="paperformat_euro_sepa_lowmargin" model="report.paperformat">
<field name="name">European A4 low margin for SEPA</field>
@@ -18,5 +17,4 @@
<field name="dpi">80</field>
</record>
</data>
</openerp>
</odoo>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<odoo>
<data noupdate="1">
<record id="payment_mode_inbound_sepa_dd1" model="account.payment.mode">
@@ -21,7 +21,7 @@
<field name="format">sepa</field>
<field name="type">recurrent</field>
<field name="recurrent_sequence_type">first</field>
<field name="signature_date">2014-02-01</field>
<field name="signature_date" eval="time.strftime('%Y-01-01')"/>
<field name="state">valid</field>
</record>
@@ -46,4 +46,4 @@
</data>
</openerp>
</odoo>

View File

@@ -1,50 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2015 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 import pooler, SUPERUSER_ID
def migrate(cr, version):
if not version:
return
pool = pooler.get_pool(cr.dbname)
cr.execute('''
SELECT
old_sepa.file,
rel.account_order_id AS payment_order_id,
payment_order.reference
FROM migration_banking_export_sdd old_sepa
LEFT JOIN migration_account_payment_order_sdd_rel rel
ON old_sepa.id=rel.banking_export_sepa_id
LEFT JOIN payment_order ON payment_order.id=rel.account_order_id
''')
for sepa_file in cr.dictfetchall():
filename = 'sdd_%s.xml' % sepa_file['reference'].replace('/', '-')
pool['ir.attachment'].create(
cr, SUPERUSER_ID, {
'name': filename,
'res_id': sepa_file['payment_order_id'],
'res_model': 'payment.order',
'datas': str(sepa_file['file']),
})
return

View File

@@ -1,32 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2015 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/>.
#
##############################################################################
def migrate(cr, version):
if not version:
return
cr.execute(
'ALTER TABLE banking_export_sdd '
'RENAME TO migration_banking_export_sdd')
cr.execute(
'ALTER TABLE account_payment_order_sdd_rel '
'RENAME TO migration_account_payment_order_sdd_rel')

View File

@@ -1,13 +0,0 @@
# -*- coding: utf-8 -*-
# © 2016 Sergio Teruel <sergio.teruel@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
def migrate(cr, version):
if not version:
return
cr.execute('''
UPDATE account_banking_mandate SET format='sepa'
''')
return

View File

@@ -3,7 +3,7 @@
# © 2014 Serv. Tecnol. Avanzados - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import models, fields, api, exceptions, _
from odoo import models, fields, api, exceptions, _
from datetime import datetime
from dateutil.relativedelta import relativedelta
import logging

View File

@@ -2,7 +2,7 @@
# © 2016 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import models, fields, api
from odoo import models, fields, api
class AccountPaymentMethod(models.Model):

View File

@@ -2,9 +2,9 @@
# © 2016 Antiun Ingenieria S.L. - Antonio Espinosa
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import models, fields, api, _
from odoo import models, fields, api, _
from .common import is_sepa_creditor_identifier_valid
from openerp.exceptions import ValidationError
from odoo.exceptions import ValidationError
class AccountPaymentMode(models.Model):

View File

@@ -2,35 +2,14 @@
# © 2016 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp import models, fields, api, _
from openerp.exceptions import UserError
from odoo import models, fields, api, _
from odoo.exceptions import UserError
from lxml import etree
class AccountPaymentOrder(models.Model):
_inherit = 'account.payment.order'
def _get_previous_bank(self, payline):
previous_bank = False
older_lines = self.env['account.payment.line'].search([
('mandate_id', '=', payline.mandate_id.id),
('partner_bank_id', '!=', payline.partner_bank_id.id)])
if older_lines:
previous_date = False
previous_payline = False
for older_line in older_lines:
if hasattr(older_line.order_id, 'date_sent'):
older_line_date = older_line.order_id.date_sent
else:
older_line_date = older_line.order_id.date_done
if (older_line_date and
older_line_date > previous_date):
previous_date = older_line_date
previous_payline = older_line
if previous_payline:
previous_bank = previous_payline.partner_bank_id
return previous_bank
@api.multi
def generate_payment_file(self):
"""Creates the SEPA Direct Debit file. That's the important code !"""
@@ -89,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
@@ -127,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)
@@ -210,46 +192,24 @@ class AccountPaymentOrder(models.Model):
'line.mandate_id.signature_date',
{'line': line}, 10, gen_args=gen_args)
if sequence_type == 'FRST' and line.mandate_id.last_debit_date:
previous_bank = self._get_previous_bank(line)
if previous_bank:
amendment_indicator = etree.SubElement(
mandate_related_info, 'AmdmntInd')
amendment_indicator.text = 'true'
amendment_info_details = etree.SubElement(
mandate_related_info, 'AmdmntInfDtls')
if (
previous_bank.bank_bic ==
line.partner_bank_id.bank_bic):
ori_debtor_account = etree.SubElement(
amendment_info_details, 'OrgnlDbtrAcct')
ori_debtor_account_id = etree.SubElement(
ori_debtor_account, 'Id')
ori_debtor_account_iban = etree.SubElement(
ori_debtor_account_id, 'IBAN')
ori_debtor_account_iban.text = self._validate_iban(
self._prepare_field(
'Original Debtor Account',
'previous_bank.sanitized_acc_number',
{'previous_bank': previous_bank},
gen_args=gen_args))
else:
ori_debtor_agent = etree.SubElement(
amendment_info_details, 'OrgnlDbtrAgt')
ori_debtor_agent_institution = etree.SubElement(
ori_debtor_agent, 'FinInstnId')
ori_debtor_agent_bic = etree.SubElement(
ori_debtor_agent_institution, bic_xml_tag)
ori_debtor_agent_bic.text = self._prepare_field(
'Original Debtor Agent',
'previous_bank.bank_bic',
{'previous_bank': previous_bank},
gen_args=gen_args)
ori_debtor_agent_other = etree.SubElement(
ori_debtor_agent_institution, 'Othr')
ori_debtor_agent_other_id = etree.SubElement(
ori_debtor_agent_other, 'Id')
ori_debtor_agent_other_id.text = 'SMNDA'
# SMNDA = Same Mandate New Debtor Agent
amendment_indicator = etree.SubElement(
mandate_related_info, 'AmdmntInd')
amendment_indicator.text = 'true'
amendment_info_details = etree.SubElement(
mandate_related_info, 'AmdmntInfDtls')
ori_debtor_account = etree.SubElement(
amendment_info_details, 'OrgnlDbtrAcct')
ori_debtor_account_id = etree.SubElement(
ori_debtor_account, 'Id')
ori_debtor_agent_other = etree.SubElement(
ori_debtor_account_id, 'Othr')
ori_debtor_agent_other_id = etree.SubElement(
ori_debtor_agent_other, 'Id')
ori_debtor_agent_other_id.text = 'SMNDA'
# Until 20/11/2016, SMNDA meant
# "Same Mandate New Debtor Agent"
# After 20/11/2016, SMNDA means
# "Same Mandate New Debtor Account"
self.generate_party_block(
dd_transaction_info, 'Dbtr', 'C',

View File

@@ -2,7 +2,7 @@
# © 2015-2016 Akretion - Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import models, api
from odoo import models, api
class BankPaymentLine(models.Model):

View File

@@ -4,9 +4,9 @@
# © 2016 Antiun Ingenieria S.L. - Antonio Espinosa
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import models, fields, api, _
from odoo import models, fields, api, _
from .common import is_sepa_creditor_identifier_valid
from openerp.exceptions import ValidationError
from odoo.exceptions import ValidationError
class ResCompany(models.Model):
@@ -19,8 +19,6 @@ class ResCompany(models.Model):
"of :\n- your country ISO code (2 letters)\n- a 2-digits "
"checkum\n- a 3-letters business code\n- a country-specific "
"identifier")
original_creditor_identifier = fields.Char(
string='Original Creditor Identifier', size=70)
@api.multi
@api.constrains('sepa_creditor_identifier')

View File

@@ -2,7 +2,7 @@
# © 2016 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import models, fields
from odoo import models, fields
class AccountConfigSettings(models.TransientModel):

View File

@@ -2,17 +2,18 @@
# © 2016 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp import SUPERUSER_ID
from odoo import api, SUPERUSER_ID
def update_bank_journals(cr, pool):
ajo = pool['account.journal']
journal_ids = ajo.search(cr, SUPERUSER_ID, [('type', '=', 'bank')])
sdd_id = pool['ir.model.data'].xmlid_to_res_id(
cr, SUPERUSER_ID,
'account_banking_sepa_direct_debit.sepa_direct_debit')
if sdd_id:
ajo.write(cr, SUPERUSER_ID, journal_ids, {
'inbound_payment_method_ids': [(4, sdd_id)],
})
def update_bank_journals(cr, registry):
with api.Environment.manage():
env = api.Environment(cr, SUPERUSER_ID, {})
ajo = env['account.journal']
journals = ajo.search([('type', '=', 'bank')])
sdd = env.ref(
'account_banking_sepa_direct_debit.sepa_direct_debit')
if sdd:
journals.write({
'inbound_payment_method_ids': [(4, sdd.id)],
})
return

View File

@@ -1,21 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<odoo>
<!-- QWeb Report -->
<report
id="report_sepa_direct_debit_mandate"
model="account.banking.mandate"
string="Sepa Mandate"
report_type="qweb-pdf"
name="account_banking_sepa_direct_debit.sepa_direct_debit_mandate"
file="account_banking_sepa_direct_debit.sepa_direct_debit_mandate"
<!-- QWeb Report -->
<report
id="report_sepa_direct_debit_mandate"
model="account.banking.mandate"
string="Sepa Mandate"
report_type="qweb-pdf"
name="account_banking_sepa_direct_debit.sepa_direct_debit_mandate"
file="account_banking_sepa_direct_debit.sepa_direct_debit_mandate"
/>
<record id="report_sepa_direct_debit_mandate" model="ir.actions.report.xml">
<field name="paperformat_id"
ref="account_banking_sepa_direct_debit.paperformat_euro_sepa_lowmargin"/>
</record>
<record id="report_sepa_direct_debit_mandate" model="ir.actions.report.xml">
<field name="paperformat_id"
ref="account_banking_sepa_direct_debit.paperformat_euro_sepa_lowmargin"/>
</record>
</data>
</openerp>
</odoo>

View File

@@ -2,16 +2,17 @@
# © 2016 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp.addons.account.tests.account_test_classes\
from odoo.addons.account.tests.account_test_classes\
import AccountingTestCase
from openerp.tools import float_compare
from odoo.tools import float_compare
import time
from lxml import etree
class TestSDD(AccountingTestCase):
def test_sdd(self):
def setUp(self):
super(TestSDD, self).setUp()
self.company = self.env['res.company']
self.account_model = self.env['account.account']
self.move_model = self.env['account.move']
@@ -53,8 +54,13 @@ class TestSDD(AccountingTestCase):
'bank_account_link': 'fixed',
'fixed_journal_id': self.bank_journal.id,
})
eur_currency_id = self.env.ref('base.EUR').id
company.currency_id = eur_currency_id
self.eur_currency_id = self.env.ref('base.EUR').id
company.currency_id = self.eur_currency_id
# Trigger the recompute of account type on res.partner.bank
for bank_acc in self.partner_bank_model.search([]):
bank_acc.acc_number = bank_acc.acc_number
def test_sdd(self):
self.env.ref(
'account_banking_sepa_direct_debit.res_partner_2_mandate').\
recurrent_sequence_type = 'first'
@@ -81,7 +87,8 @@ class TestSDD(AccountingTestCase):
self.assertEquals(len(pay_lines), 1)
agrolait_pay_line1 = pay_lines[0]
accpre = self.env['decimal.precision'].precision_get('Account')
self.assertEquals(agrolait_pay_line1.currency_id.id, eur_currency_id)
self.assertEquals(
agrolait_pay_line1.currency_id.id, self.eur_currency_id)
self.assertEquals(
agrolait_pay_line1.mandate_id, invoice1.mandate_id)
self.assertEquals(
@@ -100,7 +107,8 @@ class TestSDD(AccountingTestCase):
('partner_id', '=', self.partner_agrolait.id)])
self.assertEquals(len(bank_lines), 1)
agrolait_bank_line = bank_lines[0]
self.assertEquals(agrolait_bank_line.currency_id.id, eur_currency_id)
self.assertEquals(
agrolait_bank_line.currency_id.id, self.eur_currency_id)
self.assertEquals(float_compare(
agrolait_bank_line.amount_currency, 42.0, precision_digits=accpre),
0)
@@ -163,5 +171,5 @@ class TestSDD(AccountingTestCase):
'name': 'Great service',
'account_id': self.account_revenue.id,
})
invoice.signal_workflow('invoice_open')
invoice.action_invoice_open()
return invoice

View File

@@ -1,14 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2013-2016 Akretion (http://www.akretion.com)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __openerp__.py
© 2013-2016 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<!--
Customize all mandate views (and actions) to fit SEPA mandate style
-->
<openerp>
<data>
<odoo>
<record id="view_mandate_form" model="ir.ui.view">
@@ -62,5 +60,5 @@
</field>
</record>
</data>
</openerp>
</odoo>

View File

@@ -2,8 +2,8 @@
<!-- © 2015 Antiun Ingenieria S.L. - Antonio Espinosa
© 2016 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
<openerp>
<data>
<odoo>
<record id="account_payment_mode_form" model="ir.ui.view">
<field name="name">Add SEPA identifiers on payment mode form</field>
@@ -19,5 +19,5 @@
</field>
</record>
</data>
</openerp>
</odoo>

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2013-2016 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="view_company_form" model="ir.ui.view">
<field name="name">sepa_direct_debit.res.company.form</field>
<field name="model">res.company</field>
<field name="inherit_id" ref="account_banking_pain_base.view_company_form"/>
<field name="arch" type="xml">
<group name="pain" position="inside">
<field name="sepa_creditor_identifier"/>
</group>
</field>
</record>
</data>
</openerp>

View File

@@ -1,21 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="view_account_config_settings" model="ir.ui.view">
<field name="name">sepa_direct_debit.account_config_settings.form</field>
<field name="model">account.config.settings</field>
<field name="inherit_id" ref="account.view_account_config_settings"/>
<field name="inherit_id" ref="account_banking_pain_base.view_account_config_settings"/>
<field name="arch" type="xml">
<div name="payment_acquirer" position="before">
<div name="sepa_direct_debit">
<label for="sepa_creditor_identifier"/>
<field name="sepa_creditor_identifier" class="oe_inline"
placeholder="Write the ICS of your company"/>
</div>
</div>
<group name="pain" position="inside">
<field name="sepa_creditor_identifier"
placeholder="Write the ICS of your company"/>
</group>
</field>
</record>
</data>
</odoo>