diff --git a/CHANGELOG b/CHANGELOG
index 2fecd7c1e2..f0f85db86a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,5 @@
+* Add date up to which to invoice timesheet
+
Version 5.8.0 - 2020-11-02
* Bug fixes (see mercurial logs for details)
* Remove support for Python 3.5
diff --git a/project.py b/project.py
index 850b11f799..2b393fad34 100644
--- a/project.py
+++ b/project.py
@@ -207,6 +207,17 @@ class Progress:
class Timesheet:
+ project_invoice_timesheet_up_to = fields.Date(
+ "Invoice up to",
+ states={
+ 'invisible': Eval('project_invoice_method') != 'timesheet',
+ },
+ depends=['project_invoice_method'],
+ help="Limits which timesheet lines get invoiced to "
+ "only those before the date.")
+ invoice_timesheet_up_to = fields.Function(fields.Date(
+ "Invoice up to"), 'on_change_with_invoice_timesheet_up_to')
+
@classmethod
def __setup__(cls):
super().__setup__()
@@ -221,6 +232,14 @@ class Timesheet:
if 'invoice_method' not in cls.product.depends:
cls.product.depends.append('invoice_method')
+ @fields.depends('type', 'project_invoice_timesheet_up_to',
+ 'parent', '_parent_parent.invoice_timesheet_up_to')
+ def on_change_with_invoice_timesheet_up_to(self, name=None):
+ if self.type == 'project':
+ return self.project_invoice_timesheet_up_to
+ elif self.parent:
+ return self.parent.invoice_timesheet_up_to
+
@classmethod
def _get_quantity_to_invoice_timesheet(cls, works):
pool = Pool()
@@ -311,10 +330,11 @@ class Timesheet:
except AttributeError:
origins = []
if self.invoice_method == 'timesheet':
+ up_to = self.invoice_timesheet_up_to or datetime.date.max
origins.extend(
l for tw in self.timesheet_works
for l in tw.timesheet_lines
- if not l.invoice_line)
+ if not l.invoice_line and l.date <= up_to)
return origins
diff --git a/tests/scenario_project_invoice_timesheet.rst b/tests/scenario_project_invoice_timesheet.rst
index 34e49809a2..8b9ef12b46 100644
--- a/tests/scenario_project_invoice_timesheet.rst
+++ b/tests/scenario_project_invoice_timesheet.rst
@@ -16,6 +16,7 @@ Imports::
>>> from trytond.modules.account_invoice.tests.tools import \
... create_payment_term
>>> today = datetime.date.today()
+ >>> yesterday = today - datetime.timedelta(days=1)
Activate modules::
@@ -133,11 +134,13 @@ Create timesheets::
>>> TimesheetLine = Model.get('timesheet.line')
>>> line = TimesheetLine()
+ >>> line.date = yesterday
>>> line.employee = employee
>>> line.duration = datetime.timedelta(hours=3)
>>> line.work, = task.timesheet_works
>>> line.save()
>>> line = TimesheetLine()
+ >>> line.date = today
>>> line.employee = employee
>>> line.duration = datetime.timedelta(hours=2)
>>> line.work, = project.timesheet_works
@@ -151,8 +154,23 @@ Check project amounts::
>>> project.invoiced_amount
Decimal('0.00')
-Invoice project::
+Invoice project up to yesterday::
+ >>> set_user(project_user)
+ >>> project.project_invoice_timesheet_up_to = yesterday
+ >>> project.save()
+ >>> set_user(project_invoice_user)
+ >>> project.click('invoice')
+ >>> project.amount_to_invoice
+ Decimal('40.00')
+ >>> project.invoiced_amount
+ Decimal('60.00')
+
+Invoice all project::
+
+ >>> set_user(project_user)
+ >>> project.project_invoice_timesheet_up_to = None
+ >>> project.save()
>>> set_user(project_invoice_user)
>>> project.click('invoice')
>>> project.amount_to_invoice
diff --git a/view/work_form.xml b/view/work_form.xml
index dae7b29d4f..0f4ded9d3b 100644
--- a/view/work_form.xml
+++ b/view/work_form.xml
@@ -8,6 +8,10 @@ this repository contains the full copyright notices and license terms. -->
+
+
+
+