[MIG] account_payment_order: Migration to 13.0

This commit is contained in:
Raf Ven
2020-03-12 19:49:29 +01:00
parent 3506c0ad12
commit 1e6ce5225e
27 changed files with 397 additions and 526 deletions

View File

@@ -14,13 +14,13 @@ Account Payment Order
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fbank--payment-lightgray.png?logo=github
:target: https://github.com/OCA/bank-payment/tree/12.0/account_payment_order
:target: https://github.com/OCA/bank-payment/tree/13.0/account_payment_order
:alt: OCA/bank-payment
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/bank-payment-12-0/bank-payment-12-0-account_payment_order
:target: https://translation.odoo-community.org/projects/bank-payment-13-0/bank-payment-13-0-account_payment_order
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/173/12.0
:target: https://runbot.odoo-community.org/runbot/173/13.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
@@ -66,7 +66,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 <https://github.com/OCA/bank-payment/issues/new?body=module:%20account_payment_order%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
`feedback <https://github.com/OCA/bank-payment/issues/new?body=module:%20account_payment_order%0Aversion:%2013.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
@@ -99,6 +99,9 @@ Contributors
* Jose María Alzaga <jose.alzaga@aselcis.com>
* Meyomesse Gilles <meyomesse.gilles@gmail.com>
* Carlos Dauden
* `DynApps <https://www.dynapps.be>`_:
* Raf Ven <raf.ven@dynapps.be>
Maintainers
~~~~~~~~~~~
@@ -113,6 +116,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
This module is part of the `OCA/bank-payment <https://github.com/OCA/bank-payment/tree/12.0/account_payment_order>`_ project on GitHub.
This module is part of the `OCA/bank-payment <https://github.com/OCA/bank-payment/tree/13.0/account_payment_order>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@@ -8,7 +8,7 @@
{
"name": "Account Payment Order",
"version": "12.0.1.4.0",
"version": "13.0.1.0.0",
"license": "AGPL-3",
"author": "ACSONE SA/NV, "
"Therp BV, "
@@ -17,7 +17,8 @@
"Odoo Community Association (OCA)",
"website": "https://github.com/OCA/bank-payment",
"category": "Banking addons",
"depends": ["account_payment_partner", "base_iban",], # for manual_bank_tranfer
"external_dependencies": {"python": ["lxml"]},
"depends": ["account_payment_partner", "base_iban"], # for manual_bank_tranfer
"data": [
"views/account_payment_method.xml",
"security/payment_security.xml",

View File

@@ -1279,4 +1279,3 @@ msgstr ""
#: model_terms:ir.ui.view,arch_db:account_payment_order.account_invoice_payment_line_multi_form
msgid "otherwise, new payment orders will be created (one per payment mode)."
msgstr ""

View File

@@ -4,7 +4,6 @@ from . import account_payment_line
from . import bank_payment_line
from . import account_move
from . import account_move_line
from . import account_invoice
from . import res_bank
from . import account_payment_method
from . import account_journal

View File

@@ -1,152 +0,0 @@
# © 2013-2014 ACSONE SA (<https://acsone.eu>).
# © 2014 Serv. Tecnol. Avanzados - Pedro M. Baeza
# © 2016 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from odoo import _, api, fields, models
from odoo.exceptions import UserError
class AccountInvoice(models.Model):
_inherit = "account.invoice"
payment_order_ok = fields.Boolean(compute="_compute_payment_order_ok",)
# we restore this field from <=v11 for now for preserving behavior
# TODO: Check if we can remove it and base everything in something at
# payment mode or company level
reference_type = fields.Selection(
selection=[("none", "Free Reference"), ("structured", "Structured Reference"),],
string="Payment Reference",
required=True,
readonly=True,
states={"draft": [("readonly", False)]},
default="none",
)
@api.depends(
"payment_mode_id",
"move_id",
"move_id.line_ids",
"move_id.line_ids.payment_mode_id",
)
def _compute_payment_order_ok(self):
for invoice in self:
payment_mode = invoice.move_id.line_ids.filtered(
lambda x: not x.reconciled
).mapped("payment_mode_id")[:1]
if not payment_mode:
payment_mode = invoice.payment_mode_id
invoice.payment_order_ok = payment_mode.payment_order_ok
@api.model
def line_get_convert(self, line, part):
"""Copy supplier bank account 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"])
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, payment_mode=None):
self.ensure_one()
if payment_mode is None:
payment_mode = self.env["account.payment.mode"]
vals = {
"payment_mode_id": payment_mode.id or self.payment_mode_id.id,
}
# other important fields are set by the inherit of create
# in account_payment_order.py
return vals
@api.multi
def create_account_payment_line(self):
apoo = self.env["account.payment.order"]
result_payorder_ids = []
action_payment_type = "debit"
for inv in self:
if inv.state != "open":
raise UserError(_("The invoice %s is not in Open state") % inv.number)
if not inv.move_id:
raise UserError(_("No Journal Entry on invoice %s") % inv.number)
applicable_lines = inv.move_id.line_ids.filtered(
lambda x: (
not x.reconciled
and x.payment_mode_id.payment_order_ok
and x.account_id.internal_type in ("receivable", "payable")
and not any(
p_state in ("draft", "open", "generated")
for p_state in x.payment_line_ids.mapped("state")
)
)
)
if not applicable_lines:
raise UserError(
_(
"No Payment Line created for invoice %s because "
"it already exists or because this invoice is "
"already paid."
)
% inv.number
)
payment_modes = applicable_lines.mapped("payment_mode_id")
if not payment_modes:
raise UserError(_("No Payment Mode on invoice %s") % inv.number)
for payment_mode in payment_modes:
payorder = apoo.search(
[
("payment_mode_id", "=", payment_mode.id),
("state", "=", "draft"),
],
limit=1,
)
new_payorder = False
if not payorder:
payorder = apoo.create(inv._prepare_new_payment_order(payment_mode))
new_payorder = True
result_payorder_ids.append(payorder.id)
action_payment_type = payorder.payment_type
count = 0
for line in applicable_lines.filtered(
lambda x: x.payment_mode_id == payment_mode
):
line.create_payment_line_from_move_line(payorder)
count += 1
if new_payorder:
inv.message_post(
body=_(
"%d payment lines added to the new draft payment "
"order %s which has been automatically created."
)
% (count, payorder.name)
)
else:
inv.message_post(
body=_(
"%d payment lines added to the existing draft "
"payment order %s."
)
% (count, payorder.name)
)
action = self.env["ir.actions.act_window"].for_xml_id(
"account_payment_order",
"account_payment_order_%s_action" % action_payment_type,
)
if len(result_payorder_ids) == 1:
action.update(
{
"view_mode": "form,tree,pivot,graph",
"res_id": payorder.id,
"views": False,
}
)
else:
action.update(
{
"view_mode": "tree,form,pivot,graph",
"domain": "[('id', 'in', %s)]" % result_payorder_ids,
"views": False,
}
)
return action

View File

@@ -8,13 +8,12 @@ class AccountJournal(models.Model):
_inherit = "account.journal"
inbound_payment_order_only = fields.Boolean(
compute="_compute_inbound_payment_order_only", readonly=True, store=True,
compute="_compute_inbound_payment_order_only", readonly=True, store=True
)
outbound_payment_order_only = fields.Boolean(
compute="_compute_outbound_payment_order_only", readonly=True, store=True,
compute="_compute_outbound_payment_order_only", readonly=True, store=True
)
@api.multi
@api.depends("inbound_payment_method_ids.payment_order_only")
def _compute_inbound_payment_order_only(self):
for rec in self:
@@ -22,7 +21,6 @@ class AccountJournal(models.Model):
p.payment_order_only for p in rec.inbound_payment_method_ids
)
@api.multi
@api.depends("outbound_payment_method_ids.payment_order_only")
def _compute_outbound_payment_order_only(self):
for rec in self:

View File

@@ -1,12 +1,139 @@
# © 2013-2014 ACSONE SA (<https://acsone.eu>).
# © 2014 Serv. Tecnol. Avanzados - Pedro M. Baeza
# © 2016 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from odoo import fields, models
from odoo import _, api, fields, models
from odoo.exceptions import UserError
class AccountMove(models.Model):
_inherit = "account.move"
payment_order_id = fields.Many2one(
"account.payment.order", string="Payment Order", copy=False, readonly=True
comodel_name="account.payment.order",
string="Payment Order",
copy=False,
readonly=True,
)
payment_order_ok = fields.Boolean(compute="_compute_payment_order_ok")
# we restore this field from <=v11 for now for preserving behavior
# TODO: Check if we can remove it and base everything in something at
# payment mode or company level
reference_type = fields.Selection(
selection=[("none", "Free Reference"), ("structured", "Structured Reference")],
string="Reference Type",
required=True,
readonly=True,
states={"draft": [("readonly", False)]},
default="none",
)
@api.depends("payment_mode_id", "line_ids", "line_ids.payment_mode_id")
def _compute_payment_order_ok(self):
for move in self:
payment_mode = move.line_ids.filtered(lambda x: not x.reconciled).mapped(
"payment_mode_id"
)[:1]
if not payment_mode:
payment_mode = move.payment_mode_id
move.payment_order_ok = payment_mode.payment_order_ok
def _prepare_new_payment_order(self, payment_mode=None):
self.ensure_one()
if payment_mode is None:
payment_mode = self.env["account.payment.mode"]
vals = {"payment_mode_id": payment_mode.id or self.payment_mode_id.id}
# other important fields are set by the inherit of create
# in account_payment_order.py
return vals
def create_account_payment_line(self):
apoo = self.env["account.payment.order"]
result_payorder_ids = []
action_payment_type = "debit"
for move in self:
if move.state != "posted":
raise UserError(_("The invoice %s is not in Posted state") % move.name)
applicable_lines = move.line_ids.filtered(
lambda x: (
not x.reconciled
and x.payment_mode_id.payment_order_ok
and x.account_id.internal_type in ("receivable", "payable")
and not any(
p_state in ("draft", "open", "generated")
for p_state in x.payment_line_ids.mapped("state")
)
)
)
if not applicable_lines:
raise UserError(
_(
"No Payment Line created for invoice %s because "
"it already exists or because this invoice is "
"already paid."
)
% move.name
)
payment_modes = applicable_lines.mapped("payment_mode_id")
if not payment_modes:
raise UserError(_("No Payment Mode on invoice %s") % move.name)
for payment_mode in payment_modes:
payorder = apoo.search(
[
("payment_mode_id", "=", payment_mode.id),
("state", "=", "draft"),
],
limit=1,
)
new_payorder = False
if not payorder:
payorder = apoo.create(
move._prepare_new_payment_order(payment_mode)
)
new_payorder = True
result_payorder_ids.append(payorder.id)
action_payment_type = payorder.payment_type
count = 0
for line in applicable_lines.filtered(
lambda x: x.payment_mode_id == payment_mode
):
line.create_payment_line_from_move_line(payorder)
count += 1
if new_payorder:
move.message_post(
body=_(
"%d payment lines added to the new draft payment "
"order %s which has been automatically created."
)
% (count, payorder.name)
)
else:
move.message_post(
body=_(
"%d payment lines added to the existing draft "
"payment order %s."
)
% (count, payorder.name)
)
action = self.env["ir.actions.act_window"].for_xml_id(
"account_payment_order",
"account_payment_order_%s_action" % action_payment_type,
)
if len(result_payorder_ids) == 1:
action.update(
{
"view_mode": "form,tree,pivot,graph",
"res_id": payorder.id,
"views": False,
}
)
else:
action.update(
{
"view_mode": "tree,form,pivot,graph",
"domain": "[('id', 'in', %s)]" % result_payorder_ids,
"views": False,
}
)
return action

View File

@@ -2,23 +2,20 @@
# © 2014 Serv. Tecnol. Avanzados - Pedro M. Baeza
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from lxml import etree
from odoo import api, fields, models
from odoo import fields, models
from odoo.fields import first
from odoo.osv import orm
class AccountMoveLine(models.Model):
_inherit = "account.move.line"
partner_bank_id = fields.Many2one(
"res.partner.bank",
comodel_name="res.partner.bank",
string="Partner Bank Account",
help="Bank account on which we should pay the supplier",
)
bank_payment_line_id = fields.Many2one(
"bank.payment.line", string="Bank Payment Line", readonly=True, index=True,
comodel_name="bank.payment.line", readonly=True, index=True
)
payment_line_ids = fields.One2many(
comodel_name="account.payment.line",
@@ -26,29 +23,28 @@ class AccountMoveLine(models.Model):
string="Payment lines",
)
@api.multi
def _prepare_payment_line_vals(self, payment_order):
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.ref or self.move_id.name
communication = self.ref or self.name
# 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
if self.move_id.is_invoice():
if self.move_id.reference_type != "none":
communication = self.move_id.ref
ref2comm_type = aplo.invoice_reference_type2communication_type()
communication_type = ref2comm_type[self.invoice_id.reference_type]
communication_type = ref2comm_type[self.move_id.reference_type]
else:
if (
self.invoice_id.type in ("in_invoice", "in_refund")
and self.invoice_id.reference
self.move_id.type in ("in_invoice", "in_refund")
and self.move_id.ref
):
communication = self.invoice_id.reference
elif "out" in self.invoice_id.type:
communication = self.move_id.ref
elif "out" in self.move_id.type:
# Force to only put invoice number here
communication = self.invoice_id.number
communication = self.move_id.name
if self.currency_id:
currency_id = self.currency_id.id
amount_currency = self.amount_residual_currency
@@ -73,55 +69,8 @@ class AccountMoveLine(models.Model):
}
return vals
@api.multi
def create_payment_line_from_move_line(self, payment_order):
vals_list = []
for mline in self:
vals_list.append(mline._prepare_payment_line_vals(payment_order))
return self.env["account.payment.line"].create(vals_list)
@api.model
def fields_view_get(
self, view_id=None, view_type="form", toolbar=False, submenu=False
):
# When the user looks for open payables or receivables, in the
# context of payment orders, she should focus primarily on amount that
# is due to be paid, and secondarily on the total amount. In this
# method we are forcing to display both the amount due in company and
# in the invoice currency.
# We then hide the fields debit and credit, because they add no value.
result = super(AccountMoveLine, self).fields_view_get(
view_id, view_type, toolbar=toolbar, submenu=submenu
)
doc = etree.XML(result["arch"])
if view_type == "tree" and self._module == "account_payment_order":
if not doc.xpath("//field[@name='balance']"):
for placeholder in doc.xpath("//field[@name='amount_currency']"):
elem = etree.Element(
"field", {"name": "balance", "readonly": "True"}
)
orm.setup_modifiers(elem)
placeholder.addprevious(elem)
if not doc.xpath("//field[@name='amount_residual_currency']"):
for placeholder in doc.xpath("//field[@name='amount_currency']"):
elem = etree.Element(
"field",
{"name": "amount_residual_currency", "readonly": "True"},
)
orm.setup_modifiers(elem)
placeholder.addnext(elem)
if not doc.xpath("//field[@name='amount_residual']"):
for placeholder in doc.xpath("//field[@name='amount_currency']"):
elem = etree.Element(
"field", {"name": "amount_residual", "readonly": "True"}
)
orm.setup_modifiers(elem)
placeholder.addnext(elem)
# Remove credit and debit data - which is irrelevant in this case
for elem in doc.xpath("//field[@name='debit']"):
doc.remove(elem)
for elem in doc.xpath("//field[@name='credit']"):
doc.remove(elem)
result["arch"] = etree.tostring(doc)
return result

View File

@@ -17,7 +17,6 @@ class AccountPayment(models.Model):
res["domain"] = journal_domain
return res
@api.multi
@api.onchange("journal_id")
def _onchange_journal(self):
res = super(AccountPayment, self)._onchange_journal()

View File

@@ -11,7 +11,10 @@ class AccountPaymentLine(models.Model):
name = fields.Char(string="Payment Reference", readonly=True, copy=False)
order_id = fields.Many2one(
"account.payment.order", string="Payment Order", ondelete="cascade", index=True
comodel_name="account.payment.order",
string="Payment Order",
ondelete="cascade",
index=True,
)
company_id = fields.Many2one(
related="order_id.company_id", store=True, readonly=True
@@ -29,50 +32,45 @@ class AccountPaymentLine(models.Model):
related="order_id.state", string="State", readonly=True, store=True
)
move_line_id = fields.Many2one(
"account.move.line", string="Journal Item", ondelete="restrict"
comodel_name="account.move.line", string="Journal Item", ondelete="restrict"
)
ml_maturity_date = fields.Date(related="move_line_id.date_maturity", readonly=True)
currency_id = fields.Many2one(
"res.currency",
comodel_name="res.currency",
string="Currency of the Payment Transaction",
required=True,
default=lambda self: self.env.user.company_id.currency_id,
)
# v8 field : currency
amount_currency = fields.Monetary(string="Amount", currency_field="currency_id")
amount_company_currency = fields.Monetary(
compute="_compute_amount_company_currency",
string="Amount in Company Currency",
readonly=True,
currency_field="company_currency_id",
) # v8 field : amount
)
partner_id = fields.Many2one(
"res.partner",
comodel_name="res.partner",
string="Partner",
required=True,
domain=[("parent_id", "=", False)],
)
partner_bank_id = fields.Many2one(
"res.partner.bank",
comodel_name="res.partner.bank",
string="Partner Bank Account",
required=False,
ondelete="restrict",
) # v8 field : bank_id
)
date = fields.Date(string="Payment Date")
communication = fields.Char(
string="Communication",
required=True,
help="Label of the payment that will be seen by the destinee",
required=True, help="Label of the payment that will be seen by the destinee"
)
communication_type = fields.Selection(
[("normal", "Free"),],
string="Communication Type",
required=True,
default="normal",
selection=[("normal", "Free")], required=True, default="normal"
)
# v8 field : state
bank_line_id = fields.Many2one(
"bank.payment.line", string="Bank Payment Line", readonly=True, index=True,
comodel_name="bank.payment.line",
string="Bank Payment Line",
readonly=True,
index=True,
)
_sql_constraints = [
@@ -91,7 +89,6 @@ class AccountPaymentLine(models.Model):
)
return super(AccountPaymentLine, self).create(vals)
@api.multi
@api.depends("amount_currency", "currency_id", "company_currency_id", "date")
def _compute_amount_company_currency(self):
for line in self:
@@ -103,7 +100,6 @@ class AccountPaymentLine(models.Model):
line.date or fields.Date.today(),
)
@api.multi
def payment_line_hashcode(self):
self.ensure_one()
bplo = self.env["bank.payment.line"]
@@ -150,7 +146,6 @@ class AccountPaymentLine(models.Model):
res = {"none": "normal", "structured": "structured"}
return res
@api.multi
def draft2open_payment_line_check(self):
self.ensure_one()
if self.bank_account_required and not self.partner_bank_id:

View File

@@ -26,12 +26,12 @@ class AccountPaymentMode(models.Model):
)
# Default options for the "payment.order.create" wizard
default_payment_mode = fields.Selection(
[("same", "Same"), ("same_or_null", "Same or empty"), ("any", "Any"),],
selection=[("same", "Same"), ("same_or_null", "Same or empty"), ("any", "Any")],
string="Payment Mode on Invoice",
default="same",
)
default_journal_ids = fields.Many2many(
"account.journal",
comodel_name="account.journal",
string="Journals Filter",
domain="[('company_id', '=', company_id)]",
)
@@ -39,16 +39,22 @@ class AccountPaymentMode(models.Model):
string="Linked to an Invoice or Refund", default=False
)
default_target_move = fields.Selection(
[("posted", "All Posted Entries"), ("all", "All Entries"),],
selection=[("posted", "All Posted Entries"), ("all", "All Entries")],
string="Target Moves",
default="posted",
)
default_date_type = fields.Selection(
[("due", "Due"), ("move", "Move"),], default="due", string="Type of Date Filter"
selection=[("due", "Due"), ("move", "Move")],
default="due",
string="Type of Date Filter",
)
# default option for account.payment.order
default_date_prefered = fields.Selection(
[("now", "Immediately"), ("due", "Due Date"), ("fixed", "Fixed Date"),],
selection=[
("now", "Immediately"),
("due", "Due Date"),
("fixed", "Fixed Date"),
],
string="Default Payment Execution Date",
)
group_lines = fields.Boolean(
@@ -70,32 +76,33 @@ class AccountPaymentMode(models.Model):
string="Generate Accounting Entries On File Upload", default=True
)
offsetting_account = fields.Selection(
[("bank_account", "Bank Account"), ("transfer_account", "Transfer Account"),],
string="Offsetting Account",
selection=[
("bank_account", "Bank Account"),
("transfer_account", "Transfer Account"),
],
default="bank_account",
)
transfer_account_id = fields.Many2one(
"account.account",
string="Transfer Account",
comodel_name="account.account",
domain=[("reconcile", "=", True)],
help="Pay off lines in 'file uploaded' payment orders with a move on "
"this account. You can only select accounts "
"that are marked for reconciliation",
)
transfer_journal_id = fields.Many2one(
"account.journal",
string="Transfer Journal",
comodel_name="account.journal",
help="Journal to write payment entries when confirming "
"payment/debit orders of this mode",
)
move_option = fields.Selection(
[("date", "One move per payment date"), ("line", "One move per payment line"),],
string="Move Option",
selection=[
("date", "One move per payment date"),
("line", "One move per payment line"),
],
default="date",
)
post_move = fields.Boolean(string="Post Move", default=True)
post_move = fields.Boolean(default=True)
@api.multi
@api.constrains(
"generate_move",
"offsetting_account",

View File

@@ -16,24 +16,22 @@ class AccountPaymentOrder(models.Model):
_inherit = ["mail.thread"]
_order = "id desc"
name = fields.Char(string="Number", readonly=True, copy=False) # v8 field : name
name = fields.Char(string="Number", readonly=True, copy=False)
payment_mode_id = fields.Many2one(
"account.payment.mode",
"Payment Mode",
comodel_name="account.payment.mode",
required=True,
ondelete="restrict",
track_visibility="onchange",
readonly=True,
states={"draft": [("readonly", False)]},
)
payment_type = fields.Selection(
[("inbound", "Inbound"), ("outbound", "Outbound"),],
selection=[("inbound", "Inbound"), ("outbound", "Outbound")],
string="Payment Type",
readonly=True,
required=True,
)
payment_method_id = fields.Many2one(
"account.payment.method",
comodel_name="account.payment.method",
related="payment_mode_id.payment_method_id",
readonly=True,
store=True,
@@ -53,7 +51,7 @@ class AccountPaymentOrder(models.Model):
string="Allowed journals",
)
journal_id = fields.Many2one(
"account.journal",
comodel_name="account.journal",
string="Bank Journal",
ondelete="restrict",
readonly=True,
@@ -68,7 +66,7 @@ class AccountPaymentOrder(models.Model):
readonly=True,
)
state = fields.Selection(
[
selection=[
("draft", "Draft"),
("open", "Confirmed"),
("generated", "File Generated"),
@@ -83,7 +81,11 @@ class AccountPaymentOrder(models.Model):
track_visibility="onchange",
)
date_prefered = fields.Selection(
[("now", "Immediately"), ("due", "Due Date"), ("fixed", "Fixed Date"),],
selection=[
("now", "Immediately"),
("due", "Due Date"),
("fixed", "Fixed Date"),
],
string="Payment Execution Date Type",
required=True,
default="due",
@@ -103,23 +105,22 @@ class AccountPaymentOrder(models.Model):
date_uploaded = fields.Date(string="File Upload Date", readonly=True)
date_done = fields.Date(string="Done Date", readonly=True)
generated_user_id = fields.Many2one(
"res.users",
comodel_name="res.users",
string="Generated by",
readonly=True,
ondelete="restrict",
copy=False,
)
payment_line_ids = fields.One2many(
"account.payment.line",
"order_id",
comodel_name="account.payment.line",
inverse_name="order_id",
string="Transaction Lines",
readonly=True,
states={"draft": [("readonly", False)]},
)
# v8 field : line_ids
bank_line_ids = fields.One2many(
"bank.payment.line",
"order_id",
comodel_name="bank.payment.line",
inverse_name="order_id",
string="Bank Payment Lines",
readonly=True,
help="The bank payment lines are used to generate the payment file. "
@@ -130,16 +131,16 @@ class AccountPaymentOrder(models.Model):
"mode.",
)
total_company_currency = fields.Monetary(
compute="_compute_total",
store=True,
readonly=True,
currency_field="company_currency_id",
compute="_compute_total", store=True, currency_field="company_currency_id"
)
bank_line_count = fields.Integer(
compute="_compute_bank_line_count", string="Number of Bank Lines", readonly=True
compute="_compute_bank_line_count", string="Number of Bank Lines"
)
move_ids = fields.One2many(
"account.move", "payment_order_id", string="Journal Entries", readonly=True
comodel_name="account.move",
inverse_name="payment_order_id",
string="Journal Entries",
readonly=True,
)
description = fields.Char()
@@ -150,8 +151,9 @@ class AccountPaymentOrder(models.Model):
record.allowed_journal_ids = record.payment_mode_id.fixed_journal_id
elif record.payment_mode_id.bank_account_link == "variable":
record.allowed_journal_ids = record.payment_mode_id.variable_journal_ids
else:
record.allowed_journal_ids = False
@api.multi
def unlink(self):
for order in self:
if order.state == "uploaded":
@@ -163,7 +165,6 @@ class AccountPaymentOrder(models.Model):
)
return super(AccountPaymentOrder, self).unlink()
@api.multi
@api.constrains("payment_type", "payment_mode_id")
def payment_order_constraints(self):
for order in self:
@@ -179,7 +180,6 @@ class AccountPaymentOrder(models.Model):
% (order.payment_type, order.payment_mode_id.payment_type)
)
@api.multi
@api.constrains("date_scheduled")
def check_date_scheduled(self):
today = fields.Date.context_today(self)
@@ -194,7 +194,6 @@ class AccountPaymentOrder(models.Model):
% (order.name, order.date_scheduled)
)
@api.multi
@api.depends("payment_line_ids", "payment_line_ids.amount_company_currency")
def _compute_total(self):
for rec in self:
@@ -202,7 +201,6 @@ class AccountPaymentOrder(models.Model):
rec.mapped("payment_line_ids.amount_company_currency") or [0.0]
)
@api.multi
@api.depends("bank_line_ids")
def _compute_bank_line_count(self):
for order in self:
@@ -232,29 +230,23 @@ class AccountPaymentOrder(models.Model):
if self.payment_mode_id.default_date_prefered:
self.date_prefered = self.payment_mode_id.default_date_prefered
@api.multi
def action_done(self):
self.write(
{"date_done": fields.Date.context_today(self), "state": "done",}
)
self.write({"date_done": fields.Date.context_today(self), "state": "done"})
return True
@api.multi
def action_done_cancel(self):
for move in self.move_ids:
move.button_cancel()
for move_line in move.line_ids:
move_line.remove_move_reconcile()
move.unlink()
move.with_context(force_delete=True).unlink()
self.action_cancel()
return True
@api.multi
def cancel2draft(self):
self.write({"state": "draft"})
return True
@api.multi
def action_cancel(self):
for order in self:
order.write({"state": "cancel"})
@@ -269,7 +261,6 @@ class AccountPaymentOrder(models.Model):
"communication": "-".join([line.communication for line in paylines]),
}
@api.multi
def draft2open(self):
"""
Called when you click on the 'Confirm' button
@@ -368,7 +359,6 @@ class AccountPaymentOrder(models.Model):
self.write({"state": "open"})
return True
@api.multi
def generate_payment_file(self):
"""Returns (payment file as string, filename)"""
self.ensure_one()
@@ -382,7 +372,6 @@ class AccountPaymentOrder(models.Model):
)
)
@api.multi
def open2generated(self):
self.ensure_one()
payment_file_str, filename = self.generate_payment_file()
@@ -394,7 +383,6 @@ class AccountPaymentOrder(models.Model):
"res_id": self.id,
"name": filename,
"datas": base64.b64encode(payment_file_str),
"datas_fname": filename,
}
)
simplified_form_view = self.env.ref(
@@ -418,17 +406,15 @@ class AccountPaymentOrder(models.Model):
)
return action
@api.multi
def generated2uploaded(self):
for order in self:
if order.payment_mode_id.generate_move:
order.generate_move()
self.write(
{"state": "uploaded", "date_uploaded": fields.Date.context_today(self),}
{"state": "uploaded", "date_uploaded": fields.Date.context_today(self)}
)
return True
@api.multi
def _prepare_move(self, bank_lines=None):
if self.payment_type == "outbound":
ref = _("Payment order %s") % self.name
@@ -458,7 +444,6 @@ class AccountPaymentOrder(models.Model):
vals["line_ids"].append((0, 0, trf_ml_vals))
return vals
@api.multi
def _prepare_move_line_offsetting_account(
self, amount_company_currency, amount_payment_currency, bank_lines
):
@@ -507,7 +492,6 @@ class AccountPaymentOrder(models.Model):
)
return vals
@api.multi
def _prepare_move_line_partner_account(self, bank_line):
if bank_line.payment_line_ids[0].move_line_id:
account_id = bank_line.payment_line_ids[0].move_line_id.account_id.id
@@ -547,7 +531,6 @@ class AccountPaymentOrder(models.Model):
)
return vals
@api.multi
def _create_reconcile_move(self, hashcode, blines):
self.ensure_one()
post_move = self.payment_mode_id.post_move
@@ -558,7 +541,6 @@ class AccountPaymentOrder(models.Model):
if post_move:
move.post()
@api.multi
def _prepare_trf_moves(self):
"""
prepare a dict "trfmoves" that can be used when
@@ -576,7 +558,6 @@ class AccountPaymentOrder(models.Model):
trfmoves[hashcode] = bline
return trfmoves
@api.multi
def generate_move(self):
"""
Create the moves that pay off the move lines from

View File

@@ -12,26 +12,26 @@ class BankPaymentLine(models.Model):
name = fields.Char(string="Bank Payment Line Ref", required=True, readonly=True)
order_id = fields.Many2one(
"account.payment.order",
string="Order",
comodel_name="account.payment.order",
ondelete="cascade",
index=True,
readonly=True,
)
payment_type = fields.Selection(
related="order_id.payment_type",
string="Payment Type",
readonly=True,
store=True,
)
state = fields.Selection(
related="order_id.state", string="State", readonly=True, store=True
related="order_id.payment_type", readonly=True, store=True
)
state = fields.Selection(related="order_id.state", readonly=True, store=True)
payment_line_ids = fields.One2many(
"account.payment.line", "bank_line_id", string="Payment Lines", readonly=True
comodel_name="account.payment.line",
inverse_name="bank_line_id",
string="Payment Lines",
readonly=True,
)
partner_id = fields.Many2one(
"res.partner", related="payment_line_ids.partner_id", readonly=True, store=True
comodel_name="res.partner",
related="payment_line_ids.partner_id",
readonly=True,
store=True,
) # store=True for groupby
# Function Float fields are sometimes badly displayed in tree view,
# see bug report https://github.com/odoo/odoo/issues/8632
@@ -51,30 +51,30 @@ class BankPaymentLine(models.Model):
readonly=True,
)
currency_id = fields.Many2one(
"res.currency",
comodel_name="res.currency",
required=True,
readonly=True,
related="payment_line_ids.currency_id",
) # v8 field: currency
)
partner_bank_id = fields.Many2one(
"res.partner.bank",
comodel_name="res.partner.bank",
string="Bank Account",
readonly=True,
related="payment_line_ids.partner_bank_id",
) # v8 field: bank_id
)
date = fields.Date(related="payment_line_ids.date", readonly=True)
communication_type = fields.Selection(
related="payment_line_ids.communication_type", readonly=True
)
communication = fields.Char(string="Communication", required=True, readonly=True)
company_id = fields.Many2one(
"res.company",
comodel_name="res.company",
related="order_id.payment_mode_id.company_id",
store=True,
readonly=True,
)
company_currency_id = fields.Many2one(
"res.currency",
comodel_name="res.currency",
related="order_id.payment_mode_id.company_id.currency_id",
readonly=True,
store=True,
@@ -97,7 +97,6 @@ class BankPaymentLine(models.Model):
]
return same_fields
@api.multi
@api.depends("payment_line_ids", "payment_line_ids.amount_currency")
def _compute_amount(self):
for bline in self:
@@ -120,7 +119,6 @@ class BankPaymentLine(models.Model):
)
return super(BankPaymentLine, self).create(vals)
@api.multi
def move_line_offsetting_account_hashcode(self):
"""
This method is inherited in the module
@@ -133,7 +131,6 @@ class BankPaymentLine(models.Model):
hashcode = str(self.id)
return hashcode
@api.multi
def reconcile_payment_lines(self):
for bline in self:
if all([pline.move_line_id for pline in bline.payment_line_ids]):
@@ -141,12 +138,10 @@ class BankPaymentLine(models.Model):
else:
bline.no_reconcile_hook()
@api.multi
def no_reconcile_hook(self):
"""This method is designed to be inherited if needed"""
return
@api.multi
def reconcile(self):
self.ensure_one()
amlo = self.env["account.move.line"]
@@ -188,7 +183,6 @@ class BankPaymentLine(models.Model):
lines_to_rec.reconcile()
@api.multi
def unlink(self):
for line in self:
order_state = line.order_id.state

View File

@@ -8,7 +8,6 @@ from odoo.exceptions import ValidationError
class ResBank(models.Model):
_inherit = "res.bank"
@api.multi
@api.constrains("bic")
def check_bic_length(self):
for bank in self:

View File

@@ -13,3 +13,6 @@
* Jose María Alzaga <jose.alzaga@aselcis.com>
* Meyomesse Gilles <meyomesse.gilles@gmail.com>
* Carlos Dauden
* `DynApps <https://www.dynapps.be>`_:
* Raf Ven <raf.ven@dynapps.be>

