diff --git a/src/Form/Toolbar/AbstractToolbarForm.php b/src/Form/Toolbar/AbstractToolbarForm.php
index 5905a103..097de9d9 100644
--- a/src/Form/Toolbar/AbstractToolbarForm.php
+++ b/src/Form/Toolbar/AbstractToolbarForm.php
@@ -346,4 +346,13 @@ abstract class AbstractToolbarForm extends AbstractType
],
]);
}
+
+ protected function addBillableChoice(FormBuilderInterface $builder)
+ {
+ $builder->add('billable', BillableType::class, [
+ 'required' => false,
+ 'placeholder' => null,
+ 'search' => false,
+ ]);
+ }
}
diff --git a/src/Form/Toolbar/BillableType.php b/src/Form/Toolbar/BillableType.php
new file mode 100644
index 00000000..4786fe78
--- /dev/null
+++ b/src/Form/Toolbar/BillableType.php
@@ -0,0 +1,40 @@
+setDefaults([
+ 'label' => 'label.billable',
+ 'choices' => [
+ 'entryState.all' => null,
+ 'yes' => true,
+ 'no' => false,
+ ],
+ ]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getParent()
+ {
+ return ChoiceType::class;
+ }
+}
diff --git a/src/Form/Type/BillableType.php b/src/Form/Type/BillableType.php
new file mode 100644
index 00000000..d58db76e
--- /dev/null
+++ b/src/Form/Type/BillableType.php
@@ -0,0 +1,38 @@
+setDefaults([
+ 'label' => 'label.billable',
+ ]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getParent()
+ {
+ return YesNoType::class;
+ }
+}
diff --git a/src/Repository/Query/BillableInterface.php b/src/Repository/Query/BillableInterface.php
new file mode 100644
index 00000000..87c4b031
--- /dev/null
+++ b/src/Repository/Query/BillableInterface.php
@@ -0,0 +1,48 @@
+billable;
+ }
+
+ public function isBillable(): bool
+ {
+ return $this->billable === true;
+ }
+
+ public function isNotBillable(): bool
+ {
+ return $this->billable === false;
+ }
+
+ public function isIgnoreBillable(): bool
+ {
+ return $this->billable === null;
+ }
+
+ public function setBillable(?bool $isBillable): void
+ {
+ $this->billable = $isBillable;
+ }
+}
diff --git a/src/Repository/Query/InvoiceQuery.php b/src/Repository/Query/InvoiceQuery.php
index 750456ed..16a0099c 100644
--- a/src/Repository/Query/InvoiceQuery.php
+++ b/src/Repository/Query/InvoiceQuery.php
@@ -25,7 +25,7 @@ class InvoiceQuery extends TimesheetQuery
public function __construct()
{
parent::__construct();
- $this->setBillable(InvoiceQuery::STATE_BILLABLE);
+ $this->setBillable(true);
}
public function getTemplate(): ?InvoiceTemplate
diff --git a/src/Repository/Query/TimesheetQuery.php b/src/Repository/Query/TimesheetQuery.php
index cd60fa9b..7073f1a1 100644
--- a/src/Repository/Query/TimesheetQuery.php
+++ b/src/Repository/Query/TimesheetQuery.php
@@ -17,15 +17,15 @@ use App\Form\Model\DateRange;
/**
* Can be used for advanced timesheet repository queries.
*/
-class TimesheetQuery extends ActivityQuery
+class TimesheetQuery extends ActivityQuery implements BillableInterface
{
+ use BillableTrait;
+
public const STATE_ALL = 1;
public const STATE_RUNNING = 2;
public const STATE_STOPPED = 3;
public const STATE_EXPORTED = 4;
public const STATE_NOT_EXPORTED = 5;
- public const STATE_BILLABLE = 6;
- public const STATE_NOT_BILLABLE = 7;
public const TIMESHEET_ORDER_ALLOWED = ['begin', 'end', 'duration', 'rate', 'customer', 'project', 'activity', 'description'];
@@ -45,10 +45,6 @@ class TimesheetQuery extends ActivityQuery
* @var int
*/
protected $exported = self::STATE_ALL;
- /**
- * @var int
- */
- private $billable = self::STATE_ALL;
/**
* @var \DateTime|null
*/
@@ -295,30 +291,6 @@ class TimesheetQuery extends ActivityQuery
return $this;
}
- public function getBillable(): int
- {
- return $this->billable;
- }
-
- public function isBillable(): bool
- {
- return $this->billable === self::STATE_BILLABLE;
- }
-
- public function isNotBillable(): bool
- {
- return $this->billable === self::STATE_NOT_BILLABLE;
- }
-
- public function setBillable(int $billable): TimesheetQuery
- {
- if (\in_array($billable, [self::STATE_ALL, self::STATE_BILLABLE, self::STATE_NOT_BILLABLE], true)) {
- $this->billable = $billable;
- }
-
- return $this;
- }
-
public function getModifiedAfter(): ?\DateTime
{
return $this->modifiedAfter;
diff --git a/tests/Repository/Query/InvoiceQueryTest.php b/tests/Repository/Query/InvoiceQueryTest.php
index 09158b31..7d7dfcd5 100644
--- a/tests/Repository/Query/InvoiceQueryTest.php
+++ b/tests/Repository/Query/InvoiceQueryTest.php
@@ -10,7 +10,6 @@
namespace App\Tests\Repository\Query;
use App\Repository\Query\InvoiceQuery;
-use App\Repository\Query\TimesheetQuery;
/**
* @covers \App\Repository\Query\InvoiceQuery
@@ -36,7 +35,11 @@ class InvoiceQueryTest extends TimesheetQueryTest
$this->assertMarkAsExported($sut);
$this->assertModifiedAfter($sut);
- self::assertEquals(TimesheetQuery::STATE_BILLABLE, $sut->getBillable());
+ self::assertTrue($sut->getBillable());
+ self::assertTrue($sut->isBillable());
+ self::assertFalse($sut->isNotBillable());
+ self::assertFalse($sut->isIgnoreBillable());
+
self::assertTrue($sut->isBillable());
self::assertFalse($sut->isNotBillable());
$this->assertBillable($sut);
diff --git a/tests/Repository/Query/TimesheetQueryTest.php b/tests/Repository/Query/TimesheetQueryTest.php
index 26c4a1f6..9b4656e9 100644
--- a/tests/Repository/Query/TimesheetQueryTest.php
+++ b/tests/Repository/Query/TimesheetQueryTest.php
@@ -37,7 +37,11 @@ class TimesheetQueryTest extends BaseQueryTest
$this->assertSearchTerm($sut);
$this->assertModifiedAfter($sut);
- self::assertEquals(TimesheetQuery::STATE_ALL, $sut->getBillable());
+ self::assertNull($sut->getBillable());
+ self::assertFalse($sut->isBillable());
+ self::assertFalse($sut->isNotBillable());
+ self::assertTrue($sut->isIgnoreBillable());
+
self::assertFalse($sut->isBillable());
self::assertFalse($sut->isNotBillable());
$this->assertBillable($sut);
@@ -140,22 +144,22 @@ class TimesheetQueryTest extends BaseQueryTest
protected function assertBillable(TimesheetQuery $sut)
{
- self::assertInstanceOf(TimesheetQuery::class, $sut->setBillable(TimesheetQuery::STATE_ALL));
- self::assertEquals(TimesheetQuery::STATE_ALL, $sut->getBillable());
+ $sut->setBillable(null);
+ self::assertNull($sut->getBillable());
self::assertFalse($sut->isBillable());
self::assertFalse($sut->isNotBillable());
+ self::assertTrue($sut->isIgnoreBillable());
- $sut->setBillable(PHP_INT_MAX);
- self::assertEquals(TimesheetQuery::STATE_ALL, $sut->getBillable());
-
- $sut->setBillable(TimesheetQuery::STATE_BILLABLE);
- self::assertEquals(TimesheetQuery::STATE_BILLABLE, $sut->getBillable());
+ $sut->setBillable(true);
+ self::assertTrue($sut->getBillable());
self::assertTrue($sut->isBillable());
self::assertFalse($sut->isNotBillable());
+ self::assertFalse($sut->isIgnoreBillable());
- $sut->setBillable(TimesheetQuery::STATE_NOT_BILLABLE);
- self::assertEquals(TimesheetQuery::STATE_NOT_BILLABLE, $sut->getBillable());
+ $sut->setBillable(false);
+ self::assertFalse($sut->getBillable());
self::assertFalse($sut->isBillable());
self::assertTrue($sut->isNotBillable());
+ self::assertFalse($sut->isIgnoreBillable());
}
}
diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf
index 18bb061e..0c17479f 100644
--- a/translations/messages.de.xlf
+++ b/translations/messages.de.xlf
@@ -340,6 +340,10 @@
placeholder.type_message
Schreibe Deine Nachricht...
+
+ label.billable
+ Abrechenbar
+