mirror of
https://github.com/OCA/bank-payment.git
synced 2025-02-02 10:37:31 +02:00
@@ -7,7 +7,7 @@
|
||||
{
|
||||
"name": "Account Banking Mandate",
|
||||
"summary": "Banking mandates",
|
||||
"version": "14.0.1.1.0",
|
||||
"version": "14.0.1.1.1",
|
||||
"license": "AGPL-3",
|
||||
"author": "Compassion CH, "
|
||||
"Tecnativa, "
|
||||
|
||||
@@ -20,7 +20,7 @@ class ResPartnerBank(models.Model):
|
||||
@api.constrains("company_id")
|
||||
def _company_constrains(self):
|
||||
for rpb in self:
|
||||
if (
|
||||
if rpb.company_id and (
|
||||
self.env["account.banking.mandate"]
|
||||
.sudo()
|
||||
.search(
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
{
|
||||
"name": "Account Banking PAIN Base Module",
|
||||
"summary": "Base module for PAIN file generation",
|
||||
"version": "14.0.1.0.0",
|
||||
"version": "14.0.1.0.1",
|
||||
"license": "AGPL-3",
|
||||
"author": "Akretion, Noviat, Tecnativa, Odoo Community Association (OCA)",
|
||||
"website": "https://github.com/OCA/bank-payment",
|
||||
|
||||
@@ -58,17 +58,70 @@ class AccountPaymentOrder(models.Model):
|
||||
"transfer of the SEPA XML file.",
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _sepa_iban_prefix_list(self):
|
||||
# List of IBAN prefixes (not country codes !)
|
||||
# Source: https://www.europeanpaymentscouncil.eu/sites/default/files/kb/file/2020-10/EPC409-09%20EPC%20List%20of%20SEPA%20Scheme%20Countries%20v3.0_1.pdf # noqa: B950
|
||||
# Some countries use IBAN but are not part of the SEPA zone
|
||||
# example: Turkey, Madagascar, Tunisia, etc.
|
||||
return [
|
||||
"BE",
|
||||
"BG",
|
||||
"ES",
|
||||
"HR",
|
||||
"CY",
|
||||
"CZ",
|
||||
"DK",
|
||||
"EE",
|
||||
"FI",
|
||||
"FR",
|
||||
"DE",
|
||||
"GI",
|
||||
"GR",
|
||||
"GB",
|
||||
"HU",
|
||||
"IS",
|
||||
"IE",
|
||||
"IT",
|
||||
"LV",
|
||||
"LI",
|
||||
"LT",
|
||||
"LU",
|
||||
"PT",
|
||||
"MT",
|
||||
"MC",
|
||||
"NL",
|
||||
"NO",
|
||||
"PL",
|
||||
"RO",
|
||||
"SM",
|
||||
"SK",
|
||||
"SI",
|
||||
"SE",
|
||||
"CH",
|
||||
"VA",
|
||||
]
|
||||
|
||||
@api.depends(
|
||||
"company_partner_bank_id.acc_type",
|
||||
"company_partner_bank_id.sanitized_acc_number",
|
||||
"payment_line_ids.currency_id",
|
||||
"payment_line_ids.partner_bank_id.acc_type",
|
||||
"payment_line_ids.partner_bank_id.sanitized_acc_number",
|
||||
)
|
||||
def _compute_sepa(self):
|
||||
eur = self.env.ref("base.EUR")
|
||||
sepa_list = self._sepa_iban_prefix_list()
|
||||
for order in self:
|
||||
sepa = True
|
||||
if order.company_partner_bank_id.acc_type != "iban":
|
||||
sepa = False
|
||||
if (
|
||||
order.company_partner_bank_id
|
||||
and order.company_partner_bank_id.sanitized_acc_number[:2]
|
||||
not in sepa_list
|
||||
):
|
||||
sepa = False
|
||||
for pline in order.payment_line_ids:
|
||||
if pline.currency_id != eur:
|
||||
sepa = False
|
||||
@@ -76,6 +129,12 @@ class AccountPaymentOrder(models.Model):
|
||||
if pline.partner_bank_id.acc_type != "iban":
|
||||
sepa = False
|
||||
break
|
||||
if (
|
||||
pline.partner_bank_id
|
||||
and pline.partner_bank_id.sanitized_acc_number[:2] not in sepa_list
|
||||
):
|
||||
sepa = False
|
||||
break
|
||||
sepa = order.compute_sepa_final_hook(sepa)
|
||||
self.sepa = sepa
|
||||
|
||||
|
||||
@@ -20,4 +20,18 @@
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
<record id="account_payment_line_tree" model="ir.ui.view">
|
||||
<field name="name">pain.base.account.payment.tree</field>
|
||||
<field name="model">account.payment.line</field>
|
||||
<field
|
||||
name="inherit_id"
|
||||
ref="account_payment_order.account_payment_line_tree"
|
||||
/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="communication" position="after">
|
||||
<field name="priority" optional="hide" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -21,5 +21,19 @@
|
||||
/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
</record>
|
||||
<record id="account_payment_order_tree" model="ir.ui.view">
|
||||
<field name="name">pain.base.account.payment.order.tree</field>
|
||||
<field name="model">account.payment.order</field>
|
||||
<field
|
||||
name="inherit_id"
|
||||
ref="account_payment_order.account_payment_order_tree"
|
||||
/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="description" position="after">
|
||||
<field name="sepa" optional="hide" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -17,4 +17,15 @@
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
<record id="bank_payment_line_tree" model="ir.ui.view">
|
||||
<field name="name">pain.base.bank.payment.line.tree</field>
|
||||
<field name="model">bank.payment.line</field>
|
||||
<field name="inherit_id" ref="account_payment_order.bank_payment_line_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="communication" position="after">
|
||||
<field name="priority" optional="hide" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{
|
||||
"name": "Account Banking SEPA Credit Transfer",
|
||||
"summary": "Create SEPA XML files for Credit Transfers",
|
||||
"version": "14.0.1.0.0",
|
||||
"version": "14.0.1.0.1",
|
||||
"license": "AGPL-3",
|
||||
"author": "Akretion, " "Tecnativa, " "Odoo Community Association (OCA)",
|
||||
"website": "https://github.com/OCA/bank-payment",
|
||||
|
||||
@@ -10,7 +10,6 @@ from lxml import etree
|
||||
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tests.common import SavepointCase
|
||||
from odoo.tools import float_compare
|
||||
|
||||
|
||||
class TestSCT(SavepointCase):
|
||||
@@ -182,12 +181,11 @@ class TestSCT(SavepointCase):
|
||||
)
|
||||
self.assertEqual(len(pay_lines), 3)
|
||||
agrolait_pay_line1 = pay_lines[0]
|
||||
accpre = self.env["decimal.precision"].precision_get("Account")
|
||||
self.assertEqual(agrolait_pay_line1.currency_id, self.eur_currency)
|
||||
self.assertEqual(agrolait_pay_line1.partner_bank_id, invoice1.partner_bank_id)
|
||||
self.assertEqual(
|
||||
float_compare(
|
||||
agrolait_pay_line1.amount_currency, 42, precision_digits=accpre
|
||||
agrolait_pay_line1.currency_id.compare_amounts(
|
||||
agrolait_pay_line1.amount_currency, 42
|
||||
),
|
||||
0,
|
||||
)
|
||||
@@ -203,8 +201,8 @@ class TestSCT(SavepointCase):
|
||||
agrolait_bank_line = bank_lines[0]
|
||||
self.assertEqual(agrolait_bank_line.currency_id, self.eur_currency)
|
||||
self.assertEqual(
|
||||
float_compare(
|
||||
agrolait_bank_line.amount_currency, 49.0, precision_digits=accpre
|
||||
agrolait_bank_line.currency_id.compare_amounts(
|
||||
agrolait_bank_line.amount_currency, 49.0
|
||||
),
|
||||
0,
|
||||
)
|
||||
@@ -240,7 +238,7 @@ class TestSCT(SavepointCase):
|
||||
for inv in [invoice1, invoice2, invoice3, invoice4, invoice5]:
|
||||
self.assertEqual(inv.state, "posted")
|
||||
self.assertEqual(
|
||||
float_compare(inv.amount_residual, 0.0, precision_digits=accpre),
|
||||
inv.currency_id.compare_amounts(inv.amount_residual, 0.0),
|
||||
0,
|
||||
)
|
||||
return
|
||||
@@ -275,12 +273,11 @@ class TestSCT(SavepointCase):
|
||||
)
|
||||
self.assertEqual(len(pay_lines), 2)
|
||||
asus_pay_line1 = pay_lines[0]
|
||||
accpre = self.env["decimal.precision"].precision_get("Account")
|
||||
self.assertEqual(asus_pay_line1.currency_id, self.usd_currency)
|
||||
self.assertEqual(asus_pay_line1.partner_bank_id, invoice1.partner_bank_id)
|
||||
self.assertEqual(
|
||||
float_compare(
|
||||
asus_pay_line1.amount_currency, 2042, precision_digits=accpre
|
||||
asus_pay_line1.currency_id.compare_amounts(
|
||||
asus_pay_line1.amount_currency, 2042
|
||||
),
|
||||
0,
|
||||
)
|
||||
@@ -296,8 +293,8 @@ class TestSCT(SavepointCase):
|
||||
asus_bank_line = bank_lines[0]
|
||||
self.assertEqual(asus_bank_line.currency_id, self.usd_currency)
|
||||
self.assertEqual(
|
||||
float_compare(
|
||||
asus_bank_line.amount_currency, 3054.0, precision_digits=accpre
|
||||
asus_bank_line.currency_id.compare_amounts(
|
||||
asus_bank_line.amount_currency, 3054.0
|
||||
),
|
||||
0,
|
||||
)
|
||||
@@ -333,7 +330,7 @@ class TestSCT(SavepointCase):
|
||||
for inv in [invoice1, invoice2]:
|
||||
self.assertEqual(inv.state, "posted")
|
||||
self.assertEqual(
|
||||
float_compare(inv.amount_residual, 0.0, precision_digits=accpre),
|
||||
inv.currency_id.compare_amounts(inv.amount_residual, 0.0),
|
||||
0,
|
||||
)
|
||||
return
|
||||
@@ -349,7 +346,7 @@ class TestSCT(SavepointCase):
|
||||
move_type="in_invoice",
|
||||
):
|
||||
partner_bank = cls.env.ref(partner_bank_xmlid)
|
||||
partner_bank.write({"company_id": cls.main_company.id})
|
||||
partner_bank.write({"company_id": False})
|
||||
data = {
|
||||
"partner_id": partner_id,
|
||||
"reference_type": "none",
|
||||
@@ -359,6 +356,7 @@ class TestSCT(SavepointCase):
|
||||
"move_type": move_type,
|
||||
"payment_mode_id": cls.payment_mode.id,
|
||||
"partner_bank_id": partner_bank.id,
|
||||
"company_id": cls.main_company.id,
|
||||
"invoice_line_ids": [],
|
||||
}
|
||||
line_data = {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{
|
||||
"name": "Account Banking SEPA Direct Debit",
|
||||
"summary": "Create SEPA files for Direct Debit",
|
||||
"version": "14.0.1.1.0",
|
||||
"version": "14.0.1.1.1",
|
||||
"license": "AGPL-3",
|
||||
"author": "Akretion, " "Tecnativa, " "Odoo Community Association (OCA)",
|
||||
"website": "https://github.com/OCA/bank-payment",
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
/>
|
||||
<field
|
||||
name="print_report_name"
|
||||
>'Mandate-%s-%s' % (object.unique_mandate_reference, object.partner_id.name.replace(' ', '_'))</field>
|
||||
>'Mandate-%s-%s' % (object.unique_mandate_reference, object.partner_id and object.partner_id.name.replace(' ', '_') or '')</field>
|
||||
<field name="binding_model_id" ref="model_account_banking_mandate" />
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
{
|
||||
"name": "Account Payment Mode",
|
||||
"version": "14.0.1.0.1",
|
||||
"version": "14.0.1.0.2",
|
||||
"development_status": "Production/Stable",
|
||||
"license": "AGPL-3",
|
||||
"author": "Akretion,Odoo Community Association (OCA)",
|
||||
|
||||
@@ -40,7 +40,7 @@ class AccountPaymentMode(models.Model):
|
||||
fixed_journal_id = fields.Many2one(
|
||||
"account.journal",
|
||||
string="Fixed Bank Journal",
|
||||
domain=[("type", "=", "bank")],
|
||||
domain="[('company_id', '=', company_id), ('type', 'in', ('bank', 'cash'))]",
|
||||
ondelete="restrict",
|
||||
check_company=True,
|
||||
)
|
||||
@@ -52,6 +52,7 @@ class AccountPaymentMode(models.Model):
|
||||
column1="payment_mode_id",
|
||||
column2="journal_id",
|
||||
string="Allowed Bank Journals",
|
||||
domain="[('company_id', '=', company_id), ('type', 'in', ('bank', 'cash'))]",
|
||||
)
|
||||
payment_method_id = fields.Many2one(
|
||||
"account.payment.method",
|
||||
|
||||
@@ -22,12 +22,10 @@
|
||||
<field
|
||||
name="fixed_journal_id"
|
||||
attrs="{'invisible': [('bank_account_link', '!=', 'fixed')], 'required': [('bank_account_link', '=', 'fixed')]}"
|
||||
domain="[('company_id', '=', company_id), ('type', '=', 'bank')]"
|
||||
/>
|
||||
<field
|
||||
name="variable_journal_ids"
|
||||
attrs="{'invisible': [('bank_account_link', '!=', 'variable')], 'required': [('bank_account_link', '=', 'variable')]}"
|
||||
domain="[('company_id', '=', company_id), ('type', '=', 'bank')]"
|
||||
widget="many2many_tags"
|
||||
/>
|
||||
</group>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
{
|
||||
"name": "Account Payment Order",
|
||||
"version": "14.0.1.2.4",
|
||||
"version": "14.0.1.3.0",
|
||||
"license": "AGPL-3",
|
||||
"author": "ACSONE SA/NV, "
|
||||
"Therp BV, "
|
||||
|
||||
10
account_payment_order/migrations/14.0.1.3.0/pre-migration.py
Normal file
10
account_payment_order/migrations/14.0.1.3.0/pre-migration.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# Copyright 2021 Akretion France (http://www.akretion.com/)
|
||||
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
|
||||
def migrate(cr, version):
|
||||
if not version:
|
||||
return
|
||||
|
||||
cr.execute("UPDATE account_payment_order SET state='uploaded' WHERE state='done'")
|
||||
@@ -24,7 +24,6 @@ class AccountMove(models.Model):
|
||||
reference_type = fields.Selection(
|
||||
selection=[("none", "Free Reference"), ("structured", "Structured Reference")],
|
||||
string="Reference Type",
|
||||
required=True,
|
||||
readonly=True,
|
||||
states={"draft": [("readonly", False)]},
|
||||
default="none",
|
||||
|
||||
@@ -68,7 +68,7 @@ class AccountPaymentLine(models.Model):
|
||||
)
|
||||
date = fields.Date(string="Payment Date")
|
||||
communication = fields.Char(
|
||||
required=True, help="Label of the payment that will be seen by the destinee"
|
||||
required=False, help="Label of the payment that will be seen by the destinee"
|
||||
)
|
||||
communication_type = fields.Selection(
|
||||
selection=[("normal", "Free")], required=True, default="normal"
|
||||
@@ -162,3 +162,5 @@ class AccountPaymentLine(models.Model):
|
||||
raise UserError(
|
||||
_("Missing Partner Bank Account on payment line %s") % self.name
|
||||
)
|
||||
if not self.communication:
|
||||
raise UserError(_("Communication is empty on payment line %s.") % self.name)
|
||||
|
||||
@@ -75,27 +75,6 @@ class AccountPaymentMode(models.Model):
|
||||
generate_move = fields.Boolean(
|
||||
string="Generate Accounting Entries On File Upload", default=True
|
||||
)
|
||||
offsetting_account = fields.Selection(
|
||||
selection=[
|
||||
("bank_account", "Bank Account"),
|
||||
("transfer_account", "Transfer Account"),
|
||||
],
|
||||
default="bank_account",
|
||||
)
|
||||
transfer_account_id = fields.Many2one(
|
||||
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",
|
||||
check_company=True,
|
||||
)
|
||||
transfer_journal_id = fields.Many2one(
|
||||
comodel_name="account.journal",
|
||||
help="Journal to write payment entries when confirming "
|
||||
"payment/debit orders of this mode",
|
||||
check_company=True,
|
||||
)
|
||||
move_option = fields.Selection(
|
||||
selection=[
|
||||
("date", "One move per payment date"),
|
||||
@@ -105,50 +84,17 @@ class AccountPaymentMode(models.Model):
|
||||
)
|
||||
post_move = fields.Boolean(default=True)
|
||||
|
||||
@api.constrains(
|
||||
"generate_move",
|
||||
"offsetting_account",
|
||||
"transfer_account_id",
|
||||
"transfer_journal_id",
|
||||
"move_option",
|
||||
)
|
||||
@api.constrains("generate_move", "move_option")
|
||||
def transfer_move_constrains(self):
|
||||
for mode in self:
|
||||
if mode.generate_move:
|
||||
if not mode.offsetting_account:
|
||||
raise ValidationError(
|
||||
_(
|
||||
"On the payment mode '%s', you must select an "
|
||||
"option for the 'Offsetting Account' parameter"
|
||||
)
|
||||
% mode.name
|
||||
)
|
||||
elif mode.offsetting_account == "transfer_account":
|
||||
if not mode.transfer_account_id:
|
||||
raise ValidationError(
|
||||
_(
|
||||
"On the payment mode '%s', you must "
|
||||
"select a value for the 'Transfer Account'."
|
||||
)
|
||||
% mode.name
|
||||
)
|
||||
if not mode.transfer_journal_id:
|
||||
raise ValidationError(
|
||||
_(
|
||||
"On the payment mode '%s', you must "
|
||||
"select a value for the 'Transfer Journal'."
|
||||
)
|
||||
% mode.name
|
||||
)
|
||||
if not mode.move_option:
|
||||
raise ValidationError(
|
||||
_(
|
||||
"On the payment mode '%s', you must "
|
||||
"choose an option for the 'Move Option' "
|
||||
"parameter."
|
||||
)
|
||||
% mode.name
|
||||
if mode.generate_move and not mode.move_option:
|
||||
raise ValidationError(
|
||||
_(
|
||||
"On the payment mode '%s', you must "
|
||||
"choose an option for the 'Move Option' parameter."
|
||||
)
|
||||
% mode.name
|
||||
)
|
||||
|
||||
@api.onchange("payment_method_id")
|
||||
def payment_method_id_change(self):
|
||||
@@ -175,16 +121,6 @@ class AccountPaymentMode(models.Model):
|
||||
def generate_move_change(self):
|
||||
if self.generate_move:
|
||||
# default values
|
||||
self.offsetting_account = "bank_account"
|
||||
self.move_option = "date"
|
||||
else:
|
||||
self.offsetting_account = False
|
||||
self.transfer_account_id = False
|
||||
self.transfer_journal_id = False
|
||||
self.move_option = False
|
||||
|
||||
@api.onchange("offsetting_account")
|
||||
def offsetting_account_change(self):
|
||||
if self.offsetting_account == "bank_account":
|
||||
self.transfer_account_id = False
|
||||
self.transfer_journal_id = False
|
||||
|
||||
@@ -23,6 +23,7 @@ class AccountPaymentOrder(models.Model):
|
||||
required=True,
|
||||
ondelete="restrict",
|
||||
tracking=True,
|
||||
readonly=True,
|
||||
states={"draft": [("readonly", False)]},
|
||||
check_company=True,
|
||||
)
|
||||
@@ -74,7 +75,6 @@ class AccountPaymentOrder(models.Model):
|
||||
("open", "Confirmed"),
|
||||
("generated", "File Generated"),
|
||||
("uploaded", "File Uploaded"),
|
||||
("done", "Done"),
|
||||
("cancel", "Cancel"),
|
||||
],
|
||||
string="Status",
|
||||
@@ -106,7 +106,6 @@ class AccountPaymentOrder(models.Model):
|
||||
)
|
||||
date_generated = fields.Date(string="File Generation Date", readonly=True)
|
||||
date_uploaded = fields.Date(string="File Upload Date", readonly=True)
|
||||
date_done = fields.Date(string="Done Date", readonly=True)
|
||||
generated_user_id = fields.Many2one(
|
||||
comodel_name="res.users",
|
||||
string="Generated by",
|
||||
@@ -118,14 +117,14 @@ class AccountPaymentOrder(models.Model):
|
||||
payment_line_ids = fields.One2many(
|
||||
comodel_name="account.payment.line",
|
||||
inverse_name="order_id",
|
||||
string="Transaction Lines",
|
||||
string="Transactions",
|
||||
readonly=True,
|
||||
states={"draft": [("readonly", False)]},
|
||||
)
|
||||
bank_line_ids = fields.One2many(
|
||||
comodel_name="bank.payment.line",
|
||||
inverse_name="order_id",
|
||||
string="Bank Payment Lines",
|
||||
string="Bank Transactions",
|
||||
readonly=True,
|
||||
help="The bank payment lines are used to generate the payment file. "
|
||||
"They are automatically created from transaction lines upon "
|
||||
@@ -138,7 +137,7 @@ class AccountPaymentOrder(models.Model):
|
||||
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"
|
||||
compute="_compute_bank_line_count", string="Number of Bank Transactions"
|
||||
)
|
||||
move_ids = fields.One2many(
|
||||
comodel_name="account.move",
|
||||
@@ -146,6 +145,9 @@ class AccountPaymentOrder(models.Model):
|
||||
string="Journal Entries",
|
||||
readonly=True,
|
||||
)
|
||||
move_count = fields.Integer(
|
||||
compute="_compute_move_count", string="Number of Journal Entries"
|
||||
)
|
||||
description = fields.Char()
|
||||
|
||||
@api.depends("payment_mode_id")
|
||||
@@ -210,6 +212,19 @@ class AccountPaymentOrder(models.Model):
|
||||
for order in self:
|
||||
order.bank_line_count = len(order.bank_line_ids)
|
||||
|
||||
@api.depends("move_ids")
|
||||
def _compute_move_count(self):
|
||||
rg_res = self.env["account.move"].read_group(
|
||||
[("payment_order_id", "in", self.ids)],
|
||||
["payment_order_id"],
|
||||
["payment_order_id"],
|
||||
)
|
||||
mapped_data = {
|
||||
x["payment_order_id"][0]: x["payment_order_id_count"] for x in rg_res
|
||||
}
|
||||
for order in self:
|
||||
order.move_count = mapped_data.get(order.id, 0)
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
if vals.get("name", "New") == "New":
|
||||
@@ -234,11 +249,7 @@ class AccountPaymentOrder(models.Model):
|
||||
if self.payment_mode_id.default_date_prefered:
|
||||
self.date_prefered = self.payment_mode_id.default_date_prefered
|
||||
|
||||
def action_done(self):
|
||||
self.write({"date_done": fields.Date.context_today(self), "state": "done"})
|
||||
return True
|
||||
|
||||
def action_done_cancel(self):
|
||||
def action_uploaded_cancel(self):
|
||||
for move in self.move_ids:
|
||||
move.button_cancel()
|
||||
for move_line in move.line_ids:
|
||||
@@ -420,27 +431,19 @@ class AccountPaymentOrder(models.Model):
|
||||
return True
|
||||
|
||||
def _prepare_move(self, bank_lines=None):
|
||||
move_date = False
|
||||
if self.payment_type == "outbound":
|
||||
ref = _("Payment order %s") % self.name
|
||||
else:
|
||||
ref = _("Debit order %s") % self.name
|
||||
if bank_lines and len(bank_lines) == 1:
|
||||
ref += " - " + bank_lines.name
|
||||
if self.payment_mode_id.offsetting_account == "bank_account":
|
||||
journal_id = self.journal_id.id
|
||||
if bank_lines:
|
||||
move_date = bank_lines[0].date
|
||||
elif self.payment_mode_id.offsetting_account == "transfer_account":
|
||||
journal_id = self.payment_mode_id.transfer_journal_id.id
|
||||
vals = {
|
||||
"journal_id": journal_id,
|
||||
"date": bank_lines[0].date,
|
||||
"journal_id": self.journal_id.id,
|
||||
"ref": ref,
|
||||
"payment_order_id": self.id,
|
||||
"line_ids": [],
|
||||
}
|
||||
if move_date:
|
||||
vals.update({"date": move_date})
|
||||
total_company_currency = total_payment_currency = 0
|
||||
for bline in bank_lines:
|
||||
total_company_currency += bline.amount_company_currency
|
||||
@@ -458,18 +461,10 @@ class AccountPaymentOrder(models.Model):
|
||||
):
|
||||
vals = {}
|
||||
if self.payment_type == "outbound":
|
||||
name = _("Payment order %s") % self.name
|
||||
account_id = self.journal_id.payment_credit_account_id.id
|
||||
else:
|
||||
name = _("Debit order %s") % self.name
|
||||
if self.payment_mode_id.offsetting_account == "bank_account":
|
||||
vals.update({"date": bank_lines[0].date})
|
||||
else:
|
||||
vals.update({"date_maturity": bank_lines[0].date})
|
||||
account_id = self.journal_id.payment_debit_account_id.id
|
||||
|
||||
if self.payment_mode_id.offsetting_account == "bank_account":
|
||||
account_id = self.journal_id.default_account_id.id
|
||||
elif self.payment_mode_id.offsetting_account == "transfer_account":
|
||||
account_id = self.payment_mode_id.transfer_account_id.id
|
||||
partner_id = False
|
||||
for index, bank_line in enumerate(bank_lines):
|
||||
if index == 0:
|
||||
@@ -480,7 +475,6 @@ class AccountPaymentOrder(models.Model):
|
||||
break
|
||||
vals.update(
|
||||
{
|
||||
"name": name,
|
||||
"partner_id": partner_id,
|
||||
"account_id": account_id,
|
||||
"credit": (
|
||||
@@ -586,10 +580,19 @@ class AccountPaymentOrder(models.Model):
|
||||
|
||||
def action_move_journal_line(self):
|
||||
self.ensure_one()
|
||||
action = self.env.ref("account.action_move_journal_line")
|
||||
action_dict = action.read()[0]
|
||||
action_dict["domain"] = [("id", "in", self.move_ids.ids)]
|
||||
action = self.env.ref("account.action_move_journal_line").sudo().read()[0]
|
||||
if self.move_count == 1:
|
||||
action.update(
|
||||
{
|
||||
"view_mode": "form,tree,kanban",
|
||||
"views": False,
|
||||
"view_id": False,
|
||||
"res_id": self.move_ids[0].id,
|
||||
}
|
||||
)
|
||||
else:
|
||||
action["domain"] = [("id", "in", self.move_ids.ids)]
|
||||
ctx = self.env.context.copy()
|
||||
ctx.update({"search_default_misc_filter": 0})
|
||||
action_dict["context"] = ctx
|
||||
return action_dict
|
||||
action["context"] = ctx
|
||||
return action
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# © 2017 Creu Blanca
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
@@ -48,37 +47,6 @@ class TestPaymentMode(TransactionCase):
|
||||
}
|
||||
)
|
||||
|
||||
def test_constrains(self):
|
||||
with self.assertRaises(ValidationError):
|
||||
self.payment_mode_c1.write(
|
||||
{"generate_move": True, "offsetting_account": False}
|
||||
)
|
||||
with self.assertRaises(ValidationError):
|
||||
self.payment_mode_c1.write(
|
||||
{
|
||||
"generate_move": True,
|
||||
"offsetting_account": "bank_account",
|
||||
"move_option": False,
|
||||
}
|
||||
)
|
||||
with self.assertRaises(ValidationError):
|
||||
self.payment_mode_c1.write(
|
||||
{
|
||||
"generate_move": True,
|
||||
"offsetting_account": "transfer_account",
|
||||
"transfer_account_id": False,
|
||||
}
|
||||
)
|
||||
with self.assertRaises(ValidationError):
|
||||
self.payment_mode_c1.write(
|
||||
{
|
||||
"generate_move": True,
|
||||
"offsetting_account": "transfer_account",
|
||||
"transfer_account_id": self.account.id,
|
||||
"transfer_journal_id": False,
|
||||
}
|
||||
)
|
||||
|
||||
def test_onchange_generate_move(self):
|
||||
self.payment_mode_c1.generate_move = True
|
||||
self.payment_mode_c1.generate_move_change()
|
||||
@@ -87,11 +55,6 @@ class TestPaymentMode(TransactionCase):
|
||||
self.payment_mode_c1.generate_move_change()
|
||||
self.assertFalse(self.payment_mode_c1.move_option)
|
||||
|
||||
def test_onchange_offsetting_account(self):
|
||||
self.payment_mode_c1.offsetting_account = "bank_account"
|
||||
self.payment_mode_c1.offsetting_account_change()
|
||||
self.assertFalse(self.payment_mode_c1.transfer_account_id)
|
||||
|
||||
def test_onchange_payment_type(self):
|
||||
self.payment_mode_c1.payment_method_id = self.manual_in
|
||||
self.payment_mode_c1.payment_method_id_change()
|
||||
|
||||
@@ -115,7 +115,7 @@ class TestPaymentOrderInbound(TestPaymentOrderInboundBase):
|
||||
|
||||
with self.assertRaises(UserError):
|
||||
bank_line.unlink()
|
||||
payment_order.action_done_cancel()
|
||||
payment_order.action_uploaded_cancel()
|
||||
self.assertEqual(payment_order.state, "cancel")
|
||||
payment_order.cancel2draft()
|
||||
payment_order.unlink()
|
||||
|
||||
@@ -48,8 +48,8 @@ class TestPaymentOrderOutbound(AccountTestInvoicingCommon):
|
||||
).id,
|
||||
}
|
||||
)
|
||||
cls.invoice = cls._create_supplier_invoice(cls)
|
||||
cls.invoice_02 = cls._create_supplier_invoice(cls)
|
||||
cls.invoice = cls._create_supplier_invoice(cls, "F1242")
|
||||
cls.invoice_02 = cls._create_supplier_invoice(cls, "F1243")
|
||||
cls.bank_journal = cls.company_data["default_journal_bank"]
|
||||
# Make sure no other payment orders are in the DB
|
||||
cls.domain = [
|
||||
@@ -59,11 +59,12 @@ class TestPaymentOrderOutbound(AccountTestInvoicingCommon):
|
||||
]
|
||||
cls.env["account.payment.order"].search(cls.domain).unlink()
|
||||
|
||||
def _create_supplier_invoice(self):
|
||||
def _create_supplier_invoice(self, ref):
|
||||
invoice = self.env["account.move"].create(
|
||||
{
|
||||
"partner_id": self.partner.id,
|
||||
"move_type": "in_invoice",
|
||||
"ref": ref,
|
||||
"payment_mode_id": self.mode.id,
|
||||
"invoice_date": fields.Date.today(),
|
||||
"invoice_line_ids": [
|
||||
@@ -157,8 +158,7 @@ class TestPaymentOrderOutbound(AccountTestInvoicingCommon):
|
||||
order.open2generated()
|
||||
order.generated2uploaded()
|
||||
self.assertEqual(order.move_ids[0].date, order.bank_line_ids[0].date)
|
||||
order.action_done()
|
||||
self.assertEqual(order.state, "done")
|
||||
self.assertEqual(order.state, "uploaded")
|
||||
|
||||
def test_cancel_payment_order(self):
|
||||
# Open invoice
|
||||
@@ -193,7 +193,7 @@ class TestPaymentOrderOutbound(AccountTestInvoicingCommon):
|
||||
|
||||
with self.assertRaises(UserError):
|
||||
bank_line.unlink()
|
||||
payment_order.action_done_cancel()
|
||||
payment_order.action_uploaded_cancel()
|
||||
self.assertEqual(payment_order.state, "cancel")
|
||||
payment_order.cancel2draft()
|
||||
payment_order.unlink()
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<field name="payment_mode_id" position="after">
|
||||
<field name="payment_order_ok" invisible="1" />
|
||||
</field>
|
||||
<field name="ref" position="after">
|
||||
<field name="payment_reference" position="before">
|
||||
<field
|
||||
name="reference_type"
|
||||
required="1"
|
||||
@@ -51,7 +51,7 @@
|
||||
/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
</record>
|
||||
<record
|
||||
id="account_invoice_create_account_payment_line_action"
|
||||
model="ir.actions.act_window"
|
||||
@@ -62,4 +62,21 @@
|
||||
<field name="target">new</field>
|
||||
<field name="binding_model_id" ref="account.model_account_move" />
|
||||
</record>
|
||||
|
||||
<record id="view_invoice_tree" model="ir.ui.view">
|
||||
<field name="name">account_payment_order.view_invoice_tree</field>
|
||||
<field name="model">account.move</field>
|
||||
<field name="inherit_id" ref="account.view_invoice_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<button name="action_register_payment" position="after">
|
||||
<button
|
||||
name="%(account_invoice_create_account_payment_line_action)d"
|
||||
type="action"
|
||||
string="Add to Payment/Debit Order"
|
||||
groups="account_payment_order.group_account_payment"
|
||||
invisible="context.get('default_move_type') not in ('out_invoice', 'out_refund', 'in_invoice', 'in_refund')"
|
||||
/>
|
||||
</button>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -59,12 +59,12 @@
|
||||
<field name="partner_id" />
|
||||
<field name="communication" />
|
||||
<field name="partner_bank_id" />
|
||||
<field name="move_line_id" invisible="1" />
|
||||
<field name="ml_maturity_date" />
|
||||
<field name="move_line_id" optional="hide" />
|
||||
<field name="ml_maturity_date" optional="show" />
|
||||
<field name="date" />
|
||||
<field name="amount_currency" string="Amount" />
|
||||
<field name="currency_id" />
|
||||
<field name="name" />
|
||||
<field name="currency_id" invisible="1" />
|
||||
<field name="name" optional="show" />
|
||||
<field
|
||||
name="amount_company_currency"
|
||||
sum="Total in Company Currency"
|
||||
|
||||
@@ -38,21 +38,6 @@
|
||||
attrs="{'invisible': [('payment_order_ok', '=', False)]}"
|
||||
>
|
||||
<field name="generate_move" />
|
||||
<field
|
||||
name="offsetting_account"
|
||||
widget="radio"
|
||||
attrs="{'required': [('generate_move', '=', True)], 'invisible': [('generate_move', '=', False)]}"
|
||||
/>
|
||||
<field
|
||||
name="transfer_account_id"
|
||||
attrs="{'invisible': [('offsetting_account', '!=', 'transfer_account')], 'required': [('offsetting_account', '=', 'transfer_account')]}"
|
||||
context="{'default_reconcile': True, 'default_company_id': company_id}"
|
||||
/>
|
||||
<!-- We can't put a default vue to user_type_id... -->
|
||||
<field
|
||||
name="transfer_journal_id"
|
||||
attrs="{'invisible': [('offsetting_account', '!=', 'transfer_account')], 'required': [('offsetting_account', '=', 'transfer_account')]}"
|
||||
/>
|
||||
<field
|
||||
name="move_option"
|
||||
attrs="{'invisible': [('generate_move', '=', False)], 'required': [('generate_move', '=', True)]}"
|
||||
|
||||
@@ -47,29 +47,31 @@
|
||||
string="Cancel Payments"
|
||||
/>
|
||||
<button
|
||||
name="action_done_cancel"
|
||||
name="action_uploaded_cancel"
|
||||
type="object"
|
||||
states="uploaded"
|
||||
string="Cancel Payments"
|
||||
/>
|
||||
<field name="state" widget="statusbar" />
|
||||
<field
|
||||
name="state"
|
||||
widget="statusbar"
|
||||
statusbar_visible="draft,open,generated,uploaded"
|
||||
/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button
|
||||
class="oe_stat_button"
|
||||
name="action_bank_payment_line"
|
||||
string="Bank Payment Lines"
|
||||
type="object"
|
||||
icon="fa-bars"
|
||||
/>
|
||||
<button
|
||||
class="oe_stat_button"
|
||||
name="action_move_journal_line"
|
||||
string="Transfer Journal Entries"
|
||||
type="object"
|
||||
icon="fa-bars"
|
||||
/>
|
||||
>
|
||||
<field
|
||||
string="Journal Entries"
|
||||
name="move_count"
|
||||
widget="statinfo"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only" />
|
||||
@@ -82,12 +84,10 @@
|
||||
<field
|
||||
name="payment_mode_id"
|
||||
domain="[('payment_order_ok', '=', True), ('payment_type', '=', payment_type)]"
|
||||
widget="selection"
|
||||
/>
|
||||
<field name="allowed_journal_ids" invisible="1" />
|
||||
<field
|
||||
name="journal_id"
|
||||
widget="selection"
|
||||
domain="[('id', 'in', allowed_journal_ids)]"
|
||||
/>
|
||||
<field name="bank_account_link" invisible="1" />
|
||||
@@ -97,7 +97,10 @@
|
||||
groups="base.group_multi_company"
|
||||
/>
|
||||
<field name="payment_type" invisible="0" />
|
||||
<field name="bank_line_count" />
|
||||
<field
|
||||
name="bank_line_count"
|
||||
attrs="{'invisible': [('state', 'in', ('draft', 'cancel'))]}"
|
||||
/>
|
||||
</group>
|
||||
<group name="head-right">
|
||||
<field name="date_prefered" />
|
||||
@@ -118,6 +121,13 @@
|
||||
context="{'default_payment_type': payment_type}"
|
||||
/>
|
||||
</page>
|
||||
<page
|
||||
name="bank-lines"
|
||||
string="Bank Transactions"
|
||||
attrs="{'invisible': [('state', 'in', ('draft', 'cancel'))]}"
|
||||
>
|
||||
<field name="bank_line_ids" edit="0" create="0" />
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
@@ -131,22 +141,29 @@
|
||||
<field name="name">account.payment.order.tree</field>
|
||||
<field name="model">account.payment.order</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree
|
||||
string="Payment Orders"
|
||||
decoration-info="state=='draft'"
|
||||
decoration-success="state=='generated'"
|
||||
decoration-danger="state=='open'"
|
||||
decoration-muted="state=='cancel'"
|
||||
>
|
||||
<field name="name" />
|
||||
<tree string="Payment Orders">
|
||||
<field name="name" decoration-bf="1" />
|
||||
<field name="payment_mode_id" />
|
||||
<field name="journal_id" />
|
||||
<field name="company_id" groups="base.group_multi_company" />
|
||||
<field name="date_uploaded" />
|
||||
<field name="description" />
|
||||
<field name="description" optional="show" />
|
||||
<field
|
||||
name="bank_line_count"
|
||||
optional="hide"
|
||||
string="Bank Transactions"
|
||||
/>
|
||||
<field name="total_company_currency" sum="Total Company Currency" />
|
||||
<field name="company_currency_id" invisible="1" />
|
||||
<field name="state" />
|
||||
<field
|
||||
name="state"
|
||||
decoration-info="state == 'draft'"
|
||||
decoration-success="state == 'uploaded'"
|
||||
decoration-warning="state == 'open'"
|
||||
decoration-danger="state == 'generated'"
|
||||
decoration-muted="state == 'cancel'"
|
||||
widget="badge"
|
||||
/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -49,8 +49,8 @@
|
||||
<field name="partner_bank_id" />
|
||||
<field name="date" />
|
||||
<field name="amount_currency" sum="Total Amount" />
|
||||
<field name="currency_id" />
|
||||
<field name="name" />
|
||||
<field name="currency_id" invisible="1" />
|
||||
<field name="name" optional="show" />
|
||||
<field
|
||||
name="company_id"
|
||||
groups="base.group_multi_company"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
{
|
||||
"name": "Account Payment Partner",
|
||||
"version": "14.0.1.3.1",
|
||||
"version": "14.0.1.3.2",
|
||||
"category": "Banking addons",
|
||||
"license": "AGPL-3",
|
||||
"summary": "Adds payment mode on partners and invoices",
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
<field name="inherit_id" ref="account.view_invoice_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="amount_residual_signed" position="after">
|
||||
<field name="payment_mode_id" />
|
||||
<field name="payment_mode_id" optional="hide" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
Reference in New Issue
Block a user