View File

@@ -99,16 +99,12 @@
</td>
<td class="text-center">
<t
t-if="line.move_line_id.invoice_id and 'in_' in line.move_line_id.invoice_id.type"
t-if="line.move_line_id.move_id and 'in_' in line.move_line_id.move_id.type"
>
<span
t-field="line.move_line_id.invoice_id.reference"
/>
<span t-field="line.move_line_id.move_id.ref" />
</t>
<t t-else="">
<span
t-esc="line.move_line_id.invoice_id.number or line.move_line_id.move_id.name"
/>
<span t-esc="line.move_line_id.move_id.name" />
</t>
</td>
<td class="text-center">

View File

@@ -367,7 +367,7 @@ ul.auto-toc {
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/bank-payment/tree/12.0/account_payment_order"><img alt="OCA/bank-payment" src="https://img.shields.io/badge/github-OCA%2Fbank--payment-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/bank-payment-12-0/bank-payment-12-0-account_payment_order"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/173/12.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/bank-payment/tree/13.0/account_payment_order"><img alt="OCA/bank-payment" src="https://img.shields.io/badge/github-OCA%2Fbank--payment-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/bank-payment-13-0/bank-payment-13-0-account_payment_order"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/173/13.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p>This module adds support for payment orders and debit orders.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
@@ -411,7 +411,7 @@ Configuration &gt; Management &gt; Payment Modes.</p>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/bank-payment/issues">GitHub Issues</a>.
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
<a class="reference external" href="https://github.com/OCA/bank-payment/issues/new?body=module:%20account_payment_order%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<a class="reference external" href="https://github.com/OCA/bank-payment/issues/new?body=module:%20account_payment_order%0Aversion:%2013.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
@@ -443,6 +443,10 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<li>Jose María Alzaga &lt;<a class="reference external" href="mailto:jose.alzaga&#64;aselcis.com">jose.alzaga&#64;aselcis.com</a>&gt;</li>
<li>Meyomesse Gilles &lt;<a class="reference external" href="mailto:meyomesse.gilles&#64;gmail.com">meyomesse.gilles&#64;gmail.com</a>&gt;</li>
<li>Carlos Dauden</li>
<li><a class="reference external" href="https://www.dynapps.be">DynApps</a>:<ul>
<li>Raf Ven &lt;<a class="reference external" href="mailto:raf.ven&#64;dynapps.be">raf.ven&#64;dynapps.be</a>&gt;</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="maintainers">
@@ -452,7 +456,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/bank-payment/tree/12.0/account_payment_order">OCA/bank-payment</a> project on GitHub.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/bank-payment/tree/13.0/account_payment_order">OCA/bank-payment</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>

View File

@@ -28,7 +28,11 @@ class TestAccountPayment(SavepointCase):
[("type", "=", "bank")], limit=1
)
cls.bank_journal.inbound_payment_method_ids = [
(6, 0, [cls.inbound_payment_method_01.id, cls.inbound_payment_method_02.id])
(
6,
0,
[cls.inbound_payment_method_01.id, cls.inbound_payment_method_02.id],
)
]
cls.bank_journal.outbound_payment_method_ids = [
(6, 0, [cls.outbound_payment_method_01.id])
@@ -59,11 +63,7 @@ class TestAccountPayment(SavepointCase):
self.assertFalse(self.inbound_payment_method_02.payment_order_only)
self.assertFalse(self.bank_journal.inbound_payment_order_only)
new_account_payment = self.account_payment_model.new(
{
"journal_id": self.bank_journal.id,
"payment_type": "inbound",
"amount": 1,
}
{"journal_id": self.bank_journal.id, "payment_type": "inbound", "amount": 1}
)
# check journals
journal_res = new_account_payment._compute_journal_domain_and_types()

View File

@@ -6,7 +6,7 @@
from datetime import date, timedelta
from odoo.exceptions import UserError, ValidationError
from odoo.tests.common import SavepointCase
from odoo.tests.common import Form, SavepointCase
class TestPaymentOrderInboundBase(SavepointCase):
@@ -17,29 +17,22 @@ class TestPaymentOrderInboundBase(SavepointCase):
self.inbound_mode = self.env.ref(
"account_payment_mode.payment_mode_inbound_dd1"
)
self.invoice_line_account = (
self.env["account.account"]
.search(
[
(
"user_type_id",
"=",
self.env.ref("account.data_account_type_revenue").id,
)
],
limit=1,
)
.id
self.invoice_line_account = self.env["account.account"].search(
[
(
"user_type_id",
"=",
self.env.ref("account.data_account_type_revenue").id,
)
],
limit=1,
)
self.journal = self.env["account.journal"].search(
[("type", "=", "bank")], limit=1
)
self.inbound_mode.variable_journal_ids = self.journal
# Make sure no others orders are present
self.domain = [
("state", "=", "draft"),
("payment_type", "=", "inbound"),
]
self.domain = [("state", "=", "draft"), ("payment_type", "=", "inbound")]
self.payment_order_obj = self.env["account.payment.order"]
self.payment_order_obj.search(self.domain).unlink()
# Create payment order
@@ -52,56 +45,34 @@ class TestPaymentOrderInboundBase(SavepointCase):
)
# Open invoice
self.invoice = self._create_customer_invoice(self)
self.invoice.action_invoice_open()
self.invoice.action_post()
# Add to payment order using the wizard
self.env["account.invoice.payment.line.multi"].with_context(
active_model="account.invoice", active_ids=self.invoice.ids
active_model="account.move", active_ids=self.invoice.ids
).create({}).run()
def _create_customer_invoice(self):
invoice_account = (
self.env["account.account"]
.search(
[
(
"user_type_id",
"=",
self.env.ref("account.data_account_type_receivable").id,
)
],
limit=1,
)
.id
)
invoice = self.env["account.invoice"].create(
{
"partner_id": self.env.ref("base.res_partner_4").id,
"account_id": invoice_account,
"type": "out_invoice",
"payment_mode_id": self.inbound_mode.id,
}
)
self.env["account.invoice.line"].create(
{
"product_id": self.env.ref("product.product_product_4").id,
"quantity": 1.0,
"price_unit": 100.0,
"invoice_id": invoice.id,
"name": "product that cost 100",
"account_id": self.invoice_line_account,
}
)
return invoice
with Form(
self.env["account.move"].with_context(default_type="out_invoice")
) as invoice_form:
invoice_form.partner_id = self.env.ref("base.res_partner_4")
with invoice_form.invoice_line_ids.new() as invoice_line_form:
invoice_line_form.product_id = self.env.ref("product.product_product_4")
invoice_line_form.name = "product that cost 100"
invoice_line_form.quantity = 1
invoice_line_form.price_unit = 100.0
invoice_line_form.account_id = self.invoice_line_account
invoice = invoice_form.save()
invoice_form = Form(invoice)
invoice_form.payment_mode_id = self.inbound_mode
return invoice_form.save()
class TestPaymentOrderInbound(TestPaymentOrderInboundBase):
def test_constrains_type(self):
with self.assertRaises(ValidationError):
order = self.env["account.payment.order"].create(
{
"payment_mode_id": self.inbound_mode.id,
"journal_id": self.journal.id,
}
{"payment_mode_id": self.inbound_mode.id, "journal_id": self.journal.id}
)
order.payment_type = "outbound"
@@ -118,9 +89,7 @@ class TestPaymentOrderInbound(TestPaymentOrderInboundBase):
# Set journal to allow cancelling entries
bank_journal.update_posted = True
payment_order.write(
{"journal_id": bank_journal.id,}
)
payment_order.write({"journal_id": bank_journal.id})
self.assertEqual(len(payment_order.payment_line_ids), 1)
self.assertEqual(len(payment_order.bank_line_ids), 0)

View File

@@ -38,46 +38,30 @@ class TestPaymentOrderOutbound(TransactionCase):
[("type", "=", "bank")], limit=1
)
# Make sure no other payment orders are in the DB
self.domain = [
("state", "=", "draft"),
("payment_type", "=", "outbound"),
]
self.domain = [("state", "=", "draft"), ("payment_type", "=", "outbound")]
self.env["account.payment.order"].search(self.domain).unlink()
def _create_supplier_invoice(self):
invoice_account = (
self.env["account.account"]
.search(
[
(
"user_type_id",
"=",
self.env.ref("account.data_account_type_payable").id,
)
],
limit=1,
)
.id
)
invoice = self.env["account.invoice"].create(
invoice = self.env["account.move"].create(
{
"partner_id": self.env.ref("base.res_partner_4").id,
"account_id": invoice_account,
"type": "in_invoice",
"payment_mode_id": self.env.ref(
"account_payment_mode.payment_mode_outbound_ct1"
).id,
}
)
self.env["account.invoice.line"].create(
{
"product_id": self.env.ref("product.product_product_4").id,
"quantity": 1.0,
"price_unit": 100.0,
"invoice_id": invoice.id,
"name": "product that cost 100",
"account_id": self.invoice_line_account,
"invoice_line_ids": [
(
0,
None,
{
"product_id": self.env.ref("product.product_product_4").id,
"quantity": 1.0,
"price_unit": 100.0,
"name": "product that cost 100",
"account_id": self.invoice_line_account,
},
)
],
}
)
@@ -110,12 +94,12 @@ class TestPaymentOrderOutbound(TransactionCase):
}
)
self.invoice_02.action_invoice_open()
self.invoice_02.action_post()
self.order_creation("fixed")
def order_creation(self, date_prefered):
# Open invoice
self.invoice.action_invoice_open()
self.invoice.action_post()
order_vals = {
"payment_type": "outbound",
"payment_mode_id": self.creation_mode.id,
@@ -160,10 +144,10 @@ class TestPaymentOrderOutbound(TransactionCase):
def test_cancel_payment_order(self):
# Open invoice
self.invoice.action_invoice_open()
self.invoice.action_post()
# Add to payment order using the wizard
self.env["account.invoice.payment.line.multi"].with_context(
active_model="account.invoice", active_ids=self.invoice.ids
active_model="account.move", active_ids=self.invoice.ids
).create({}).run()
payment_order = self.env["account.payment.order"].search(self.domain)
@@ -174,9 +158,7 @@ class TestPaymentOrderOutbound(TransactionCase):
# Set journal to allow cancelling entries
bank_journal.update_posted = True
payment_order.write(
{"journal_id": bank_journal.id,}
)
payment_order.write({"journal_id": bank_journal.id})
self.assertEqual(len(payment_order.payment_line_ids), 1)
self.assertEqual(len(payment_order.bank_line_ids), 0)
@@ -202,9 +184,7 @@ class TestPaymentOrderOutbound(TransactionCase):
self.assertEqual(payment_order.state, "cancel")
payment_order.cancel2draft()
payment_order.unlink()
self.assertEqual(
len(self.env["account.payment.order"].search(self.domain)), 0,
)
self.assertEqual(len(self.env["account.payment.order"].search(self.domain)), 0)
def test_constrains(self):
outbound_order = self.env["account.payment.order"].create(

View File

@@ -4,74 +4,62 @@
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-->
<odoo>
<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" />
<record id="view_move_form" model="ir.ui.view">
<field name="name">account_payment_order.view_move_form</field>
<field name="model">account.move</field>
<field name="inherit_id" ref="account_payment_partner.view_move_form" />
<field name="arch" type="xml">
<button
name="%(account.action_account_invoice_payment)d"
type="action"
position="after"
>
<button id="account_invoice_payment_btn" position="after">
<!-- 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
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')]}"
attrs="{'invisible': ['|', '|',
('payment_order_ok', '=', False),
('state', '!=', 'open'),
('type', 'not in', ('out_invoice', 'out_refund'))
]}"
/>
<!-- 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 name="reference" position="before">
<field
name="reference_type"
required="1"
nolabel="1"
attrs="{'readonly':[('state','!=','draft')]}"
/>
</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')]}"
attrs="{'invisible': ['|', '|',
('payment_order_ok', '=', False),
('state', '!=', 'open'),
('type', 'not in', ('in_invoice', 'in_refund'))
]}"
/>
</button>
<field name="payment_mode_id" position="after">
<field name="payment_order_ok" invisible="1" />
</field>
<field name="ref" position="before">
<field
name="reference_type"
required="1"
nolabel="1"
attrs="{'readonly':[('state','!=','draft')],
'invisible': [('type', 'not in', ('out_invoice', 'out_refund'))]}"
/>
</field>
</field>
</record>
<act_window
id="account_invoice_create_account_payment_line_action"
multi="True"
key2="client_action_multi"
name="Add to Payment/Debit Order"
res_model="account.invoice.payment.line.multi"
src_model="account.invoice"
binding_model="account.move"
binding_views="form"
view_mode="form"
target="new"
id="account_invoice_create_account_payment_line_action"
/>
</odoo>

