changeset c053ef01407f in modules/account_statement:default
details: 
https://hg.tryton.org/modules/account_statement?cmd=changeset;node=c053ef01407f
description:
        Use invoice amount to pay as line amount when creating lines from 
origins

        issue7912
        review52551002
diffstat:

 CHANGELOG                                    |    1 +
 statement.py                                 |   45 +++++++++
 tests/scenario_statement_origin_invoices.rst |  128 +++++++++++++++++++++++++++
 tests/test_account_statement.py              |    5 +
 4 files changed, 179 insertions(+), 0 deletions(-)

diffs (208 lines):

diff -r 9ed31f1f5201 -r c053ef01407f CHANGELOG
--- a/CHANGELOG Fri Apr 12 15:59:24 2019 +0200
+++ b/CHANGELOG Sun Apr 14 14:30:06 2019 +0200
@@ -1,3 +1,4 @@
+* Use invoice amount to pay as line amount when creating lines from origins
 * Rename Origin field informations to information
 
 Version 5.0.0 - 2018-10-01
diff -r 9ed31f1f5201 -r c053ef01407f statement.py
--- a/statement.py      Fri Apr 12 15:59:24 2019 +0200
+++ b/statement.py      Sun Apr 14 14:30:06 2019 +0200
@@ -248,6 +248,51 @@
         return ((getattr(self, 'end_balance', 0) or 0)
             - (getattr(self, 'start_balance', 0) or 0))
 
+    @fields.depends('origins', 'lines', 'journal', 'company')
+    def on_change_origins(self):
+        if not self.journal or not self.origins or not self.company:
+            return
+        if self.journal.currency != self.company.currency:
+            return
+
+        invoices = set()
+        for line in self.lines:
+            if (getattr(line, 'invoice', None)
+                    and line.invoice.currency == self.company.currency):
+                invoices.add(line.invoice)
+        for origin in self.origins:
+            for line in origin.lines:
+                if (getattr(line, 'invoice', None)
+                        and line.invoice.currency == self.company.currency):
+                    invoices.add(line.invoice)
+        invoice_id2amount_to_pay = {}
+        for invoice in invoices:
+            if invoice.type == 'out':
+                sign = -1
+            else:
+                sign = 1
+            invoice_id2amount_to_pay[invoice.id] = sign * invoice.amount_to_pay
+
+        origins = list(self.origins)
+        for origin in origins:
+            lines = list(origin.lines)
+            for line in lines:
+                if (getattr(line, 'invoice', None) and line.id
+                        and line.invoice.id in invoice_id2amount_to_pay):
+                    amount_to_pay = invoice_id2amount_to_pay[line.invoice.id]
+                    if (amount_to_pay
+                            and getattr(line, 'amount', None)
+                            and (line.amount >= 0) == (amount_to_pay <= 0)):
+                        if abs(line.amount) > abs(amount_to_pay):
+                            line.amount = amount_to_pay.copy_sign(line.amount)
+                        else:
+                            invoice_id2amount_to_pay[line.invoice.id] = (
+                                line.amount + amount_to_pay)
+                    else:
+                        line.invoice = None
+            origin.lines = lines
+        self.origins = origins
+
     @fields.depends('lines', 'journal', 'company')
     def on_change_lines(self):
         pool = Pool()
