[MIG] account_payment_partner: Start to port bank-payment to v9 (with a lot of improvements) during the Sorrento Code sprint 2016

Improvements include:
- full re-organisation of modules and big re-organisation of the code
- simplification of the code related to the fact that support for direct debit is now in t
he base module, not added by an optional module account_direct_debit (module was removed)
- new design of the wizard to select move lines to pay
- support for non-SEPA file transfer-
- support for German direct debit SEPA files (fixes bug #129)
- remove workflow of payment.order
* Finalise the wizard of selection of move lines to pay
* Add button "Add to payment/debit order" on invoice form view
* Started to integrate payment transfer in account_payment_order (not finished at all though)
* Copy payment mode and mandate from invoice to refund
* Run dos2unix on the few files that had DOS carriage return
* Add _id suffix on M2O fields customer_payment_mode and supplier_payment_mode (Odoo did the same on all the M2O property fields of res.partner)
* Better handling of partner_bank_id and mandate_id on invoice: invisible/required/onchange
* Move field bank_account_required from module account_payment_partner to account_payment_mode
This commit is contained in:
Alexis de Lattre
2016-04-30 01:46:34 +02:00
committed by Thomas Binsfeld
parent 77ff49f9de
commit 294cd5ffe9
18 changed files with 192 additions and 251 deletions

View File

@@ -1,6 +1,7 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:alt: License: AGPL-3
=======================
Account Payment Partner
=======================
@@ -17,7 +18,8 @@ Installation
============
This module depends on :
* account_banking_payment_export
* account_payment_mode
This module is part of the OCA/bank-payment suite.
@@ -34,22 +36,22 @@ This payment mode is automatically associated to the invoice related to the part
When you create an payment order, only invoices related to chosen payment mode are displayed.
Invoices without any payment mode are displayed to.
For further information, please visit:
* https://www.odoo.com/forum/help-1
.. 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
Known issues / Roadmap
======================
* No known issues.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/bank-payment/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback
`here <https://github.com/OCA/bank-payment/issues/new?body=module:%20account_payment_partner%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/bank-payment/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smashing it by providing a detailed and welcomed feedback.
Credits
=======
@@ -58,7 +60,7 @@ Contributors
------------
* Pedro M. Baeza
* Alexis de Lattre
* Alexis de Lattre <alexis.delattre@akretion.com>
* Raphaël Valyi
* Stefan Rijnhart (Therp)
* Alexandre Fayolle

View File

@@ -3,4 +3,3 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import models
from . import wizard

View File

@@ -5,7 +5,7 @@
{
'name': 'Account Payment Partner',
'version': '8.0.0.2.0',
'version': '9.0.1.0.0',
'category': 'Banking addons',
'license': 'AGPL-3',
'summary': 'Adds payment mode on partners and invoices',
@@ -13,14 +13,12 @@
"Serv. Tecnol. Avanzados - Pedro M. Baeza, "
"Odoo Community Association (OCA)",
'website': 'https://github.com/OCA/bank-payment',
'depends': ['account_banking_payment_export'],
'depends': ['account_payment_mode'],
'data': [
'views/res_partner_view.xml',
'views/account_invoice_view.xml',
'views/account_move_line.xml',
'views/report_invoice.xml',
'views/payment_mode.xml',
'security/ir.model.access.csv',
'wizard/payment_order_create_view.xml',
],
'demo': ['demo/partner_demo.xml'],
'installable': True,

View File

@@ -3,49 +3,23 @@
<openerp>
<data noupdate="1">
<!-- Camptocamp -->
<record id="supplier_payment_mode_12" model="ir.property" forcecreate="True">
<field name="name">supplier_payment_mode_12</field>
<record id="default_supplier_payment_mode_id" model="ir.property" forcecreate="True">
<field name="name">Default Supplier Payment Mode</field>
<field name="fields_id"
search="[('model','=','res.partner'),('name','=','supplier_payment_mode')]"/>
search="[('model','=','res.partner'),('name','=','supplier_payment_mode_id')]"/>
<field name="value"
eval="'payment.mode,'+str(ref('account_banking_payment_export.payment_mode_2'))"/>
eval="'account.payment.mode,'+str(ref('account_payment_mode.payment_mode_outbound_ct1'))"/>
<field name="company_id" ref="base.main_company"/>
<field name="res_id" ref="base.res_partner_12"/>
</record>
<record id="customer_payment_mode_12" model="ir.property" forcecreate="True">
<field name="name">customer_payment_mode_12</field>
<record id="default_customer_payment_mode_id" model="ir.property" forcecreate="True">
<field name="name">Default Customer Payment Mode</field>
<field name="fields_id"
search="[('model','=','res.partner'),('name','=','customer_payment_mode')]"/>
search="[('model','=','res.partner'),('name','=','customer_payment_mode_id')]"/>
<field name="value"
eval="'payment.mode,'+str(ref('account_banking_payment_export.payment_mode_2'))"/>
eval="'account.payment.mode,'+str(ref('account_payment_mode.payment_mode_inbound_ct1'))"/>
<field name="company_id" ref="base.main_company"/>
<field name="res_id" ref="base.res_partner_12"/>
</record>
<!-- Agrolait -->
<record id="customer_payment_mode_2" model="ir.property" forcecreate="True">
<field name="name">customer_payment_mode_2</field>
<field name="fields_id"
search="[('model','=','res.partner'),('name','=','customer_payment_mode')]"/>
<field name="value"
eval="'payment.mode,'+str(ref('account_banking_payment_export.payment_mode_3'))"/>
<field name="company_id" ref="base.main_company"/>
<field name="res_id" ref="base.res_partner_2"/>
</record>
<!-- Asustek -->
<record id="supplier_payment_mode_1" model="ir.property" forcecreate="True">
<field name="name">supplier_payment_mode_1</field>
<field name="fields_id"
search="[('model','=','res.partner'),('name','=','supplier_payment_mode')]"/>
<field name="value"
eval="'payment.mode,'+str(ref('account_banking_payment_export.payment_mode_2'))"/>
<field name="company_id" ref="base.main_company"/>
<field name="res_id" ref="base.res_partner_1"/>
</record>
</data>
</openerp>

View File

@@ -2,4 +2,4 @@
from . import res_partner
from . import account_invoice
from . import payment_mode
from . import account_move_line

View File

@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# © 2014 Akretion - Alexis de Lattre <alexis.delattre@akretion.com>
# © 2014-2016 Akretion - Alexis de Lattre <alexis.delattre@akretion.com>
# © 2014 Serv. Tecnol. Avanzados - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
@@ -10,27 +10,70 @@ class AccountInvoice(models.Model):
_inherit = 'account.invoice'
payment_mode_id = fields.Many2one(
comodel_name='payment.mode', string="Payment Mode",
domain="[('type', '=', type)]")
comodel_name='account.payment.mode', string="Payment Mode",
ondelete='restrict',
readonly=True, states={'draft': [('readonly', False)]})
bank_account_required = fields.Boolean(
related='payment_mode_id.payment_method_id.bank_account_required',
readonly=True)
@api.multi
def onchange_partner_id(
self, type, partner_id, date_invoice=False,
payment_term=False, partner_bank_id=False, company_id=False):
res = super(AccountInvoice, self).onchange_partner_id(
type, partner_id, date_invoice=date_invoice,
payment_term=payment_term, partner_bank_id=partner_bank_id,
company_id=company_id)
if partner_id:
partner = self.env['res.partner'].browse(partner_id)
if type == 'in_invoice':
res['value']['payment_mode_id'] = \
partner.supplier_payment_mode.id
elif type == 'out_invoice':
res['value'].update({
'payment_mode_id': partner.customer_payment_mode.id,
'partner_bank_id': partner.customer_payment_mode.bank_id.id
})
@api.onchange('partner_id', 'company_id')
def _onchange_partner_id(self):
super(AccountInvoice, self)._onchange_partner_id()
if self.partner_id:
if self.type == 'in_invoice':
pay_mode = self.partner_id.supplier_payment_mode_id
self.payment_mode_id = pay_mode
if (
pay_mode and
pay_mode.payment_type == 'outbound' and
pay_mode.payment_method_id.bank_account_required and
self.commercial_partner_id.bank_ids):
self.partner_bank_id =\
self.commercial_partner_id.bank_ids[0]
elif self.type == 'out_invoice':
pay_mode = self.partner_id.customer_payment_mode_id
self.payment_mode_id = pay_mode
if pay_mode and pay_mode.bank_account_link == 'fixed':
self.partner_bank_id = pay_mode.fixed_journal_id.\
bank_account_id
else:
res['value']['payment_mode_id'] = False
self.payment_mode_id = False
if self.type == 'in_invoice':
self.partner_bank_id = False
@api.onchange('payment_mode_id')
def payment_mode_id_change(self):
if (
self.payment_mode_id and
self.payment_mode_id.payment_type == 'outbound' and
not self.payment_mode_id.payment_method_id.
bank_account_required):
self.partner_bank_id = False
elif not self.payment_mode_id:
self.partner_bank_id = False
@api.model
def line_get_convert(self, line, part):
"""Copy payment mode from invoice to account move line"""
res = super(AccountInvoice, self).line_get_convert(line, part)
if line.get('type') == 'dest' and line.get('invoice_id'):
invoice = self.browse(line['invoice_id'])
res['payment_mode_id'] = invoice.payment_mode_id.id or False
return res
# I think copying payment mode from invoice to refund by default
# is a good idea because the most common way of "paying" a refund is to
# deduct it on the payment of the next invoice (and OCA/bank-payment
# allows to have negative payment lines since March 2016)
@api.model
def _prepare_refund(
self, invoice, date_invoice=None, date=None, description=None,
journal_id=None):
vals = super(AccountInvoice, self)._prepare_refund(
invoice, date_invoice=date_invoice, date=date,
description=description, journal_id=journal_id)
vals['payment_mode_id'] = invoice.payment_mode_id.id
if invoice.type == 'in_invoice':
vals['partner_bank_id'] = invoice.partner_bank_id.id
return vals

View File

@@ -0,0 +1,12 @@
# -*- coding: utf-8 -*-
# © 2016 Akretion (http://www.akretion.com/)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import models, fields
class AccountMoveLine(models.Model):
_inherit = 'account.move.line'
payment_mode_id = fields.Many2one(
'account.payment.mode', string='Payment Mode', ondelete='restrict')

View File

@@ -1,16 +0,0 @@
# -*- coding: utf-8 -*-
# © 2014 Akretion - Alexis de Lattre <alexis.delattre@akretion.com>
# © 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
class PaymentMode(models.Model):
_inherit = "payment.mode"
default_payment_mode = fields.Selection([
('same', 'Same'),
('same_or_null', 'Same or empty'),
('any', 'Any'),
], string='Payment Mode on Invoice', default='same')

View File

@@ -9,17 +9,20 @@ from openerp import models, fields, api
class ResPartner(models.Model):
_inherit = 'res.partner'
supplier_payment_mode = fields.Many2one(
'payment.mode', string='Supplier Payment Mode', company_dependent=True,
domain="[('purchase_ok', '=', True)]",
# v8 fields : same without the _id suffix
supplier_payment_mode_id = fields.Many2one(
'account.payment.mode', string='Supplier Payment Mode',
company_dependent=True,
domain=[('payment_type', '=', 'outbound')],
help="Select the default payment mode for this supplier.")
customer_payment_mode = fields.Many2one(
'payment.mode', string='Customer Payment Mode', company_dependent=True,
domain="[('sale_ok', '=', True)]",
customer_payment_mode_id = fields.Many2one(
'account.payment.mode', string='Customer Payment Mode',
company_dependent=True,
domain=[('payment_type', '=', 'inbound')],
help="Select the default payment mode for this customer.")
@api.model
def _commercial_fields(self):
res = super(ResPartner, self)._commercial_fields()
res += ['supplier_payment_mode', 'customer_payment_mode']
res += ['supplier_payment_mode_id', 'customer_payment_mode_id']
return res

View File

@@ -1,3 +0,0 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_payment_mode_read,Read access on payment.mode to Employees,account_payment.model_payment_mode,base.group_user,1,0,0,0
access_payment_mode_type_read,Read access on payment.mode.type to Employees,account_banking_payment_export.model_payment_mode_type,base.group_user,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_payment_mode_read Read access on payment.mode to Employees account_payment.model_payment_mode base.group_user 1 0 0 0
3 access_payment_mode_type_read Read access on payment.mode.type to Employees account_banking_payment_export.model_payment_mode_type base.group_user 1 0 0 0

View File

@@ -1,21 +1,20 @@
<?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
© 2014-2016 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<openerp>
<odoo>
<data>
<record id="invoice_filter" model="ir.ui.view">
<field name="name">account_payment_partner.invoice_filter</field>
<record id="view_account_invoice_filter" model="ir.ui.view">
<field name="name">account_payment_partner.account_invoice_search</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.view_account_invoice_filter"/>
<field name="arch" type="xml">
<filter string="Status" position="after">
<filter string="Payment mode" name="filter_payment_mode" context="{'group_by':'payment_mode_id'}"/>
<filter name="status" position="after">
<filter string="Payment Mode" name="payment_mode_groupby"
context="{'group_by': 'payment_mode_id'}"/>
</filter>
</field>
</record>
@@ -28,8 +27,12 @@
<field name="arch" type="xml">
<field name="partner_bank_id" position="after">
<field name="payment_mode_id"
domain="[('sale_ok', '=', True)]"
domain="[('payment_type', '=', 'inbound')]"
widget="selection"/>
<field name="commercial_partner_id" invisible="1"/>
</field>
<field name="partner_bank_id" position="attributes">
<attribute name="invisible">0</attribute>
</field>
</field>
</record>
@@ -40,14 +43,43 @@
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.invoice_supplier_form" />
<field name="arch" type="xml">
<field name="partner_bank_id" position="after">
<field name="partner_bank_id" position="before">
<field name="payment_mode_id"
domain="[('purchase_ok', '=', True)]"
domain="[('payment_type', '=', 'outbound')]"
widget="selection"/>
<field name="commercial_partner_id" invisible="1"/>
<field name="bank_account_required" invisible="1"/>
</field>
<field name="partner_bank_id" position="attributes">
<attribute name="domain">[('partner_id', '=', commercial_partner_id)]</attribute>
<attribute name="invisible">0</attribute>
<attribute name="attrs">{'invisible': [('bank_account_required', '=', False)], 'required': [('bank_account_required', '=', True)]}</attribute>
</field>
</field>
</record>
<record id="invoice_tree" model="ir.ui.view">
<field name="name">account_payment_partner.customer_invoice_tree</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.invoice_tree"/>
<field name="arch" type="xml">
<field name="residual_signed" position="after">
<field name="payment_mode_id"/>
</field>
</field>
</record>
<record id="invoice_supplier_tree" model="ir.ui.view">
<field name="name">account_payment_partner.supplier_invoice_tree</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.invoice_supplier_tree"/>
<field name="arch" type="xml">
<field name="residual_signed" position="after">
<field name="payment_mode_id"/>
</field>
</field>
</record>
</data>
</openerp>
</odoo>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 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_move_line_form" model="ir.ui.view">
<field name="name">account_payment_partner.move_line_form</field>
<field name="model">account.move.line</field>
<field name="inherit_id" ref="account.view_move_line_form" />
<field name="arch" type="xml">
<group groups="analytic.group_analytic_accounting" position="after">
<group name="payments" string="Payments">
<field name="payment_mode_id" widget="selection"/>
</group>
</group>
</field>
</record>
</data>
</openerp>

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_payment_mode_form" model="ir.ui.view">
<field name="name">account_payment_partner.payment.mode.form</field>
<field name="model">payment.mode</field>
<field name="inherit_id" ref="account_banking_payment_export.view_payment_mode_form_inherit"/>
<field name="arch" type="xml">
<group name="payment_order_create_defaults" position="inside">
<field name="default_payment_mode"
attrs="{'invisible': [('default_invoice', '=', False)]}"/>
</group>
</field>
</record>
</data>
</openerp>

View File

@@ -2,7 +2,7 @@
<openerp>
<data>
<template id="report_invoice_payment_mode" inherit_id="account.report_invoice_document">
<xpath expr="//p[@t-if='o.payment_term.note']" position="after">
<xpath expr="//p[@t-if='o.payment_term_id']" position="after">
<p t-if="o.payment_mode_id.note">
<strong>Payment Mode:</strong>
<span t-field="o.payment_mode_id.note" />

View File

@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2014 Akretion (http://www.akretion.com/)
Copyright (C) 2014-2016 Akretion (http://www.akretion.com/)
@author Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __openerp__.py
-->
@@ -9,23 +8,21 @@
<openerp>
<data>
<record id="view_partner_property_form" model="ir.ui.view">
<field name="name">account_partner_payment.partner_form</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="account.view_partner_property_form" />
<field name="arch" type="xml">
<field name="property_payment_term" position="after">
<field name="customer_payment_mode"
domain="[('sale_ok', '=', True)]"
widget="selection"/>
<field name="property_payment_term_id" position="after">
<field name="customer_payment_mode_id" widget="selection"/>
</field>
<field name="property_supplier_payment_term" position="after">
<field name="supplier_payment_mode"
domain="[('purchase_ok', '=', True)]"
widget="selection"/>
<field name="property_supplier_payment_term_id" position="after">
<field name="supplier_payment_mode_id" widget="selection"/>
</field>
</field>
</record>
</data>
</openerp>

View File

@@ -1,23 +0,0 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Payment Partner 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 payment_order_create

View File

@@ -1,60 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Account Payment Partner module for Odoo
# Copyright (C) 2014-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 models, fields, api
class PaymentOrderCreate(models.TransientModel):
_inherit = 'payment.order.create'
payment_mode = fields.Selection([
('same', 'Same'),
('same_or_null', 'Same or empty'),
('any', 'Any'),
], string='Payment Mode on Invoice')
@api.model
def default_get(self, field_list):
res = super(PaymentOrderCreate, self).default_get(field_list)
context = self.env.context
assert context.get('active_model') == 'payment.order',\
'active_model should be payment.order'
assert context.get('active_id'), 'Missing active_id in context !'
pay_order = self.env['payment.order'].browse(context['active_id'])
res['payment_mode'] = pay_order.mode.default_payment_mode
return res
@api.multi
def extend_payment_order_domain(self, payment_order, domain):
res = super(PaymentOrderCreate, self).extend_payment_order_domain(
payment_order, domain)
if self.invoice and self.payment_mode:
if self.payment_mode == 'same':
domain.append(
('invoice.payment_mode_id', '=', payment_order.mode.id))
elif self.payment_mode == 'same_or_null':
domain += [
'|',
('invoice.payment_mode_id', '=', False),
('invoice.payment_mode_id', '=', payment_order.mode.id)]
# if payment_mode == 'any', don't modify domain
return res

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015 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_create_payment_order" model="ir.ui.view">
<field name="name">account_payment_partner.payment.order.create.form</field>
<field name="model">payment.order.create</field>
<field name="inherit_id" ref="account_banking_payment_export.view_create_payment_order"/>
<field name="arch" type="xml">
<field name="invoice" position="after">
<field name="payment_mode"
attrs="{'invisible': [('invoice', '=', False)], 'required': [('invoice', '=', True)]}"/>
</field>
</field>
</record>
</data>
</openerp>