From 3668616183a26aa191c80c8c55e625febd6ee928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 15 Apr 2019 22:12:03 +0200 Subject: [PATCH] Process reconciled invoice when posted A supplier invoice can be paid before being posted. So the workflow should continue if it is reconciled. issue7999 review279231002 --- invoice.py | 5 + tests/scenario_invoice_supplier_post_paid.rst | 123 ++++++++++++++++++ tests/test_account_invoice.py | 5 + 3 files changed, 133 insertions(+) create mode 100644 tests/scenario_invoice_supplier_post_paid.rst diff --git a/invoice.py b/invoice.py index 0f24acbe90..bd6c713232 100644 --- a/invoice.py +++ b/invoice.py @@ -1373,9 +1373,14 @@ class Invoice(Workflow, ModelSQL, ModelView, TaxableMixin): Move.save(moves) cls.save(invoices) Move.post([i.move for i in invoices if i.move.state != 'posted']) + reconciled = [] for invoice in invoices: if invoice.type == 'out': invoice.print_invoice() + if invoice.reconciled: + reconciled.append(invoice) + if reconciled: + cls.__queue__.process(reconciled) @classmethod @ModelView.button_action('account_invoice.wizard_pay') diff --git a/tests/scenario_invoice_supplier_post_paid.rst b/tests/scenario_invoice_supplier_post_paid.rst new file mode 100644 index 0000000000..2ddd915726 --- /dev/null +++ b/tests/scenario_invoice_supplier_post_paid.rst @@ -0,0 +1,123 @@ +========================== +Invoice Supplier Post Paid +========================== + +Imports:: + >>> import datetime + >>> from dateutil.relativedelta import relativedelta + >>> from decimal import Decimal + >>> from operator import attrgetter + >>> from proteus import Model, Wizard + >>> from trytond.tests.tools import activate_modules + >>> from trytond.modules.company.tests.tools import create_company, \ + ... get_company + >>> from trytond.modules.account.tests.tools import create_fiscalyear, \ + ... create_chart, get_accounts + >>> from trytond.modules.account_invoice.tests.tools import \ + ... set_fiscalyear_invoice_sequences + >>> today = datetime.date.today() + +Install account_invoice:: + + >>> config = activate_modules('account_invoice') + +Create company:: + + >>> _ = create_company() + >>> company = get_company() + +Create fiscal year:: + + >>> fiscalyear = set_fiscalyear_invoice_sequences( + ... create_fiscalyear(company)) + >>> fiscalyear.click('create_period') + >>> period = fiscalyear.periods[0] + +Create chart of accounts:: + + >>> _ = create_chart(company) + >>> accounts = get_accounts(company) + >>> payable = accounts['payable'] + >>> expense = accounts['expense'] + >>> cash = accounts['cash'] + +Create party:: + + >>> Party = Model.get('party.party') + >>> party = Party(name='Party') + >>> party.save() + +Create account category:: + + >>> ProductCategory = Model.get('product.category') + >>> account_category = ProductCategory(name="Account Category") + >>> account_category.accounting = True + >>> account_category.account_expense = expense + >>> account_category.save() + +Create product:: + + >>> ProductUom = Model.get('product.uom') + >>> unit, = ProductUom.find([('name', '=', 'Unit')]) + >>> ProductTemplate = Model.get('product.template') + >>> template = ProductTemplate() + >>> template.name = 'product' + >>> template.default_uom = unit + >>> template.type = 'service' + >>> template.list_price = Decimal('40') + >>> template.account_category = account_category + >>> template.save() + >>> product, = template.products + +Create validated invoice:: + + >>> Invoice = Model.get('account.invoice') + >>> invoice = Invoice() + >>> invoice.type = 'in' + >>> invoice.party = party + >>> invoice.invoice_date = today + >>> line = invoice.lines.new() + >>> line.product = product + >>> line.quantity = 5 + >>> line.unit_price = Decimal('20') + >>> invoice.click('validate_invoice') + >>> invoice.state + 'validated' + +Pay invoice:: + + >>> Move = Model.get('account.move') + >>> Journal = Model.get('account.journal') + >>> journal_cash, = Journal.find([ + ... ('code', '=', 'CASH'), + ... ]) + >>> move = Move() + >>> move.period = period + >>> move.journal = journal_cash + >>> move.date = period.start_date + >>> line = move.lines.new() + >>> line.account = payable + >>> line.debit = Decimal('100') + >>> line.party = party + >>> line = move.lines.new() + >>> line.account = cash + >>> line.credit = Decimal('100') + >>> move.save() + + >>> Line = Model.get('account.move.line') + >>> lines = Line.find([('account', '=', payable.id)]) + >>> reconcile = Wizard('account.move.reconcile_lines', lines) + +Check invoice:: + + >>> invoice.reload() + >>> invoice.state + 'validated' + >>> bool(invoice.reconciled) + True + +Post invoice:: + + >>> invoice.click('post') + >>> invoice.state + 'paid' diff --git a/tests/test_account_invoice.py b/tests/test_account_invoice.py index 0b079c1f54..74fcbcf9e0 100644 --- a/tests/test_account_invoice.py +++ b/tests/test_account_invoice.py @@ -220,6 +220,11 @@ def suite(): tearDown=doctest_teardown, encoding='utf-8', checker=doctest_checker, optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)) + suite.addTests(doctest.DocFileSuite( + 'scenario_invoice_supplier_post_paid.rst', + tearDown=doctest_teardown, encoding='utf-8', + checker=doctest_checker, + optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)) suite.addTests(doctest.DocFileSuite( 'scenario_invoice_alternate_currency.rst', tearDown=doctest_teardown, encoding='utf-8',