diff -r 9ed31f1f5201 -r c053ef01407f 
tests/scenario_statement_origin_invoices.rst
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/scenario_statement_origin_invoices.rst      Sun Apr 14 14:30:06 
2019 +0200
@@ -0,0 +1,128 @@
+==========================================
+Account Statement Origin Invoices Scenario
+==========================================
+
+Imports::
+
+    >>> import datetime
+    >>> from decimal import Decimal
+    >>> from proteus import Model, Wizard, Report
+    >>> 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_statement::
+
+    >>> config = activate_modules('account_statement')
+
+Create company::
+
+    >>> _ = create_company()
+    >>> company = get_company()
+
+Create fiscal year::
+
+    >>> fiscalyear = set_fiscalyear_invoice_sequences(
+    ...     create_fiscalyear(company))
+    >>> fiscalyear.click('create_period')
+
+Create chart of accounts::
+
+    >>> _ = create_chart(company)
+    >>> accounts = get_accounts(company)
+    >>> receivable = accounts['receivable']
+    >>> revenue = accounts['revenue']
+    >>> cash = accounts['cash']
+
+Create parties::
+
+    >>> Party = Model.get('party.party')
+    >>> customer = Party(name="Customer")
+    >>> customer.save()
+
+Create 2 customer invoices::
+
+    >>> Invoice = Model.get('account.invoice')
+    >>> customer_invoice1 = Invoice(type='out')
+    >>> customer_invoice1.party = customer
+    >>> invoice_line = customer_invoice1.lines.new()
+    >>> invoice_line.quantity = 1
+    >>> invoice_line.unit_price = Decimal('100')
+    >>> invoice_line.account = revenue
+    >>> invoice_line.description = 'Test'
+    >>> customer_invoice1.click('post')
+    >>> customer_invoice1.state
+    'posted'
+
+    >>> customer_invoice2 = Invoice(type='out')
+    >>> customer_invoice2.party = customer
+    >>> invoice_line = customer_invoice2.lines.new()
+    >>> invoice_line.quantity = 1
+    >>> invoice_line.unit_price = Decimal('150')
+    >>> invoice_line.account = revenue
+    >>> invoice_line.description = 'Test'
+    >>> customer_invoice2.click('post')
+    >>> customer_invoice2.state
+    'posted'
+
+Create Account Journal::
+
+    >>> Sequence = Model.get('ir.sequence')
+    >>> AccountJournal = Model.get('account.journal')
+
+    >>> sequence = Sequence(name="Satement",
+    ...     code='account.journal',
+    ...     company=company,
+    ...     )
+    >>> sequence.save()
+    >>> account_journal = AccountJournal(name="Statement",
+    ...     type='statement',
+    ...     sequence=sequence,
+    ...     )
+    >>> account_journal.save()
+
+Create a statement with origins::
+
+    >>> StatementJournal = Model.get('account.statement.journal')
+    >>> Statement = Model.get('account.statement')
+    >>> journal_number = StatementJournal(name="Number",
+    ...     journal=account_journal,
+    ...     account=cash,
+    ...     validation='number_of_lines',
+    ...     )
+    >>> journal_number.save()
+
+    >>> statement = Statement(name="number origins")
+    >>> statement.journal = journal_number
+    >>> statement.number_of_lines = 1
+    >>> origin = statement.origins.new()
+    >>> origin.date = today
+    >>> origin.amount = Decimal('180.00')
+    >>> statement.click('validate_statement')
+
+Pending amount is used to fill all invoices::
+
+    >>> origin, = statement.origins
+    >>> line = origin.lines.new()
+    >>> line.invoice = customer_invoice1
+    >>> line.amount
+    Decimal('100.00')
+    >>> line.party == customer
+    True
+    >>> line.account == receivable
+    True
+    >>> origin.pending_amount
+    Decimal('80.00')
+    >>> line = origin.lines.new()
+    >>> line.invoice = customer_invoice2
+    >>> line.amount
+    Decimal('80.00')
+    >>> line.party == customer
+    True
+    >>> line.account == receivable
+    True
diff -r 9ed31f1f5201 -r c053ef01407f tests/test_account_statement.py
--- a/tests/test_account_statement.py   Fri Apr 12 15:59:24 2019 +0200
+++ b/tests/test_account_statement.py   Sun Apr 14 14:30:06 2019 +0200
@@ -25,4 +25,9 @@
             tearDown=doctest_teardown, encoding='utf-8',
             checker=doctest_checker,
             optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
+    suite.addTests(doctest.DocFileSuite(
+            'scenario_statement_origin_invoices.rst',
+            tearDown=doctest_teardown, encoding='utf-8',
+            checker=doctest_checker,
+            optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
     return suite

Reply via email to