diff --git a/src/Entity/Activity.php b/src/Entity/Activity.php index fc6d2b90..795a78ca 100644 --- a/src/Entity/Activity.php +++ b/src/Entity/Activity.php @@ -174,6 +174,12 @@ class Activity implements EntityWithMetaFields, EntityWithBudget * ) */ private $teams; + /** + * @var string|null + * + * @ORM\Column(name="invoice_text", type="text", nullable=true) + */ + private $invoiceText; public function __construct() { @@ -338,6 +344,16 @@ class Activity implements EntityWithMetaFields, EntityWithBudget return $this->teams; } + public function getInvoiceText(): ?string + { + return $this->invoiceText; + } + + public function setInvoiceText(?string $invoiceText): void + { + $this->invoiceText = $invoiceText; + } + /** * @return string */ diff --git a/src/Entity/Project.php b/src/Entity/Project.php index bdd47b95..8a263b55 100644 --- a/src/Entity/Project.php +++ b/src/Entity/Project.php @@ -246,6 +246,12 @@ class Project implements EntityWithMetaFields, EntityWithBudget * ) */ private $teams; + /** + * @var string|null + * + * @ORM\Column(name="invoice_text", type="text", nullable=true) + */ + private $invoiceText; public function __construct() { @@ -520,6 +526,16 @@ class Project implements EntityWithMetaFields, EntityWithBudget return true; } + public function getInvoiceText(): ?string + { + return $this->invoiceText; + } + + public function setInvoiceText(?string $invoiceText): void + { + $this->invoiceText = $invoiceText; + } + /** * @return string */ diff --git a/src/Form/ActivityEditForm.php b/src/Form/ActivityEditForm.php index 5d97cd06..d4d16bf4 100644 --- a/src/Form/ActivityEditForm.php +++ b/src/Form/ActivityEditForm.php @@ -60,6 +60,10 @@ class ActivityEditForm extends AbstractType 'label' => 'label.description', 'required' => false, ]) + ->add('invoiceText', TextareaType::class, [ + 'label' => 'label.invoiceText', + 'required' => false, + ]) ; if ($new || !$isGlobal) { diff --git a/src/Form/ProjectEditForm.php b/src/Form/ProjectEditForm.php index 18a40685..602c2109 100644 --- a/src/Form/ProjectEditForm.php +++ b/src/Form/ProjectEditForm.php @@ -67,6 +67,10 @@ class ProjectEditForm extends AbstractType 'label' => 'label.description', 'required' => false, ]) + ->add('invoiceText', TextareaType::class, [ + 'label' => 'label.invoiceText', + 'required' => false, + ]) ->add('orderNumber', TextType::class, [ 'label' => 'label.orderNumber', 'required' => false, diff --git a/src/Invoice/Calculator/ActivityInvoiceCalculator.php b/src/Invoice/Calculator/ActivityInvoiceCalculator.php index 64d4f20a..8ebacbee 100644 --- a/src/Invoice/Calculator/ActivityInvoiceCalculator.php +++ b/src/Invoice/Calculator/ActivityInvoiceCalculator.php @@ -33,7 +33,11 @@ class ActivityInvoiceCalculator extends AbstractSumInvoiceCalculator implements return; } - $invoiceItem->setDescription($entry->getActivity()->getName()); + if ($entry->getActivity()->getInvoiceText() !== null) { + $invoiceItem->setDescription($entry->getActivity()->getInvoiceText()); + } else { + $invoiceItem->setDescription($entry->getActivity()->getName()); + } } /** diff --git a/src/Invoice/Calculator/ProjectInvoiceCalculator.php b/src/Invoice/Calculator/ProjectInvoiceCalculator.php index 25285cd6..8b53afad 100644 --- a/src/Invoice/Calculator/ProjectInvoiceCalculator.php +++ b/src/Invoice/Calculator/ProjectInvoiceCalculator.php @@ -29,8 +29,11 @@ class ProjectInvoiceCalculator extends AbstractSumInvoiceCalculator implements C protected function mergeSumInvoiceItem(InvoiceItem $invoiceItem, InvoiceItemInterface $entry) { - $invoiceItem->setProject($entry->getProject()); - $invoiceItem->setDescription($entry->getProject()->getName()); + if ($entry->getProject()->getInvoiceText() !== null) { + $invoiceItem->setDescription($entry->getProject()->getInvoiceText()); + } else { + $invoiceItem->setDescription($entry->getProject()->getName()); + } } /** diff --git a/src/Migrations/Version20220531145920.php b/src/Migrations/Version20220531145920.php new file mode 100644 index 00000000..f708a357 --- /dev/null +++ b/src/Migrations/Version20220531145920.php @@ -0,0 +1,44 @@ +getTable('kimai2_activities'); + $activities->addColumn('invoice_text', 'text', ['notnull' => false, 'default' => null]); + + $projects = $schema->getTable('kimai2_projects'); + $projects->addColumn('invoice_text', 'text', ['notnull' => false, 'default' => null]); + } + + public function down(Schema $schema): void + { + $activities = $schema->getTable('kimai2_activities'); + $activities->dropColumn('invoice_text'); + + $projects = $schema->getTable('kimai2_projects'); + $projects->dropColumn('invoice_text'); + } +} diff --git a/templates/activity/edit.html.twig b/templates/activity/edit.html.twig index 7ac2f0bd..f15bb27d 100644 --- a/templates/activity/edit.html.twig +++ b/templates/activity/edit.html.twig @@ -41,6 +41,9 @@ {% endif %} + {% if form.invoiceText is defined %} + {{ form_row(form.invoiceText) }} + {% endif %}
{{ form_row(form.visible) }} diff --git a/templates/project/edit.html.twig b/templates/project/edit.html.twig index 2096d263..6a0d9af4 100644 --- a/templates/project/edit.html.twig +++ b/templates/project/edit.html.twig @@ -52,6 +52,9 @@
{% endif %} + {% if form.invoiceText is defined %} + {{ form_row(form.invoiceText) }} + {% endif %}
{{ form_row(form.visible) }} diff --git a/tests/Entity/ActivityTest.php b/tests/Entity/ActivityTest.php index ca4a4d2a..cf613b9b 100644 --- a/tests/Entity/ActivityTest.php +++ b/tests/Entity/ActivityTest.php @@ -31,6 +31,7 @@ class ActivityTest extends AbstractEntityTest $this->assertNull($sut->getProject()); $this->assertNull($sut->getName()); $this->assertNull($sut->getComment()); + $this->assertNull($sut->getInvoiceText()); $this->assertTrue($sut->isVisible()); $this->assertTrue($sut->isBillable()); $this->assertTrue($sut->isGlobal()); @@ -66,6 +67,9 @@ class ActivityTest extends AbstractEntityTest $this->assertInstanceOf(Activity::class, $sut->setComment('hello world')); $this->assertEquals('hello world', $sut->getComment()); + $sut->setInvoiceText('very long invoice text comment 12324'); + self::assertEquals('very long invoice text comment 12324', $sut->getInvoiceText()); + self::assertFalse($sut->hasColor()); $sut->setColor('#fffccc'); $this->assertEquals('#fffccc', $sut->getColor()); diff --git a/tests/Entity/ProjectTest.php b/tests/Entity/ProjectTest.php index 3e72515b..78a4bf05 100644 --- a/tests/Entity/ProjectTest.php +++ b/tests/Entity/ProjectTest.php @@ -35,6 +35,7 @@ class ProjectTest extends AbstractEntityTest self::assertNull($sut->getStart()); self::assertNull($sut->getEnd()); self::assertNull($sut->getComment()); + self::assertNull($sut->getInvoiceText()); self::assertTrue($sut->isVisible()); self::assertTrue($sut->isBillable()); self::assertNull($sut->getColor()); @@ -86,6 +87,9 @@ class ProjectTest extends AbstractEntityTest self::assertInstanceOf(Project::class, $sut->setComment('a comment')); self::assertEquals('a comment', $sut->getComment()); + $sut->setInvoiceText('very long invoice text comment 12324'); + self::assertEquals('very long invoice text comment 12324', $sut->getInvoiceText()); + self::assertFalse($sut->hasColor()); $sut->setColor('#fffccc'); self::assertEquals('#fffccc', $sut->getColor()); diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf index d6ff0250..74d5009f 100644 --- a/translations/messages.de.xlf +++ b/translations/messages.de.xlf @@ -293,6 +293,10 @@ label.description Beschreibung + + label.invoiceText + Rechnungstext + label.name Name diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index 6b8d9444..536af04f 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -293,6 +293,10 @@ label.description Description + + label.invoiceText + Invoice text + label.name Name