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)
Various fixes/changes/improvements/...
This commit is contained in:
Alexis de Lattre
2016-05-06 01:16:20 +02:00
committed by Enric Tobella
parent e00c726c7b
commit 469af80ee7
13 changed files with 421 additions and 150 deletions

View File

@@ -28,7 +28,7 @@ Installation
This module depends on:
* account_payment
* account_payment_partner
* base_iban
This modules is part of the OCA/bank-payment suite.
@@ -36,16 +36,16 @@ This modules is part of the OCA/bank-payment suite.
Configuration
=============
No configuration required.
This module adds several options on Payment Modes, cf Accounting > Configuration > Management > Payment Modes.
Usage
=====
This module provides a menu to configure payment order types : Accounting > Configuration > Miscellaneous > Payment Export Types
You can create a Payment Order via the menu Accounting > Payments > Payment Orders and then select the move lines to pay.
For further information, please visit:
You can create a Debit Order via the menu Accounting > Payments > Debit Orders and then select the move lines to debit.
* https://www.odoo.com/forum/help-1
This module also adds a button *Add to Payment Order* on supplier invoices and a button *Add to Debit Order* on customer invoices.
Known issues / Roadmap
======================
@@ -58,7 +58,7 @@ 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_banking_payment_export%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
`here <https://github.com/OCA/bank-payment/issues/new?body=module:%20account_banking_payment_export%0Aversion:%209.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Credits

View File

@@ -32,7 +32,7 @@
'views/bank_payment_line.xml',
'views/account_move_line.xml',
'views/ir_attachment.xml',
#'views/res_partner_bank.xml',
'views/account_invoice_view.xml',
'data/payment_seq.xml',
],
'demo': ['demo/payment_demo.xml'],

View File

@@ -3,50 +3,22 @@
# © 2014 Serv. Tecnol. Avanzados - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import api, models, _
from lxml import etree
from openerp import models, fields, api, _
from openerp.exceptions import UserError
class AccountInvoice(models.Model):
_inherit = 'account.invoice'
payment_order_ok = fields.Boolean(
related='payment_mode_id.payment_order_ok', readonly=True)
@api.model
def _get_reference_type(self):
rt = super(AccountInvoice, self)._get_reference_type()
rt.append(('structured', _('Structured Reference')))
return rt
@api.model
def fields_view_get(self, view_id=None, view_type=False, toolbar=False,
submenu=False):
"""This adds the field 'reference_type' only if the view doesn't
contain this field (this is for customer invoice and with
l10n_be_invoice_bba not installed).
"""
res = super(AccountInvoice, self).fields_view_get(
view_id=view_id, view_type=view_type, toolbar=toolbar,
submenu=submenu)
if view_type != 'form':
return res
field_name = 'reference_type'
doc = etree.XML(res['arch'])
if not doc.xpath("//field[@name='%s']" % field_name):
nodes = doc.xpath("//field[@name='origin']")
if nodes:
field = self.fields_get([field_name])[field_name]
field_xml = etree.Element(
'field', {'name': field_name,
'widget': 'selection',
'states': str(field['states']),
'selection': str(field['selection']),
'required': '1' if field['required'] else '0',
'string': field['string'],
'nolabel': '0'})
nodes[0].addnext(field_xml)
res['arch'] = etree.tostring(doc)
res['fields'][field_name] = field
return res
@api.model
def line_get_convert(self, line, part):
"""Copy supplier bank account from invoice to account move line"""
@@ -56,3 +28,72 @@ class AccountInvoice(models.Model):
if invoice.type in ('in_invoice', 'in_refund'):
res['partner_bank_id'] = invoice.partner_bank_id.id or False
return res
@api.multi
def _prepare_new_payment_order(self):
self.ensure_one()
vals = {
'payment_mode_id': self.payment_mode_id.id,
'payment_type': self.payment_mode_id.payment_type,
}
if self.payment_mode_id.bank_account_link == 'fixed':
vals['journal_id'] = self.payment_mode_id.fixed_journal_id.id
# TODO : else: no filter on allowed bank accounts, because onchange not played ??
return vals
@api.multi
def create_account_payment_line(self):
apoo = self.env['account.payment.order']
aplo = self.env['account.payment.line']
action = {}
for inv in self:
if not inv.payment_mode_id:
raise UserError(_(
"No Payment Mode on invoice %s") % inv.number)
if not inv.move_id:
raise UserError(_(
"No Journal Entry on invoice %s") % inv.number)
payorders = apoo.search([
('payment_mode_id', '=', inv.payment_mode_id.id),
('state', '=', 'draft')])
if payorders:
payorder = payorders[0]
new_payorder = False
else:
payorder = apoo.create(inv._prepare_new_payment_order())
new_payorder = True
count = 0
for line in inv.move_id.line_ids:
if line.account_id == inv.account_id and not line.reconciled:
paylines = aplo.search([
('move_line_id', '=', line.id),
('state', '!=', 'cancel')])
if paylines:
continue
line.create_payment_line_from_move_line(payorder)
count += 1
if count:
if new_payorder:
inv.message_post(_(
'%d payment lines added to the new draft payment '
'order %s which has been automatically created.')
% (count, payorder.name))
else:
inv.message_post(_(
'%d payment lines added to the existing draft '
'payment order %s.')
% (count, payorder.name))
else:
raise UserError(_(
'No Payment Line created for invoice %s because '
'it already exists or because this invoice is '
'already paid.') % inv.number)
action = self.env['ir.actions.act_window'].for_xml_id(
'account_payment_order',
'account_payment_order_%s_action' % payorder.payment_type)
action.update({
'view_mode': 'form,tree,pivot,graph',
'res_id': payorder.id,
'views': False,
})
return action

View File

@@ -45,17 +45,22 @@ class AccountMoveLine(models.Model):
self.ensure_one()
assert payment_order, 'Missing payment order'
aplo = self.env['account.payment.line']
# default values for communication_type and communication
communication_type = 'normal'
communication = self.move_id.name or '-'
ref2comm_type = aplo.invoice_reference_type2communication_type()
if (
self.invoice_id and
self.invoice_id.type in ('in_invoice', 'in_refund') and
self.invoice_id.reference):
communication = self.invoice_id.reference
if self.invoice_id.reference_type:
# change these default values if move line is linked to an invoice
if self.invoice_id:
if self.invoice_id.reference_type != 'none':
communication = self.invoice_id.reference
ref2comm_type =\
aplo.invoice_reference_type2communication_type()
communication_type =\
ref2comm_type[self.invoice_id.reference_type]
else:
if (
self.invoice_id.type in ('in_invoice', 'in_refund')
and self.invoice_id.reference):
communication = self.invoice_id.reference
if self.currency_id:
currency_id = self.currency_id.id
amount_currency = self.amount_residual_currency
@@ -66,7 +71,6 @@ class AccountMoveLine(models.Model):
precision = self.env['decimal.precision'].precision_get('Account')
if payment_order.payment_type == 'outbound':
amount_currency *= -1
# TODO : inherit for mandate
vals = {
'order_id': payment_order.id,
'partner_bank_id': self.partner_bank_id.id,

View File

@@ -20,6 +20,9 @@ class AccountPaymentLine(models.Model):
related='order_id.company_currency_id', store=True, readonly=True)
payment_type = fields.Selection(
related='order_id.payment_type', store=True, readonly=True)
state = fields.Selection(
related='order_id.state', string='State',
readonly=True, store=True)
move_line_id = fields.Many2one(
'account.move.line', string='Journal Item')
ml_maturity_date = fields.Date(
@@ -83,6 +86,11 @@ class AccountPaymentLine(models.Model):
values = []
for field in bplo.same_fields_payment_line_and_bank_payment_line():
values.append(unicode(self[field]))
# Don't group the payment lines that are attached to the same supplier
# but to move lines with different accounts (very unlikely),
# for easier generation/comprehension of the transfer move
# TODO Alexis : but this is for ????
values.append(unicode(self.move_line_id.account_id or False))
hashcode = '-'.join(values)
return hashcode

View File

@@ -5,7 +5,8 @@
# © 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 openerp import models, fields, api, _
from openerp.exceptions import ValidationError
class AccountPaymentMode(models.Model):
@@ -42,6 +43,38 @@ class AccountPaymentMode(models.Model):
"* Payment Date\n"
"(other modules can set additional fields to restrict the "
"grouping.)")
transfer_move = fields.Boolean(
'Generate Accounting Entries On File Upload')
transfer_account_id = fields.Many2one(
'account.account', string='Transfer Account',
domain=[('internal_type', '=', 'other'), ('reconcile', '=', True)],
help="Pay off lines in 'file uploaded' payment orders with a move on "
"this account. You can only select accounts of type regular "
"that are marked for reconciliation")
transfer_journal_id = fields.Many2one(
'account.journal', string='Transfer Journal',
help='Journal to write payment entries when confirming '
'payment/debit orders of this mode')
transfer_move_option = fields.Selection([
('date', 'One move per payment date'),
('line', 'One move per payment line'),
], string='Transfer Move Option', default='date')
@api.multi
@api.constrains(
'transfer_move', 'transfer_account_id', 'transfer_journal_id',
'transfer_move_option')
def transfer_move_constrains(self):
for mode in self:
if mode.transfer_move and (
not mode.transfer_account_id or
not mode.transfer_journal_id or
not mode.transfer_move_option):
raise ValidationError(_(
"The option 'Generate Accounting Entries On File Upload' "
"is active on payment mode '%s', so the three parameters "
"'Transfer Account', 'Transfer Journal' and "
"'Transfer Move Option' must be set.") % mode.name)
@api.onchange('payment_method_id')
def payment_method_id_change(self):

View File

@@ -35,7 +35,9 @@ class AccountPaymentOrder(models.Model):
related='payment_mode_id.bank_account_link', readonly=True)
journal_id = fields.Many2one(
'account.journal', string='Bank Journal',
required=True)
readonly=True, states={'draft': [('readonly', False)]})
# The journal_id field is only required at confirm step, to
# allow auto-creation of payment order from invoice
company_partner_bank_id = fields.Many2one(
related='journal_id.bank_account_id', string='Company Bank Account',
readonly=True)
@@ -174,6 +176,9 @@ class AccountPaymentOrder(models.Model):
bplo = self.env['bank.payment.line']
today = fields.Date.context_today(self)
for order in self:
if not order.journal_id:
raise UserError(_(
'Missing Bank Journal on payment order %s') % order.name)
# Delete existing bank payment lines
order.bank_line_ids.unlink()
# Create the bank payment lines from the payment lines
@@ -257,5 +262,144 @@ class AccountPaymentOrder(models.Model):
@api.multi
def generated2uploaded(self):
for order in self:
if order.payment_mode_id.transfer_move:
order.generate_transfer_move()
self.write({'state': 'uploaded'})
return True
# Generation of transfer move
@api.multi
def _prepare_transfer_move(self):
vals = {
'journal_id': self.mode.transfer_journal_id.id,
'ref': '%s %s' % (
self.payment_order_type[:3].upper(), self.reference)
}
return vals
@api.multi
def _prepare_move_line_transfer_account(
self, amount, move, bank_payment_lines, labels):
if len(bank_payment_lines) == 1:
partner_id = bank_payment_lines[0].partner_id.id
name = _('%s bank line %s') % (labels[self.payment_order_type],
bank_payment_lines[0].name)
else:
partner_id = False
name = '%s %s' % (
labels[self.payment_order_type], self.reference)
date_maturity = bank_payment_lines[0].date
vals = {
'name': name,
'move_id': move.id,
'partner_id': partner_id,
'account_id': self.mode.transfer_account_id.id,
'credit': (self.payment_order_type == 'payment' and
amount or 0.0),
'debit': (self.payment_order_type == 'debit' and
amount or 0.0),
'date_maturity': date_maturity,
}
return vals
@api.multi
def _prepare_move_line_partner_account(self, bank_line, move, labels):
# TODO : ALEXIS check don't group if move_line_id.account_id
# is not the same
if bank_line.payment_line_ids[0].move_line_id:
account_id =\
bank_line.payment_line_ids[0].move_line_id.account_id.id
else:
if self.payment_order_type == 'debit':
account_id =\
bank_line.partner_id.property_account_receivable.id
else:
account_id = bank_line.partner_id.property_account_payable.id
vals = {
'name': _('%s line %s') % (
labels[self.payment_order_type], bank_line.name),
'move_id': move.id,
'partner_id': bank_line.partner_id.id,
'account_id': account_id,
'credit': (self.payment_order_type == 'debit' and
bank_line.amount_currency or 0.0),
'debit': (self.payment_order_type == 'payment' and
bank_line.amount_currency or 0.0),
}
return vals
@api.multi
def action_sent_no_move_line_hook(self, pay_line):
"""This function is designed to be inherited"""
return
@api.multi
def _create_move_line_partner_account(self, bank_line, move, labels):
"""This method is designed to be inherited in a custom module"""
# TODO: take multicurrency into account
company_currency = self.env.user.company_id.currency_id
if bank_line.currency != company_currency:
raise UserError(_(
"Cannot generate the transfer move when "
"the currency of the payment (%s) is not the "
"same as the currency of the company (%s). This "
"is not supported for the moment.")
% (bank_line.currency.name, company_currency.name))
aml_obj = self.env['account.move.line']
# create the payment/debit counterpart move line
# on the partner account
partner_ml_vals = self._prepare_move_line_partner_account(
bank_line, move, labels)
partner_move_line = aml_obj.create(partner_ml_vals)
# register the payment/debit move line
# on the payment line and call reconciliation on it
bank_line.write({'transit_move_line_id': partner_move_line.id})
@api.multi
def _reconcile_payment_lines(self, bank_payment_lines):
for bline in bank_payment_lines:
if all([pline.move_line_id for pline in bline.payment_line_ids]):
bline.debit_reconcile()
else:
self.action_sent_no_move_line_hook(bline)
@api.multi
def generate_transfer_move(self):
"""
Create the moves that pay off the move lines from
the debit order.
"""
self.ensure_one()
am_obj = self.env['account.move']
aml_obj = self.env['account.move.line']
labels = {
'outbound': _('Payment'),
'inbound': _('Direct debit'),
}
# prepare a dict "trfmoves" that can be used when
# self.mode.transfer_move_option = date or line
# key = unique identifier (date or True or line.id)
# value = [pay_line1, pay_line2, ...]
trfmoves = {}
for bline in self.bank_line_ids:
hashcode = bline.move_line_transfer_account_hashcode()
if hashcode in trfmoves:
trfmoves[hashcode].append(bline)
else:
trfmoves[hashcode] = [bline]
for hashcode, blines in trfmoves.iteritems():
mvals = self._prepare_transfer_move()
move = am_obj.create(mvals)
total_amount = 0
for bline in blines:
total_amount += bline.amount_currency
self._create_move_line_partner_account(bline, move, labels)
# create the payment/debit move line on the transfer account
trf_ml_vals = self._prepare_move_line_transfer_account(
total_amount, move, blines, labels)
aml_obj.create(trf_ml_vals)
self._reconcile_payment_lines(blines)
move.post()

View File

@@ -29,6 +29,7 @@ class BankPaymentLine(models.Model):
readonly=True)
# Function Float fields are sometimes badly displayed in tree view,
# see bug report https://github.com/odoo/odoo/issues/8632
# But is it still true in v9 ?
amount_currency = fields.Monetary(
string='Amount', currency_field='currency_id',
compute='_compute_amount', store=True, readonly=True)
@@ -48,6 +49,28 @@ class BankPaymentLine(models.Model):
company_id = fields.Many2one(
related='order_id.payment_mode_id.company_id', store=True,
readonly=True)
# TODO : not shown in view ?
# why on bank payment line and not on payment line ?
transit_move_line_id = fields.Many2one(
'account.move.line', string='Transfer Move Line', readonly=True,
help="Move line through which the payment/debit order "
"pays the invoice")
transfer_move_line_id = fields.Many2one(
'account.move.line', compute='_get_transfer_move_line',
string='Transfer move line counterpart',
help="Counterpart move line on the transfer account")
@api.multi
def _get_transfer_move_line(self):
for bank_line in self:
if bank_line.transit_move_line_id:
payment_type = bank_line.payment_type
trf_lines = bank_line.transit_move_line_id.move_id.line_id
for move_line in trf_lines:
if payment_type == 'inbound' and move_line.debit > 0:
bank_line.transfer_move_line_id = move_line
elif payment_type == 'outbound' and move_line.credit > 0:
bank_line.transfer_move_line_id = move_line
@api.model
def same_fields_payment_line_and_bank_payment_line(self):
@@ -76,3 +99,17 @@ class BankPaymentLine(models.Model):
vals['name'] = self.env['ir.sequence'].next_by_code(
'bank.payment.line') or 'New'
return super(BankPaymentLine, self).create(vals)
@api.multi
def move_line_transfer_account_hashcode(self):
"""
This method is inherited in the module
account_banking_sepa_direct_debit
"""
self.ensure_one()
if self.order_id.payment_mode_id.transfer_move_option == 'date':
hashcode = self.date
else:
hashcode = unicode(self.id)
return hashcode

View File

@@ -0,0 +1,55 @@
<?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="invoice_form" model="ir.ui.view">
<field name="name">account_payment_order.invoice_form</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account_payment_partner.invoice_form" />
<field name="arch" type="xml">
<button name="%(account.action_account_invoice_payment)d" type="action" position="after">
<button name="create_account_payment_line" type="object"
string="Add to Debit Order"
groups="account_payment_order.group_account_payment"
attrs="{'invisible': ['|', ('payment_order_ok', '=', False), ('state', '!=', 'open')]}"/>
<!-- For customer refunds:
'Add to Direct Debit Order' will deduct the refund from a customer invoice
We could also need a button 'Add to Payment Order' to reimburse
a customer via wire transfer... but I prefer to keep things
simple ; to do that, the user should manually create a payment order
and select the move lines -->
</button>
<field name="payment_mode_id" position="after">
<field name="payment_order_ok" invisible="1"/>
</field>
</field>
</record>
<record id="invoice_supplier_form" model="ir.ui.view">
<field name="name">account_payment_order.invoice_supplier_form</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account_payment_partner.invoice_supplier_form" />
<field name="arch" type="xml">
<button name="%(account.action_account_invoice_payment)d" type="action" position="after">
<button name="create_account_payment_line" type="object"
string="Add to Payment Order"
groups="account_payment_order.group_account_payment"
attrs="{'invisible': ['|', ('payment_order_ok', '=', False), ('state', '!=', 'open')]}"/>
</button>
<field name="payment_mode_id" position="after">
<field name="payment_order_ok" invisible="1"/>
</field>
</field>
</record>
</data>
</openerp>

View File

@@ -19,6 +19,16 @@
<field name="default_invoice"/>
<field name="default_date_type"/>
</group>
<group name="trf-move-config" string="Accounting Entries Options">
<field name="transfer_move"/>
<field name="transfer_account_id"
attrs="{'invisible': [('transfer_move', '=', False)], 'required': [('transfer_move', '=', True)]}"
context="{'default_internal_type': 'other', 'default_reconcile': True, 'default_company_id': company_id}"/>
<field name="transfer_journal_id"
attrs="{'invisible': [('transfer_move', '=', False)], 'required': [('transfer_move', '=', True)]}"/>
<field name="transfer_move_option"
attrs="{'invisible': [('transfer_move', '=', False)], 'required': [('transfer_move', '=', True)]}"/>
</group>
</group>
</field>
</record>

View File

@@ -88,6 +88,11 @@
<field name="model">account.payment.order</field>
<field name="arch" type="xml">
<search string="Search Payment Orders">
<filter name="draft" string="Draft" domain="[('state', '=', 'draft')]"/>
<filter name="open" string="Confirmed" domain="[('state', '=', 'open')]"/>
<filter name="generated" string="File Generated" domain="[('state', '=', 'generated')]"/>
<filter name="uploaded" string="File Uploaded" domain="[('state', '=', 'uploaded')]"/>
<filter name="done" string="Done" domain="[('state', '=', 'done')]"/>
<group string="Group By" name="groupby">
<filter name="payment_mode_groupby" string="Payment Mode" context="{'group_by': 'payment_mode_id'}"/>
<filter name="journal_groupby" string="Bank Journal" context="{'group_by': 'journal_id'}"/>
@@ -98,10 +103,33 @@
</field>
</record>
<record id="account_payment_order_graph" model="ir.ui.view">
<field name="name">account.payment.order.graph</field>
<field name="model">account.payment.order</field>
<field name="arch" type="xml">
<graph string="Payment Orders">
<field name="date_generated" type="row" interval="month"/>
<field name="total_company_currency" type="measure"/>
</graph>
</field>
</record>
<record id="account_payment_order_pivot" model="ir.ui.view">
<field name="name">account.payment.order.pivot</field>
<field name="model">account.payment.order</field>
<field name="arch" type="xml">
<pivot string="Payment Orders">
<field name="date_generated" type="row" interval="month"/>
<field name="total_company_currency" type="measure"/>
</pivot>
</field>
</record>
<record id="account_payment_order_outbound_action" model="ir.actions.act_window">
<field name="name">Payment Orders</field>
<field name="res_model">account.payment.order</field>
<field name="view_mode">tree,form</field>
<field name="view_mode">tree,form,pivot,graph</field>
<field name="domain">[('payment_type', '=', 'outbound')]</field>
<field name="context">{'default_payment_type': 'outbound'}</field>
</record>
@@ -109,7 +137,7 @@
<record id="account_payment_order_inbound_action" model="ir.actions.act_window">
<field name="name">Debit Orders</field>
<field name="res_model">account.payment.order</field>
<field name="view_mode">tree,form</field>
<field name="view_mode">tree,form,pivot,graph</field>
<field name="domain">[('payment_type', '=', 'inbound')]</field>
<field name="context">{'default_payment_type': 'inbound'}</field>
</record>

View File

@@ -102,6 +102,13 @@ class AccountPaymentLineCreate(models.TransientModel):
('debit', '>', 0),
('account_id.internal_type', '=', 'receivable'),
]
# Exclude lines that are already in a non-cancelled payment order
paylines = self.env['account.payment.line'].search([
('state', '!=', 'cancel'),
('move_line_id', '!=', False)])
if paylines:
move_lines_ids = [payline.move_line_id.id for payline in paylines]
domain += [('id', 'not in', move_lines_ids)]
return domain
@api.multi
@@ -127,106 +134,9 @@ class AccountPaymentLineCreate(models.TransientModel):
res = {'domain': {'move_line_ids': domain}}
return res
@api.multi
def filter_lines(self, lines):
""" Filter move lines before proposing them for inclusion
in the payment order.
This implementation filters out move lines that are already
included in draft or open payment orders. This prevents the
user to include the same line in two different open payment
orders. When the payment order is sent, it is assumed that
the move will be reconciled soon (or immediately with
account_banking_payment_transfer), so it will not be
proposed anymore for payment.
See also https://github.com/OCA/bank-payment/issues/93.
:param lines: recordset of move lines
:returns: list of move line ids
"""
self.ensure_one()
payment_lines = self.env['account.payment.line'].\
search([('order_id.state', 'in', ('draft', 'open')),
('move_line_id', 'in', lines.ids)])
to_exclude = set([l.move_line_id.id for l in payment_lines])
return [l.id for l in lines if l.id not in to_exclude]
@api.multi
def _prepare_payment_line(self, payment, line):
"""This function is designed to be inherited
The resulting dict is passed to the create method of payment.line"""
self.ensure_one()
_today = fields.Date.context_today(self)
date_to_pay = False # no payment date => immediate payment
if payment.date_prefered == 'due':
# -- account_banking
# date_to_pay = line.date_maturity
date_to_pay = (
line.date_maturity
if line.date_maturity and line.date_maturity > _today
else False)
# -- end account banking
elif payment.date_prefered == 'fixed':
# -- account_banking
# date_to_pay = payment.date_scheduled
date_to_pay = (
payment.date_scheduled
if payment.date_scheduled and payment.date_scheduled > _today
else False)
# -- end account banking
# -- account_banking
state = 'normal'
communication = line.ref or '-'
if line.invoice:
if line.invoice.reference_type == 'structured':
state = 'structured'
# Fallback to invoice number to keep previous behaviour
communication = line.invoice.reference or line.invoice.number
else:
if line.invoice.type in ('in_invoice', 'in_refund'):
communication = (
line.invoice.reference or
line.invoice.supplier_invoice_number or line.ref)
else:
# Make sure that the communication includes the
# customer invoice number (in the case of debit order)
communication = line.invoice.number
# support debit orders when enabled
if line.debit > 0:
amount_currency = line.amount_residual_currency * -1
else:
amount_currency = line.amount_residual_currency
if payment.payment_order_type == 'debit':
amount_currency *= -1
line2bank = line.line2bank(payment.mode.id)
# -- end account banking
res = {'move_line_id': line.id,
'amount_currency': amount_currency,
'bank_id': line2bank.get(line.id),
'order_id': payment.id,
'partner_id': line.partner_id and line.partner_id.id or False,
# account banking
'communication': communication,
'state': state,
# end account banking
'date': date_to_pay,
'currency': (line.invoice and line.invoice.currency_id.id or
line.journal_id.currency.id or
line.journal_id.company_id.currency_id.id)}
return res
@api.multi
def create_payment_lines(self):
if self.move_line_ids:
self.move_line_ids.create_payment_line_from_move_line(
self.order_id)
return True
# Force reload of payment order view as a workaround for lp:1155525
return {'name': _('Payment Orders'),
'context': context,
'view_type': 'form',
'view_mode': 'form,tree',
'res_model': 'payment.order',
'res_id': context['active_id'],
'type': 'ir.actions.act_window'}

View File

@@ -22,7 +22,8 @@
placeholder="Keep empty for using all journals"/>
<field name="payment_mode"/>
<field name="invoice"/>
<button name="populate" type="object" string="Populate"/>
<label string="Click on Add All Move Lines to auto-select the move lines matching the above criteria or click on Add an item to manually select the move lines filtered by the above criteria." colspan="2"/>
<button name="populate" type="object" string="Add All Move Lines"/>
</group>
<group name="move_lines" string="Selected Move Lines to Create Transactions">
<field name="move_line_ids" nolabel="1">