View File

@@ -19,4 +19,21 @@
</group>
</field>
</record>
<record id="view_move_line_tree" model="ir.ui.view">
<field name="name">account_payment_order.add.move_line_tree</field>
<field name="model">account.move.line</field>
<field name="inherit_id" ref="account.view_move_line_tree" />
<field name="mode">primary</field>
<field name="priority">99</field>
<field name="arch" type="xml">
<xpath expr="//field[@name='amount_currency']" position="after">
<field name="balance" readonly="1" />
<field name="amount_residual_currency" readonly="1" />
<field name="amount_residual" readonly="1" />
</xpath>
<xpath expr="//field[@name='debit']" position="replace" />
<xpath expr="//field[@name='credit']" position="replace" />
<xpath expr="//field[@name='tax_ids']" position="replace" />
</field>
</record>
</odoo>

View File

@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!--
© 2015-2016 Akretion (https://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-->
© 2015-2016 Akretion (https://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-->
<record id="bank_payment_line_form" model="ir.ui.view">
<field name="name">bank.payment.line.form</field>
<field name="model">bank.payment.line</field>

View File

@@ -14,15 +14,16 @@
<group name="main">
<field
name="datas"
filename="datas_fname"
filename="store_fname"
string="Generated File"
/>
<field name="datas_fname" invisible="1" />
<field name="store_fname" invisible="1" />
<label for="create_uid" string="Created by" />
<div name="creation_div">
<field name="create_uid" readonly="1" class="oe_inline" /> on
<field name="create_date" readonly="1" class="oe_inline" />
</div>
<field name="create_uid" readonly="1" class="oe_inline" />
on
<field name="create_date" readonly="1" class="oe_inline" />
</div>
</group>
</sheet>
</form>

View File

@@ -1,19 +1,18 @@
# © 2016 Akretion (<https://www.akretion.com>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from odoo import api, models
from odoo import models
class AccountInvoicePaymentLineMulti(models.TransientModel):
_name = "account.invoice.payment.line.multi"
_description = "Create payment lines from invoice tree view"
@api.multi
def run(self):
self.ensure_one()
assert (
self._context["active_model"] == "account.invoice"
), "Active model should be account.invoice"
invoices = self.env["account.invoice"].browse(self._context["active_ids"])
self._context["active_model"] == "account.move"
), "Active model should be account.move"
invoices = self.env["account.move"].browse(self._context["active_ids"])
action = invoices.create_account_payment_line()
return action

View File

@@ -11,29 +11,37 @@ class AccountPaymentLineCreate(models.TransientModel):
_name = "account.payment.line.create"
_description = "Wizard to create payment lines"
order_id = fields.Many2one("account.payment.order", string="Payment Order")
journal_ids = fields.Many2many("account.journal", string="Journals Filter")
order_id = fields.Many2one(
comodel_name="account.payment.order", string="Payment Order"
)
journal_ids = fields.Many2many(
comodel_name="account.journal", string="Journals Filter"
)
partner_ids = fields.Many2many(
"res.partner", string="Partners", domain=[("parent_id", "=", False)]
comodel_name="res.partner",
string="Partners",
domain=[("parent_id", "=", False)],
)
target_move = fields.Selection(
[("posted", "All Posted Entries"), ("all", "All Entries"),],
selection=[("posted", "All Posted Entries"), ("all", "All Entries")],
string="Target Moves",
)
allow_blocked = fields.Boolean(string="Allow Litigation Move Lines")
invoice = fields.Boolean(string="Linked to an Invoice or Refund")
date_type = fields.Selection(
[("due", "Due Date"), ("move", "Move Date"),],
selection=[("due", "Due Date"), ("move", "Move Date")],
string="Type of Date Filter",
required=True,
)
due_date = fields.Date(string="Due Date")
move_date = fields.Date(string="Move Date", default=fields.Date.context_today)
payment_mode = fields.Selection(
[("same", "Same"), ("same_or_null", "Same or Empty"), ("any", "Any"),],
selection=[("same", "Same"), ("same_or_null", "Same or Empty"), ("any", "Any")],
string="Payment Mode",
)
move_line_ids = fields.Many2many("account.move.line", string="Move Lines")
move_line_ids = fields.Many2many(
comodel_name="account.move.line", string="Move Lines"
)
@api.model
def default_get(self, field_list):
@@ -57,7 +65,6 @@ class AccountPaymentLineCreate(models.TransientModel):
)
return res
@api.multi
def _prepare_move_line_domain(self):
self.ensure_one()
domain = [
@@ -81,7 +88,13 @@ class AccountPaymentLineCreate(models.TransientModel):
elif self.date_type == "move":
domain.append(("date", "<=", self.move_date))
if self.invoice:
domain.append(("invoice_id", "!=", False))
domain.append(
(
"move_id.type",
"in",
("in_invoice", "out_invoice", "in_refund", "out_refund"),
)
)
if self.payment_mode:
if self.payment_mode == "same":
domain.append(
@@ -128,7 +141,6 @@ class AccountPaymentLineCreate(models.TransientModel):
domain += [("id", "not in", move_lines_ids)]
return domain
@api.multi
def populate(self):
domain = self._prepare_move_line_domain()
lines = self.env["account.move.line"].search(domain)
@@ -160,7 +172,6 @@ class AccountPaymentLineCreate(models.TransientModel):
res = {"domain": {"move_line_ids": domain}}
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)

View File

@@ -46,7 +46,11 @@
name="move_lines"
string="Selected Move Lines to Create Transactions"
>
<field name="move_line_ids" nolabel="1">
<field
name="move_line_ids"
nolabel="1"
context="{'tree_view_ref': 'account_payment_order.view_move_line_tree'}"
>
<tree>
<field name="date" />
<field name="move_id" required="0" />