changeset 36f5c90fef99 in modules/project_invoice:default
details: 
https://hg.tryton.org/modules/project_invoice?cmd=changeset&node=36f5c90fef99
description:
        Take into account up to date when computing invoice quantity

        issue10836
        review373811003
diffstat:

 project.py                                   |  37 ++++++++++++++++++---------
 tests/scenario_project_invoice_timesheet.rst |  26 ++++++++++++++++++-
 2 files changed, 49 insertions(+), 14 deletions(-)

diffs (104 lines):

diff -r eda64cc40746 -r 36f5c90fef99 project.py
--- a/project.py        Mon Nov 01 17:27:34 2021 +0100
+++ b/project.py        Mon Nov 22 10:12:44 2021 +0100
@@ -250,19 +250,32 @@
         cursor = Transaction().connection.cursor()
         line = TimesheetLine.__table__()
 
+        upto2tworks = defaultdict(list)
+        twork2work = {}
+        for work in works:
+            upto = work.invoice_timesheet_up_to
+            for timesheet_work in work.timesheet_works:
+                twork2work[timesheet_work.id] = work.id
+                upto2tworks[upto].append(timesheet_work.id)
+
         durations = defaultdict(datetime.timedelta)
-        twork2work = {tw.id: w.id for w in works for tw in w.timesheet_works}
-        for sub_ids in grouped_slice(twork2work.keys()):
-            red_sql = reduce_ids(line.work, sub_ids)
-            cursor.execute(*line.select(line.work, Sum(line.duration),
-                    where=red_sql & (line.invoice_line == Null),
-                    group_by=line.work))
-            for twork_id, duration in cursor:
-                if duration:
-                    # SQLite uses float for SUM
-                    if not isinstance(duration, datetime.timedelta):
-                        duration = datetime.timedelta(seconds=duration)
-                    durations[twork2work[twork_id]] += duration
+        query = line.select(
+            line.work, Sum(line.duration),
+            group_by=line.work)
+        for upto, tworks in upto2tworks.items():
+            for sub_ids in grouped_slice(tworks):
+                query.where = (reduce_ids(line.work, sub_ids)
+                    & (line.invoice_line == Null))
+                if upto:
+                    query.where &= (line.date <= upto)
+                cursor.execute(*query)
+
+                for twork_id, duration in cursor:
+                    if duration:
+                        # SQLite uses float for SUM
+                        if not isinstance(duration, datetime.timedelta):
+                            duration = datetime.timedelta(seconds=duration)
+                        durations[twork2work[twork_id]] += duration
 
         quantities = {}
         for work in works:
diff -r eda64cc40746 -r 36f5c90fef99 
tests/scenario_project_invoice_timesheet.rst
--- a/tests/scenario_project_invoice_timesheet.rst      Mon Nov 01 17:27:34 
2021 +0100
+++ b/tests/scenario_project_invoice_timesheet.rst      Mon Nov 22 10:12:44 
2021 +0100
@@ -46,8 +46,9 @@
     >>> project_invoice_user.login = 'project_invoice'
     >>> project_invoice_group, = Group.find([('name', '=', 'Project Invoice')])
     >>> project_group, = Group.find([('name', '=', 'Project Administration')])
+    >>> invoice_group, = Group.find([('name', '=', 'Account')])
     >>> project_invoice_user.groups.extend(
-    ...     [project_invoice_group, project_group])
+    ...     [project_invoice_group, project_group, invoice_group])
     >>> project_invoice_user.save()
 
 Create chart of accounts::
@@ -160,8 +161,19 @@
     >>> set_user(project_invoice_user)
     >>> project.click('invoice')
     >>> project.amount_to_invoice
+    Decimal('0.00')
+    >>> project.invoiced_amount
+    Decimal('60.00')
+
+    >>> project.project_invoice_timesheet_up_to = today
+    >>> project.save()
+    >>> project.amount_to_invoice
     Decimal('40.00')
-    >>> project.invoiced_amount
+
+    >>> set_user(project_invoice_user)
+    >>> Invoice = Model.get('account.invoice')
+    >>> invoice, = Invoice.find([])
+    >>> invoice.total_amount
     Decimal('60.00')
 
 Invoice all project::
@@ -176,6 +188,11 @@
     >>> project.invoiced_amount
     Decimal('100.00')
 
+    >>> set_user(project_invoice_user)
+    >>> _, invoice = Invoice.find([], order=[('id', 'ASC')])
+    >>> invoice.total_amount
+    Decimal('40.00')
+
 Create more timesheets::
 
     >>> set_user(project_user)
@@ -202,3 +219,8 @@
     Decimal('0.00')
     >>> project.invoiced_amount
     Decimal('180.00')
+
+    >>> set_user(project_invoice_user)
+    >>> _, _, invoice = Invoice.find([], order=[('id', 'ASC')])
+    >>> invoice.total_amount
+    Decimal('80.00')

Reply via email to