From ee3c27b747f00ad0761c869449998d6ed4c28d78 Mon Sep 17 00:00:00 2001 From: Jordi Ballester Date: Fri, 27 Oct 2017 19:04:05 +0200 Subject: [PATCH] When the user looks for open payables or receivables, in the context of payment orders, she should ocus on the amount that is due to be paid. 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. --- account_payment_order/README.rst | 6 +- account_payment_order/__init__.py | 1 - account_payment_order/__manifest__.py | 1 - account_payment_order/models/__init__.py | 2 - .../models/account_invoice.py | 5 +- account_payment_order/models/account_move.py | 1 - .../models/account_move_line.py | 57 +++++++- .../models/account_payment_line.py | 1 - .../models/account_payment_mode.py | 1 - .../models/account_payment_order.py | 16 ++- .../models/bank_payment_line.py | 6 +- account_payment_order/models/res_bank.py | 1 - .../report/account_payment_order.py | 1 - account_payment_order/tests/__init__.py | 7 +- account_payment_order/tests/test_bank.py | 3 +- .../tests/test_payment_mode.py | 41 +++++- .../tests/test_payment_order_inbound.py | 111 ++++++++++++++++ ...rder.py => test_payment_order_outbound.py} | 123 +++++++++++++----- .../views/account_payment_line.xml | 2 + .../views/bank_payment_line.xml | 4 +- .../wizard/account_payment_line_create.py | 10 +- setup/account_payment_order/odoo/__init__.py | 1 + .../odoo/addons/__init__.py | 1 + .../odoo/addons/account_payment_order | 1 + setup/account_payment_order/setup.cfg | 2 + setup/account_payment_order/setup.py | 6 + 26 files changed, 332 insertions(+), 79 deletions(-) create mode 100644 account_payment_order/tests/test_payment_order_inbound.py rename account_payment_order/tests/{test_payment_order.py => test_payment_order_outbound.py} (53%) create mode 100644 setup/account_payment_order/odoo/__init__.py create mode 100644 setup/account_payment_order/odoo/addons/__init__.py create mode 120000 setup/account_payment_order/odoo/addons/account_payment_order create mode 100644 setup/account_payment_order/setup.cfg create mode 100644 setup/account_payment_order/setup.py diff --git a/account_payment_order/README.rst b/account_payment_order/README.rst index 46ba8bdf2..f257e59a3 100644 --- a/account_payment_order/README.rst +++ b/account_payment_order/README.rst @@ -26,13 +26,13 @@ This module adds several options on Payment Modes, cf Invoicing/Accounting > Con Usage ===== -You can create a Payment Order via the menu Invoicing/Accounting > Payments > Payment Orders and then select the move lines to pay. +You can create a Payment order via the menu Invoicing/Accounting > Payments > Payment Orders and then select the move lines to pay. -You can create a Debit Order via the menu Invoicing/Accounting > Payments > Debit Orders and then select the move lines to debit. +You can create a Debit order via the menu Invoicing/Accounting > Payments > Debit Orders and then select the move lines to debit. This module also adds a button *Add to Payment Order* on supplier invoices and a button *Add to Debit Order* on customer invoices. -You can print a Payment Order via the menu Invoicing/Accounting > Payments > Payment Orders and then select the payment oder to print. +You can print a Payment order via the menu Invoicing/Accounting > Payments > Payment Orders and then select the payment oder to print. .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas :alt: Try me on Runbot diff --git a/account_payment_order/__init__.py b/account_payment_order/__init__.py index fc07b7248..7660e7bf6 100644 --- a/account_payment_order/__init__.py +++ b/account_payment_order/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from . import models from . import report from . import wizard diff --git a/account_payment_order/__manifest__.py b/account_payment_order/__manifest__.py index 3d1f71838..4ee9b7efb 100644 --- a/account_payment_order/__manifest__.py +++ b/account_payment_order/__manifest__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # © 2009 EduSense BV () # © 2011-2013 Therp BV () # © 2013-2014 ACSONE SA (). diff --git a/account_payment_order/models/__init__.py b/account_payment_order/models/__init__.py index 650494570..9430fe91a 100644 --- a/account_payment_order/models/__init__.py +++ b/account_payment_order/models/__init__.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - from . import account_payment_mode from . import account_payment_order from . import account_payment_line diff --git a/account_payment_order/models/account_invoice.py b/account_payment_order/models/account_invoice.py index 63b94628e..3857ddf93 100644 --- a/account_payment_order/models/account_invoice.py +++ b/account_payment_order/models/account_invoice.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # © 2013-2014 ACSONE SA (). # © 2014 Serv. Tecnol. Avanzados - Pedro M. Baeza # © 2016 Akretion (Alexis de Lattre ) @@ -57,7 +56,9 @@ class AccountInvoice(models.Model): if not inv.payment_order_ok: raise UserError(_( "The invoice %s has a payment mode '%s' " - "which is not selectable in payment orders.")) + "which is not selectable in payment orders." % ( + inv.number, inv.payment_mode_id.display_name)) + ) payorders = apoo.search([ ('payment_mode_id', '=', inv.payment_mode_id.id), ('state', '=', 'draft')]) diff --git a/account_payment_order/models/account_move.py b/account_payment_order/models/account_move.py index 2348b379c..f82073e68 100644 --- a/account_payment_order/models/account_move.py +++ b/account_payment_order/models/account_move.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # © 2016 Akretion (Alexis de Lattre ) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). diff --git a/account_payment_order/models/account_move_line.py b/account_payment_order/models/account_move_line.py index 2d7be343a..21e9b833d 100644 --- a/account_payment_order/models/account_move_line.py +++ b/account_payment_order/models/account_move_line.py @@ -1,9 +1,10 @@ -# -*- coding: utf-8 -*- # © 2014-2016 Akretion (Alexis de Lattre ) # © 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 models, fields, api +from odoo.osv import orm class AccountMoveLine(models.Model): @@ -73,3 +74,57 @@ class AccountMoveLine(models.Model): for mline in self: aplo.create(mline._prepare_payment_line_vals(payment_order)) return + + @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 diff --git a/account_payment_order/models/account_payment_line.py b/account_payment_order/models/account_payment_line.py index f47d3ce15..eddfacb5d 100644 --- a/account_payment_order/models/account_payment_line.py +++ b/account_payment_order/models/account_payment_line.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # © 2015-2016 Akretion - Alexis de Lattre # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). diff --git a/account_payment_order/models/account_payment_mode.py b/account_payment_order/models/account_payment_mode.py index ece9d2d71..47d983a27 100644 --- a/account_payment_order/models/account_payment_mode.py +++ b/account_payment_order/models/account_payment_mode.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # © 2009 EduSense BV () # © 2011-2013 Therp BV () # © 2014-2016 Serv. Tecnol. Avanzados - Pedro M. Baeza diff --git a/account_payment_order/models/account_payment_order.py b/account_payment_order/models/account_payment_order.py index 5bafd4f5c..a7dec8a96 100644 --- a/account_payment_order/models/account_payment_order.py +++ b/account_payment_order/models/account_payment_order.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # © 2009 EduSense BV () # © 2011-2013 Therp BV () # © 2016 Serv. Tecnol. Avanzados - Pedro M. Baeza @@ -55,12 +54,14 @@ class AccountPaymentOrder(models.Model): company_partner_bank_id = fields.Many2one( related='journal_id.bank_account_id', string='Company Bank Account', readonly=True) - state = fields.Selection([ - ('draft', 'Draft'), - ('open', 'Confirmed'), - ('generated', 'File Generated'), - ('uploaded', 'File Uploaded'), - ('cancel', 'Cancel'), + state = fields.Selection( + [ + ('draft', 'Draft'), + ('open', 'Confirmed'), + ('generated', 'File Generated'), + ('uploaded', 'File Uploaded'), + ('done', 'Done'), + ('cancel', 'Cancel'), ], string='Status', readonly=True, copy=False, default='draft', track_visibility='onchange') date_prefered = fields.Selection([ @@ -77,6 +78,7 @@ class AccountPaymentOrder(models.Model): "as the Payment Execution Date Type.") 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( 'res.users', string='Generated by', readonly=True, ondelete='restrict', copy=False) diff --git a/account_payment_order/models/bank_payment_line.py b/account_payment_order/models/bank_payment_line.py index ef20197f2..4c9e509dd 100644 --- a/account_payment_order/models/bank_payment_line.py +++ b/account_payment_order/models/bank_payment_line.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # © 2015-2016 Akretion - Alexis de Lattre # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). @@ -15,7 +14,7 @@ class BankPaymentLine(models.Model): readonly=True) order_id = fields.Many2one( 'account.payment.order', string='Order', ondelete='cascade', - index=True) + index=True, readonly=True) payment_type = fields.Selection( related='order_id.payment_type', string="Payment Type", readonly=True, store=True) @@ -79,9 +78,6 @@ class BankPaymentLine(models.Model): for bline in self: amount_currency = sum( bline.mapped('payment_line_ids.amount_currency')) - import logging - logging.info(bline.company_id) - logging.info(bline.company_currency_id) amount_company_currency = bline.currency_id.with_context( date=bline.date).compute( amount_currency, bline.company_currency_id) diff --git a/account_payment_order/models/res_bank.py b/account_payment_order/models/res_bank.py index 55c93a839..cfef540b1 100644 --- a/account_payment_order/models/res_bank.py +++ b/account_payment_order/models/res_bank.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # © 2015-2016 Akretion - Alexis de Lattre # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). diff --git a/account_payment_order/report/account_payment_order.py b/account_payment_order/report/account_payment_order.py index 43edaf238..8fda1a46a 100644 --- a/account_payment_order/report/account_payment_order.py +++ b/account_payment_order/report/account_payment_order.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # © 2017 Acsone SA/NV () # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). diff --git a/account_payment_order/tests/__init__.py b/account_payment_order/tests/__init__.py index b654ec98a..bd1a04644 100644 --- a/account_payment_order/tests/__init__.py +++ b/account_payment_order/tests/__init__.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- -# Copyright 2017 Camptocamp SA -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). - from . import test_payment_mode from . import test_bank -from . import test_payment_order +from . import test_payment_order_inbound +from . import test_payment_order_outbound diff --git a/account_payment_order/tests/test_bank.py b/account_payment_order/tests/test_bank.py index 99d8d7e06..aae7bf81a 100644 --- a/account_payment_order/tests/test_bank.py +++ b/account_payment_order/tests/test_bank.py @@ -1,5 +1,4 @@ -# -*- coding: utf-8 -*- -# Copyright 2017 Creu Blanca +# © 2017 Creu Blanca # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from odoo.tests.common import TransactionCase diff --git a/account_payment_order/tests/test_payment_mode.py b/account_payment_order/tests/test_payment_mode.py index 0564ad436..b56d518e4 100644 --- a/account_payment_order/tests/test_payment_mode.py +++ b/account_payment_order/tests/test_payment_mode.py @@ -1,5 +1,4 @@ -# -*- coding: utf-8 -*- -# Copyright 2017 Creu Blanca +# © 2017 Creu Blanca # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from odoo.tests.common import TransactionCase @@ -29,6 +28,15 @@ class TestPaymentMode(TransactionCase): self.manual_out = self.env.ref( 'account.account_payment_method_manual_out') + self.manual_in = self.env.ref( + 'account.account_payment_method_manual_in') + + self.electronic_out = self.env['account.payment.method'].create({ + 'name': 'Electronic Out', + 'code': 'electronic_out', + 'payment_type': 'outbound', + }) + self.payment_mode_c1 = self.env['account.payment.mode'].create({ 'name': 'Direct Debit of suppliers from Bank 1', 'bank_account_link': 'variable', @@ -63,3 +71,32 @@ class TestPaymentMode(TransactionCase): '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() + self.assertEqual(self.payment_mode_c1.move_option, 'date') + self.payment_mode_c1.generate_move = False + 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 = '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() + self.assertTrue(all([ + journal.type in [ + 'sale_refund', 'sale' + ] for journal in self.payment_mode_c1.default_journal_ids + ])) + self.payment_mode_c1.payment_method_id = self.manual_out + self.payment_mode_c1.payment_method_id_change() + self.assertTrue(all([ + journal.type in [ + 'purchase_refund', 'purchase' + ] for journal in self.payment_mode_c1.default_journal_ids + ])) diff --git a/account_payment_order/tests/test_payment_order_inbound.py b/account_payment_order/tests/test_payment_order_inbound.py new file mode 100644 index 000000000..fcd25b7f9 --- /dev/null +++ b/account_payment_order/tests/test_payment_order_inbound.py @@ -0,0 +1,111 @@ +# © 2017 Camptocamp SA +# © 2017 Creu Blanca +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo.tests.common import TransactionCase +from odoo.exceptions import ValidationError, UserError +from datetime import date, timedelta + + +class TestPaymentOrderInbound(TransactionCase): + + def setUp(self): + super(TestPaymentOrderInbound, self).setUp() + self.inbound_mode = self.browse_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.journal = self.env['account.journal'].search( + [('type', '=', 'bank')], limit=1 + ) + self.inbound_mode.variable_journal_ids = self.journal + self.inbound_order = self.env['account.payment.order'].create({ + 'payment_type': 'inbound', + 'payment_mode_id': self.inbound_mode.id, + 'journal_id': self.journal.id, + }) + self.invoice = self._create_customer_invoice() + + 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 + + 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, + }) + order.payment_type = 'outbound' + + def test_constrains_date(self): + with self.assertRaises(ValidationError): + self.inbound_order.date_scheduled = date.today() - timedelta( + days=1) + + def test_creation(self): + # Open invoice + self.invoice.action_invoice_open() + # 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 + ).create({}).run() + payment_order = self.env['account.payment.order'].search([]) + self.assertEqual(len(payment_order.ids), 1) + bank_journal = self.env['account.journal'].search( + [('type', '=', 'bank')], limit=1) + # Set journal to allow cancelling entries + bank_journal.update_posted = True + + 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) + + # Open payment order + payment_order.draft2open() + + self.assertEqual(payment_order.bank_line_count, 1) + + # Generate and upload + payment_order.open2generated() + payment_order.generated2uploaded() + + self.assertEqual(payment_order.state, 'uploaded') + with self.assertRaises(UserError): + payment_order.unlink() + + bank_line = payment_order.bank_line_ids + + with self.assertRaises(UserError): + bank_line.unlink() + payment_order.action_done_cancel() + self.assertEqual(payment_order.state, 'cancel') + payment_order.cancel2draft() + payment_order.unlink() + self.assertEqual(len(self.env['account.payment.order'].search([])), 0) diff --git a/account_payment_order/tests/test_payment_order.py b/account_payment_order/tests/test_payment_order_outbound.py similarity index 53% rename from account_payment_order/tests/test_payment_order.py rename to account_payment_order/tests/test_payment_order_outbound.py index 5e844b461..36619c1f7 100644 --- a/account_payment_order/tests/test_payment_order.py +++ b/account_payment_order/tests/test_payment_order_outbound.py @@ -1,28 +1,37 @@ -# -*- coding: utf-8 -*- -# Copyright 2017 Camptocamp SA +# © 2017 Camptocamp SA +# © 2017 Creu Blanca # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from datetime import date, datetime, timedelta +from odoo.exceptions import UserError, ValidationError from odoo.tests.common import TransactionCase -from odoo.exceptions import UserError -from datetime import datetime -class TestPaymentOrder(TransactionCase): +class TestPaymentOrderOutbound(TransactionCase): def setUp(self): - super(TestPaymentOrder, self).setUp() + super(TestPaymentOrderOutbound, self).setUp() + self.journal = self.env['account.journal'].search( + [('type', '=', 'bank')], limit=1 + ) + self.invoice_line_account = self.env['account.account'].search( + [('user_type_id', '=', self.env.ref( + 'account.data_account_type_expenses').id)], + limit=1).id self.invoice = self._create_supplier_invoice() + self.invoice_02 = self._create_supplier_invoice() + self.mode = self.env.ref( + 'account_payment_mode.payment_mode_outbound_ct1') + self.creation_mode = self.env.ref( + 'account_payment_mode.payment_mode_outbound_dd1') + self.bank_journal = self.env['account.journal'].search( + [('type', '=', 'bank')], limit=1) 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 - self.invoice_line_account = self.env['account.account'].search( - [('user_type_id', '=', self.env.ref( - 'account.data_account_type_expenses').id)], - limit=1).id - invoice = self.env['account.invoice'].create({ 'partner_id': self.env.ref('base.res_partner_4').id, 'account_id': invoice_account, @@ -42,42 +51,81 @@ class TestPaymentOrder(TransactionCase): return invoice - def test_creation(self): + def test_creation_due_date(self): + self.mode.variable_journal_ids = self.bank_journal + self.mode.group_lines = False + self.order_creation('due') + + def test_creation_no_date(self): + self.mode.group_lines = True + self.creation_mode.write({ + 'group_lines': False, + 'bank_account_link': 'fixed', + 'default_date_prefered': 'due', + 'fixed_journal_id': self.bank_journal.id, + }) + self.mode.variable_journal_ids = self.bank_journal + self.order_creation(False) + + def test_creation_fixed_date(self): + self.mode.write({ + 'bank_account_link': 'fixed', + 'default_date_prefered': 'fixed', + 'fixed_journal_id': self.bank_journal.id, + }) + + self.invoice_02.action_invoice_open() + self.order_creation('fixed') + + def order_creation(self, date_prefered): # Open invoice self.invoice.action_invoice_open() - mode = self.env.ref('account_payment_mode.payment_mode_outbound_ct1') - order = self.env['account.payment.order'].create({ + order_vals = { 'payment_type': 'outbound', - 'payment_mode_id': self.env.ref( - 'account_payment_mode.payment_mode_outbound_dd1').id - }) - bank_journal = self.env['account.journal'].search( - [('type', '=', 'bank')], limit=1) - mode.variable_journal_ids = bank_journal - order.payment_mode_id = mode.id + 'payment_mode_id': self.creation_mode.id, + } + if date_prefered: + order_vals['date_prefered'] = date_prefered + order = self.env['account.payment.order'].create(order_vals) + with self.assertRaises(UserError): + order.draft2open() + + order.payment_mode_id = self.mode.id order.payment_mode_id_change() - self.assertEqual(order.journal_id.id, bank_journal.id) + self.assertEqual(order.journal_id.id, self.bank_journal.id) self.assertEqual(len(order.payment_line_ids), 0) + if date_prefered: + self.assertEqual(order.date_prefered, date_prefered) + with self.assertRaises(UserError): + order.draft2open() line_create = self.env['account.payment.line.create'].with_context( active_model='account.payment.order', active_id=order.id - ).create({}) - line_create.date_type = 'move' - line_create.move_date = datetime.now() + ).create({ + 'date_type': 'move', + 'move_date': datetime.now() + }) line_create.payment_mode = 'any' line_create.move_line_filters_change() line_create.populate() line_create.create_payment_lines() - line_create_due = self.env['account.payment.line.create'].with_context( + line_created_due = self.env[ + 'account.payment.line.create'].with_context( active_model='account.payment.order', active_id=order.id - ).create({}) - line_create_due.date_type = 'due' - line_create_due.due_date = datetime.now() - line_create_due.populate() - line_create_due.create_payment_lines() + ).create({ + 'date_type': 'due', + 'due_date': datetime.now() + }) + line_created_due.populate() + line_created_due.create_payment_lines() self.assertGreater(len(order.payment_line_ids), 0) + order.draft2open() + order.open2generated() + order.generated2uploaded() + order.action_done() + self.assertEqual(order.state, 'done') def test_cancel_payment_order(self): # Open invoice @@ -96,7 +144,7 @@ class TestPaymentOrder(TransactionCase): bank_journal.update_posted = True payment_order.write({ - 'journal_id': bank_journal.id + 'journal_id': bank_journal.id, }) self.assertEqual(len(payment_order.payment_line_ids), 1) @@ -122,6 +170,15 @@ class TestPaymentOrder(TransactionCase): payment_order.action_done_cancel() self.assertEqual(payment_order.state, 'cancel') payment_order.cancel2draft() - payment_order.unlink() self.assertEqual(len(self.env['account.payment.order'].search([])), 0) + + def test_constrains(self): + outbound_order = self.env['account.payment.order'].create({ + 'payment_type': 'outbound', + 'payment_mode_id': self.mode.id, + 'journal_id': self.journal.id, + }) + with self.assertRaises(ValidationError): + outbound_order.date_scheduled = date.today() - timedelta( + days=1) diff --git a/account_payment_order/views/account_payment_line.xml b/account_payment_order/views/account_payment_line.xml index 11a7d1f5b..8b0416ee7 100644 --- a/account_payment_order/views/account_payment_line.xml +++ b/account_payment_order/views/account_payment_line.xml @@ -14,6 +14,7 @@ + @@ -46,6 +47,7 @@ + diff --git a/account_payment_order/views/bank_payment_line.xml b/account_payment_order/views/bank_payment_line.xml index 88af3bc45..029741f37 100644 --- a/account_payment_order/views/bank_payment_line.xml +++ b/account_payment_order/views/bank_payment_line.xml @@ -10,7 +10,7 @@ bank.payment.line.form bank.payment.line -
+ @@ -36,7 +36,7 @@ bank.payment.line.tree bank.payment.line - + diff --git a/account_payment_order/wizard/account_payment_line_create.py b/account_payment_order/wizard/account_payment_line_create.py index b3a2af0c4..acb9599de 100644 --- a/account_payment_order/wizard/account_payment_line_create.py +++ b/account_payment_order/wizard/account_payment_line_create.py @@ -101,17 +101,11 @@ class AccountPaymentLineCreate(models.TransientModel): # will not be refunded with a payment. domain += [ ('credit', '>', 0), - # '|', - ('account_id.internal_type', '=', 'payable'), - # '&', - # ('account_id.internal_type', '=', 'receivable'), - # ('reconcile_partial_id', '=', False), # TODO uncomment - ] + ('account_id.internal_type', 'in', ['payable', 'receivable'])] elif self.order_id.payment_type == 'inbound': domain += [ ('debit', '>', 0), - ('account_id.internal_type', '=', 'receivable'), - ] + ('account_id.internal_type', 'in', ['receivable', 'payable'])] # Exclude lines that are already in a non-cancelled # and non-uploaded payment order; lines that are in a # uploaded payment order are proposed if they are not reconciled, diff --git a/setup/account_payment_order/odoo/__init__.py b/setup/account_payment_order/odoo/__init__.py new file mode 100644 index 000000000..de40ea7ca --- /dev/null +++ b/setup/account_payment_order/odoo/__init__.py @@ -0,0 +1 @@ +__import__('pkg_resources').declare_namespace(__name__) diff --git a/setup/account_payment_order/odoo/addons/__init__.py b/setup/account_payment_order/odoo/addons/__init__.py new file mode 100644 index 000000000..de40ea7ca --- /dev/null +++ b/setup/account_payment_order/odoo/addons/__init__.py @@ -0,0 +1 @@ +__import__('pkg_resources').declare_namespace(__name__) diff --git a/setup/account_payment_order/odoo/addons/account_payment_order b/setup/account_payment_order/odoo/addons/account_payment_order new file mode 120000 index 000000000..06957e99f --- /dev/null +++ b/setup/account_payment_order/odoo/addons/account_payment_order @@ -0,0 +1 @@ +../../../../account_payment_order \ No newline at end of file diff --git a/setup/account_payment_order/setup.cfg b/setup/account_payment_order/setup.cfg new file mode 100644 index 000000000..3c6e79cf3 --- /dev/null +++ b/setup/account_payment_order/setup.cfg @@ -0,0 +1,2 @@ +[bdist_wheel] +universal=1 diff --git a/setup/account_payment_order/setup.py b/setup/account_payment_order/setup.py new file mode 100644 index 000000000..999b290c8 --- /dev/null +++ b/setup/account_payment_order/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) \ No newline at end of file