use timesheet description in invoices (#1079)
This commit is contained in:
@@ -47,11 +47,12 @@ abstract class AbstractMergedCalculator extends AbstractCalculator
|
||||
$invoiceItem->setEnd($entry->getEnd());
|
||||
}
|
||||
|
||||
if (null !== $this->model->getQuery()->getActivity()) {
|
||||
$invoiceItem->setActivity($this->model->getQuery()->getActivity());
|
||||
$invoiceItem->setDescription($this->model->getQuery()->getActivity()->getName());
|
||||
} elseif (null !== $this->model->getQuery()->getProject()) {
|
||||
$invoiceItem->setDescription($this->model->getQuery()->getProject()->getName());
|
||||
if (!empty($entry->getDescription())) {
|
||||
$description = '';
|
||||
if (!empty($invoiceItem->getDescription())) {
|
||||
$description = $invoiceItem->getDescription() . PHP_EOL;
|
||||
}
|
||||
$invoiceItem->setDescription($description . $entry->getDescription());
|
||||
}
|
||||
|
||||
if (null === $invoiceItem->getActivity()) {
|
||||
|
||||
@@ -47,8 +47,14 @@ abstract class AbstractSumInvoiceCalculator extends AbstractMergedCalculator imp
|
||||
}
|
||||
$timesheet = $invoiceItems[$id];
|
||||
$this->mergeTimesheets($timesheet, $entry);
|
||||
$this->mergeSumTimesheet($timesheet, $entry);
|
||||
}
|
||||
|
||||
return array_values($invoiceItems);
|
||||
}
|
||||
|
||||
protected function mergeSumTimesheet(InvoiceItem $invoiceItem, Timesheet $entry)
|
||||
{
|
||||
// allows to set values per calculator after merging the timesheet
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace App\Invoice\Calculator;
|
||||
|
||||
use App\Entity\Timesheet;
|
||||
use App\Invoice\CalculatorInterface;
|
||||
use App\Invoice\InvoiceItem;
|
||||
|
||||
/**
|
||||
* A calculator that sums up the timesheet records by activity.
|
||||
@@ -26,6 +27,12 @@ class ActivityInvoiceCalculator extends AbstractSumInvoiceCalculator implements
|
||||
return (string) $timesheet->getActivity()->getId();
|
||||
}
|
||||
|
||||
protected function mergeSumTimesheet(InvoiceItem $invoiceItem, Timesheet $entry)
|
||||
{
|
||||
$invoiceItem->setActivity($entry->getActivity());
|
||||
$invoiceItem->setDescription($entry->getActivity()->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace App\Invoice\Calculator;
|
||||
|
||||
use App\Entity\Timesheet;
|
||||
use App\Invoice\CalculatorInterface;
|
||||
use App\Invoice\InvoiceItem;
|
||||
|
||||
/**
|
||||
* A calculator that sums up the timesheet records by project.
|
||||
@@ -26,6 +27,12 @@ class ProjectInvoiceCalculator extends AbstractSumInvoiceCalculator implements C
|
||||
return (string) $timesheet->getProject()->getId();
|
||||
}
|
||||
|
||||
protected function mergeSumTimesheet(InvoiceItem $invoiceItem, Timesheet $entry)
|
||||
{
|
||||
$invoiceItem->setProject($entry->getProject());
|
||||
$invoiceItem->setDescription($entry->getProject()->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
||||
@@ -9,37 +9,21 @@
|
||||
|
||||
namespace App\Invoice\Calculator;
|
||||
|
||||
use App\Entity\Timesheet;
|
||||
use App\Invoice\CalculatorInterface;
|
||||
use App\Invoice\InvoiceItem;
|
||||
|
||||
/**
|
||||
* A calculator that sums up the timesheet records by user.
|
||||
*/
|
||||
class UserInvoiceCalculator extends AbstractMergedCalculator implements CalculatorInterface
|
||||
class UserInvoiceCalculator extends AbstractSumInvoiceCalculator implements CalculatorInterface
|
||||
{
|
||||
/**
|
||||
* @return InvoiceItem[]
|
||||
*/
|
||||
public function getEntries()
|
||||
protected function calculateSumIdentifier(Timesheet $timesheet): string
|
||||
{
|
||||
$entries = $this->model->getEntries();
|
||||
if (empty($entries)) {
|
||||
return [];
|
||||
if (null === $timesheet->getUser()->getId()) {
|
||||
throw new \Exception('Cannot handle un-persisted user');
|
||||
}
|
||||
|
||||
/** @var InvoiceItem[] $invoiceItems */
|
||||
$invoiceItems = [];
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
$id = $entry->getUser()->getId();
|
||||
if (!isset($invoiceItems[$id])) {
|
||||
$invoiceItems[$id] = new InvoiceItem();
|
||||
}
|
||||
$invoiceItem = $invoiceItems[$id];
|
||||
$this->mergeTimesheets($invoiceItem, $entry);
|
||||
}
|
||||
|
||||
return array_values($invoiceItems);
|
||||
return (string) $timesheet->getUser()->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -75,9 +75,9 @@
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td>{{ entry.begin|date_short }}</td>
|
||||
<td>
|
||||
<td contenteditable="true">
|
||||
{% if entry.description is not empty %}
|
||||
{{ entry.description }}
|
||||
{{ entry.description|nl2br }}
|
||||
{% else %}
|
||||
{{ entry.activity.name }} / {{ entry.project.name }}
|
||||
{% endif %}
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
<tr>
|
||||
<td contenteditable="true">
|
||||
{% if entry.description is not empty %}
|
||||
{{ entry.description }}
|
||||
{{ entry.description|nl2br }}
|
||||
{% else %}
|
||||
{{ entry.activity.name }} / {{ entry.project.name }}
|
||||
{% endif %}
|
||||
|
||||
@@ -72,9 +72,9 @@
|
||||
{% if model.query.user is empty %}
|
||||
<td>{{ widgets.username(entry.user) }}</td>
|
||||
{% endif %}
|
||||
<td>
|
||||
<td contenteditable="true">
|
||||
{% if entry.description is not empty %}
|
||||
{{ entry.description }}
|
||||
{{ entry.description|nl2br }}
|
||||
{% else %}
|
||||
{{ entry.activity.name }} / {{ entry.project.name }}
|
||||
{% endif %}
|
||||
|
||||
@@ -50,24 +50,19 @@ abstract class AbstractCalculatorTest extends TestCase
|
||||
$template = new InvoiceTemplate();
|
||||
$template->setVat(19);
|
||||
|
||||
$user = $this->getMockBuilder(User::class)->setMethods(['getId'])->disableOriginalConstructor()->getMock();
|
||||
$user->method('getId')->willReturn(1);
|
||||
|
||||
$project = $this->getMockBuilder(Project::class)->setMethods(['getId', 'getCustomer', 'getName'])->disableOriginalConstructor()->getMock();
|
||||
$project->method('getId')->willReturn(1);
|
||||
$project->method('getCustomer')->willReturn($customer);
|
||||
$project->method('getName')->willReturn('project description');
|
||||
|
||||
$project1 = $this->getMockBuilder(Project::class)->setMethods(['getId', 'getName'])->disableOriginalConstructor()->getMock();
|
||||
$project1->method('getId')->willReturn(1);
|
||||
$project1->method('getName')->willReturn('bar');
|
||||
|
||||
$activity = $this->getMockBuilder(Activity::class)->setMethods(['getId', 'getProject', 'getName'])->disableOriginalConstructor()->getMock();
|
||||
$activity->method('getId')->willReturn(1);
|
||||
$activity->method('getProject')->willReturn($project);
|
||||
$activity->method('getName')->willReturn('activity description');
|
||||
|
||||
$activity1 = $this->getMockBuilder(Activity::class)->setMethods(['getId', 'getName'])->disableOriginalConstructor()->getMock();
|
||||
$activity1->method('getId')->willReturn(1);
|
||||
$activity1->method('getName')->willReturn('foo');
|
||||
|
||||
$query = new InvoiceQuery();
|
||||
if ($addProject === true) {
|
||||
$query->setProject($project);
|
||||
@@ -81,9 +76,9 @@ abstract class AbstractCalculatorTest extends TestCase
|
||||
->setBegin(new \DateTime())
|
||||
->setDuration(3600)
|
||||
->setRate(293.27)
|
||||
->setUser(new User())
|
||||
->setActivity($activity1)
|
||||
->setProject($project1);
|
||||
->setUser($user)
|
||||
->setActivity($activity)
|
||||
->setProject($project);
|
||||
|
||||
$model = new InvoiceModel();
|
||||
$model->setCustomer($customer);
|
||||
@@ -101,7 +96,7 @@ abstract class AbstractCalculatorTest extends TestCase
|
||||
} elseif ($addActivity === true) {
|
||||
$this->assertEquals('activity description', $result->getDescription());
|
||||
} else {
|
||||
$this->assertEquals('foo', $result->getDescription());
|
||||
$this->assertEquals('timesheet description', $result->getDescription());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,18 +128,8 @@ class ActivityInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
$this->assertEquals(84, $entries[2]->getRate());
|
||||
}
|
||||
|
||||
public function testDescriptionByTimesheet()
|
||||
{
|
||||
$this->assertDescription(new ActivityInvoiceCalculator(), false, false);
|
||||
}
|
||||
|
||||
public function testDescriptionByActivity()
|
||||
{
|
||||
$this->assertDescription(new ActivityInvoiceCalculator(), false, true);
|
||||
}
|
||||
|
||||
public function testDescriptionByProject()
|
||||
{
|
||||
$this->assertDescription(new ActivityInvoiceCalculator(), true, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,14 +135,4 @@ class DateInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
{
|
||||
$this->assertDescription(new DateInvoiceCalculator(), false, false);
|
||||
}
|
||||
|
||||
public function testDescriptionByActivity()
|
||||
{
|
||||
$this->assertDescription(new DateInvoiceCalculator(), false, true);
|
||||
}
|
||||
|
||||
public function testDescriptionByProject()
|
||||
{
|
||||
$this->assertDescription(new DateInvoiceCalculator(), true, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,18 +35,21 @@ class DefaultCalculatorTest extends AbstractCalculatorTest
|
||||
$template->setVat(19);
|
||||
|
||||
$timesheet = new Timesheet();
|
||||
$timesheet->setDescription('foo 1');
|
||||
$timesheet->setBegin(new \DateTime());
|
||||
$timesheet->setDuration(3600);
|
||||
$timesheet->setRate(293.27);
|
||||
$timesheet->setActivity(new Activity());
|
||||
|
||||
$timesheet2 = new Timesheet();
|
||||
$timesheet2->setDescription('foo 2');
|
||||
$timesheet2->setBegin(new \DateTime());
|
||||
$timesheet2->setDuration(400);
|
||||
$timesheet2->setRate(84);
|
||||
$timesheet2->setActivity(new Activity());
|
||||
|
||||
$timesheet3 = new Timesheet();
|
||||
$timesheet3->setDescription('foo 3');
|
||||
$timesheet3->setBegin(new \DateTime());
|
||||
$timesheet3->setDuration(1800);
|
||||
$timesheet3->setRate(111.11);
|
||||
|
||||
@@ -131,16 +131,6 @@ class ProjectInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
self::assertEquals(2521.12, $entries[0]->getRate() + $entries[1]->getRate() + $entries[2]->getRate());
|
||||
}
|
||||
|
||||
public function testDescriptionByTimesheet()
|
||||
{
|
||||
$this->assertDescription(new ProjectInvoiceCalculator(), false, false);
|
||||
}
|
||||
|
||||
public function testDescriptionByActivity()
|
||||
{
|
||||
$this->assertDescription(new ProjectInvoiceCalculator(), false, true);
|
||||
}
|
||||
|
||||
public function testDescriptionByProject()
|
||||
{
|
||||
$this->assertDescription(new ProjectInvoiceCalculator(), true, false);
|
||||
|
||||
@@ -190,14 +190,4 @@ class ShortInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
{
|
||||
$this->assertDescription(new ShortInvoiceCalculator(), false, false);
|
||||
}
|
||||
|
||||
public function testDescriptionByActivity()
|
||||
{
|
||||
$this->assertDescription(new ShortInvoiceCalculator(), false, true);
|
||||
}
|
||||
|
||||
public function testDescriptionByProject()
|
||||
{
|
||||
$this->assertDescription(new ShortInvoiceCalculator(), true, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,9 @@ class UserInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
$user2 = $this->getMockBuilder(User::class)->setMethods(['getId'])->disableOriginalConstructor()->getMock();
|
||||
$user2->method('getId')->willReturn(2);
|
||||
|
||||
$user3 = $this->getMockBuilder(User::class)->setMethods(['getId'])->disableOriginalConstructor()->getMock();
|
||||
$user3->method('getId')->willReturn(3);
|
||||
|
||||
$timesheet = new Timesheet();
|
||||
$timesheet
|
||||
->setBegin(new \DateTime())
|
||||
@@ -92,7 +95,7 @@ class UserInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
->setEnd(new \DateTime())
|
||||
->setDuration(400)
|
||||
->setRate(84)
|
||||
->setUser(new User())
|
||||
->setUser($user3)
|
||||
->setActivity($activity)
|
||||
->setProject((new Project())->setName('bar'));
|
||||
|
||||
@@ -128,14 +131,4 @@ class UserInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
{
|
||||
$this->assertDescription(new UserInvoiceCalculator(), false, false);
|
||||
}
|
||||
|
||||
public function testDescriptionByActivity()
|
||||
{
|
||||
$this->assertDescription(new UserInvoiceCalculator(), false, true);
|
||||
}
|
||||
|
||||
public function testDescriptionByProject()
|
||||
{
|
||||
$this->assertDescription(new UserInvoiceCalculator(), true, false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user