Improve UX for invoice template management (#4121)
change translations and to explain that calculator actually group items by fields
This commit is contained in:
@@ -16,6 +16,7 @@ use App\Entity\Project;
|
||||
use App\Entity\Timesheet;
|
||||
use App\Entity\User;
|
||||
use App\Invoice\CalculatorInterface;
|
||||
use App\Invoice\InvoiceModel;
|
||||
use App\Repository\Query\InvoiceQuery;
|
||||
use App\Tests\Invoice\DebugFormatter;
|
||||
use App\Tests\Mocks\InvoiceModelFactoryFactory;
|
||||
@@ -23,7 +24,18 @@ use PHPUnit\Framework\TestCase;
|
||||
|
||||
abstract class AbstractCalculatorTest extends TestCase
|
||||
{
|
||||
protected function assertEmptyModel(CalculatorInterface $sut)
|
||||
abstract protected function getCalculator(): CalculatorInterface;
|
||||
|
||||
public function testCalculatorInterface(): void
|
||||
{
|
||||
$sut = $this->getCalculator();
|
||||
|
||||
self::assertLessThanOrEqual(20, \strlen($sut->getId()));
|
||||
|
||||
$this->assertEmptyModel($sut);
|
||||
}
|
||||
|
||||
private function assertEmptyModel(CalculatorInterface $sut): void
|
||||
{
|
||||
$model = $this->getEmptyModel();
|
||||
$this->assertEquals('EUR', $model->getCurrency());
|
||||
@@ -38,7 +50,7 @@ abstract class AbstractCalculatorTest extends TestCase
|
||||
$this->assertEquals(0, $sut->getTax());
|
||||
}
|
||||
|
||||
protected function getEmptyModel()
|
||||
private function getEmptyModel(): InvoiceModel
|
||||
{
|
||||
$customer = new Customer('foo');
|
||||
$template = new InvoiceTemplate();
|
||||
@@ -52,7 +64,7 @@ abstract class AbstractCalculatorTest extends TestCase
|
||||
return $model;
|
||||
}
|
||||
|
||||
protected function assertDescription(CalculatorInterface $sut, $addProject = false, $addActivity = false)
|
||||
protected function assertDescription(CalculatorInterface $sut, $addProject = false, $addActivity = false): void
|
||||
{
|
||||
$customer = new Customer('foo');
|
||||
$template = new InvoiceTemplate();
|
||||
|
||||
@@ -16,6 +16,7 @@ use App\Entity\Project;
|
||||
use App\Entity\Timesheet;
|
||||
use App\Entity\User;
|
||||
use App\Invoice\Calculator\ActivityInvoiceCalculator;
|
||||
use App\Invoice\CalculatorInterface;
|
||||
use App\Repository\Query\InvoiceQuery;
|
||||
use App\Tests\Invoice\DebugFormatter;
|
||||
use App\Tests\Mocks\InvoiceModelFactoryFactory;
|
||||
@@ -28,12 +29,12 @@ use App\Tests\Mocks\InvoiceModelFactoryFactory;
|
||||
*/
|
||||
class ActivityInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
{
|
||||
public function testEmptyModel()
|
||||
protected function getCalculator(): CalculatorInterface
|
||||
{
|
||||
$this->assertEmptyModel(new ActivityInvoiceCalculator());
|
||||
return new ActivityInvoiceCalculator();
|
||||
}
|
||||
|
||||
public function testWithMultipleEntries()
|
||||
public function testWithMultipleEntries(): void
|
||||
{
|
||||
$customer = new Customer('foo');
|
||||
$template = new InvoiceTemplate();
|
||||
@@ -140,7 +141,7 @@ class ActivityInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
$model->addEntries($entries);
|
||||
$model->setQuery($query);
|
||||
|
||||
$sut = new ActivityInvoiceCalculator();
|
||||
$sut = $this->getCalculator();
|
||||
$sut->setModel($model);
|
||||
|
||||
$this->assertEquals('activity', $sut->getId());
|
||||
@@ -149,16 +150,16 @@ class ActivityInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
$this->assertEquals('EUR', $model->getCurrency());
|
||||
$this->assertEquals(2521.12, $sut->getSubtotal());
|
||||
$this->assertEquals(6600, $sut->getTimeWorked());
|
||||
$this->assertEquals(5, \count($sut->getEntries()));
|
||||
|
||||
$entries = $sut->getEntries();
|
||||
self::assertCount(4, $entries);
|
||||
$this->assertEquals(404.38, $entries[0]->getRate());
|
||||
$this->assertEquals(2032.74, $entries[1]->getRate());
|
||||
$this->assertEquals(84, $entries[2]->getRate());
|
||||
}
|
||||
|
||||
public function testDescriptionByActivity()
|
||||
public function testDescriptionByActivity(): void
|
||||
{
|
||||
$this->assertDescription(new ActivityInvoiceCalculator(), false, true);
|
||||
$this->assertDescription($this->getCalculator(), false, true);
|
||||
}
|
||||
}
|
||||
|
||||
181
tests/Invoice/Calculator/ActivityUserInvoiceCalculatorTest.php
Normal file
181
tests/Invoice/Calculator/ActivityUserInvoiceCalculatorTest.php
Normal file
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Tests\Invoice\Calculator;
|
||||
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\InvoiceTemplate;
|
||||
use App\Entity\Project;
|
||||
use App\Entity\Timesheet;
|
||||
use App\Entity\User;
|
||||
use App\Invoice\Calculator\ActivityUserInvoiceCalculator;
|
||||
use App\Invoice\CalculatorInterface;
|
||||
use App\Repository\Query\InvoiceQuery;
|
||||
use App\Tests\Invoice\DebugFormatter;
|
||||
use App\Tests\Mocks\InvoiceModelFactoryFactory;
|
||||
|
||||
/**
|
||||
* @covers \App\Invoice\Calculator\ActivityUserInvoiceCalculator
|
||||
* @covers \App\Invoice\Calculator\AbstractSumInvoiceCalculator
|
||||
* @covers \App\Invoice\Calculator\AbstractMergedCalculator
|
||||
* @covers \App\Invoice\Calculator\AbstractCalculator
|
||||
*/
|
||||
class ActivityUserInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
{
|
||||
protected function getCalculator(): CalculatorInterface
|
||||
{
|
||||
return new ActivityUserInvoiceCalculator();
|
||||
}
|
||||
|
||||
public function testWithMultipleEntries(): void
|
||||
{
|
||||
$customer = new Customer('foo');
|
||||
$template = new InvoiceTemplate();
|
||||
$template->setVat(19);
|
||||
|
||||
$user1 = $this->getMockBuilder(User::class)->onlyMethods(['getId'])->disableOriginalConstructor()->getMock();
|
||||
$user1->method('getId')->willReturn(1);
|
||||
|
||||
$user2 = $this->getMockBuilder(User::class)->onlyMethods(['getId'])->disableOriginalConstructor()->getMock();
|
||||
$user2->method('getId')->willReturn(2);
|
||||
|
||||
$activity1 = $this->getMockBuilder(Activity::class)->onlyMethods(['getId'])->disableOriginalConstructor()->getMock();
|
||||
$activity1->method('getId')->willReturn(1);
|
||||
|
||||
$activity2 = $this->getMockBuilder(Activity::class)->onlyMethods(['getId'])->disableOriginalConstructor()->getMock();
|
||||
$activity2->method('getId')->willReturn(2);
|
||||
|
||||
$activity3 = $this->getMockBuilder(Activity::class)->onlyMethods(['getId'])->disableOriginalConstructor()->getMock();
|
||||
$activity3->method('getId')->willReturn(3);
|
||||
|
||||
$timesheet = new Timesheet();
|
||||
$timesheet
|
||||
->setBegin(new \DateTime())
|
||||
->setEnd(new \DateTime())
|
||||
->setDuration(3600)
|
||||
->setRate(293.27)
|
||||
->setUser($user1)
|
||||
->setActivity($activity1)
|
||||
->setProject((new Project())->setName('bar'));
|
||||
|
||||
$timesheet2 = new Timesheet();
|
||||
$timesheet2
|
||||
->setBegin(new \DateTime())
|
||||
->setEnd(new \DateTime())
|
||||
->setDuration(400)
|
||||
->setRate(84.75)
|
||||
->setUser($user1)
|
||||
->setActivity($activity2)
|
||||
->setProject((new Project())->setName('bar'));
|
||||
|
||||
$timesheet3 = new Timesheet();
|
||||
$timesheet3
|
||||
->setBegin(new \DateTime())
|
||||
->setEnd(new \DateTime())
|
||||
->setDuration(1800)
|
||||
->setRate(111.11)
|
||||
->setUser($user1)
|
||||
->setActivity($activity1)
|
||||
->setProject((new Project())->setName('bar'));
|
||||
|
||||
$timesheet4 = new Timesheet();
|
||||
$timesheet4
|
||||
->setBegin(new \DateTime())
|
||||
->setEnd(new \DateTime())
|
||||
->setDuration(400)
|
||||
->setRate(1947.99)
|
||||
->setUser($user1)
|
||||
->setActivity($activity2)
|
||||
->setProject((new Project())->setName('bar'));
|
||||
|
||||
$timesheet5 = new Timesheet();
|
||||
$timesheet5
|
||||
->setBegin(new \DateTime())
|
||||
->setEnd(new \DateTime())
|
||||
->setDuration(400)
|
||||
->setRate(84)
|
||||
->setUser($user2)
|
||||
->setActivity($activity3)
|
||||
->setProject((new Project())->setName('bar'));
|
||||
|
||||
$timesheet5a = new Timesheet();
|
||||
$timesheet5a
|
||||
->setBegin(new \DateTime())
|
||||
->setEnd(new \DateTime())
|
||||
->setDuration(400)
|
||||
->setRate(84)
|
||||
->setUser($user1)
|
||||
->setActivity($activity3)
|
||||
->setProject((new Project())->setName('bar'));
|
||||
|
||||
$timesheet6 = new Timesheet();
|
||||
$timesheet6
|
||||
->setBegin(new \DateTime())
|
||||
->setEnd(new \DateTime())
|
||||
->setDuration(0)
|
||||
->setRate(0)
|
||||
->setUser($user1)
|
||||
->setProject((new Project())->setName('bar'));
|
||||
|
||||
$timesheet7 = new Timesheet();
|
||||
$timesheet7
|
||||
->setBegin(new \DateTime())
|
||||
->setEnd(new \DateTime())
|
||||
->setDuration(0)
|
||||
->setRate(0)
|
||||
->setUser($user2)
|
||||
->setActivity(new Activity())
|
||||
->setProject((new Project())->setName('bar'));
|
||||
|
||||
$timesheet8 = new Timesheet();
|
||||
$timesheet8
|
||||
->setBegin(new \DateTime())
|
||||
->setEnd(new \DateTime())
|
||||
->setDuration(0)
|
||||
->setRate(0)
|
||||
->setUser($user2)
|
||||
->setProject((new Project())->setName('bar'));
|
||||
|
||||
$entries = [$timesheet, $timesheet2, $timesheet3, $timesheet4, $timesheet5, $timesheet5a, $timesheet6, $timesheet7, $timesheet8];
|
||||
|
||||
$query = new InvoiceQuery();
|
||||
$query->addActivity($activity1);
|
||||
|
||||
$model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter());
|
||||
$model->setCustomer($customer);
|
||||
$model->setTemplate($template);
|
||||
$model->addEntries($entries);
|
||||
$model->setQuery($query);
|
||||
|
||||
$sut = $this->getCalculator();
|
||||
$sut->setModel($model);
|
||||
|
||||
$this->assertEquals('activity_user', $sut->getId());
|
||||
$this->assertEquals(3100.09, $sut->getTotal());
|
||||
$this->assertEquals(19, $sut->getVat());
|
||||
$this->assertEquals('EUR', $model->getCurrency());
|
||||
$this->assertEquals(2605.12, $sut->getSubtotal());
|
||||
$this->assertEquals(7000, $sut->getTimeWorked());
|
||||
|
||||
$entries = $sut->getEntries();
|
||||
self::assertCount(6, $entries);
|
||||
$this->assertEquals(404.38, $entries[0]->getRate());
|
||||
$this->assertEquals(2032.74, $entries[1]->getRate());
|
||||
$this->assertEquals(84.0, $entries[2]->getRate());
|
||||
$this->assertEquals(84.0, $entries[3]->getRate());
|
||||
$this->assertEquals(0, $entries[4]->getRate());
|
||||
$this->assertEquals(0, $entries[5]->getRate());
|
||||
}
|
||||
|
||||
public function testDescriptionByActivity(): void
|
||||
{
|
||||
$this->assertDescription($this->getCalculator(), false, true);
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ use App\Entity\Project;
|
||||
use App\Entity\Timesheet;
|
||||
use App\Entity\User;
|
||||
use App\Invoice\Calculator\DateInvoiceCalculator;
|
||||
use App\Invoice\CalculatorInterface;
|
||||
use App\Repository\Query\InvoiceQuery;
|
||||
use App\Tests\Invoice\DebugFormatter;
|
||||
use App\Tests\Mocks\InvoiceModelFactoryFactory;
|
||||
@@ -29,12 +30,12 @@ use DateTime;
|
||||
*/
|
||||
class DateInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
{
|
||||
public function testEmptyModel()
|
||||
protected function getCalculator(): CalculatorInterface
|
||||
{
|
||||
$this->assertEmptyModel(new DateInvoiceCalculator());
|
||||
return new DateInvoiceCalculator();
|
||||
}
|
||||
|
||||
public function testWithMultipleEntries()
|
||||
public function testWithMultipleEntries(): void
|
||||
{
|
||||
$customer = new Customer('foo');
|
||||
$template = new InvoiceTemplate();
|
||||
@@ -113,7 +114,7 @@ class DateInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
$model->addEntries($entries);
|
||||
$model->setQuery($query);
|
||||
|
||||
$sut = new DateInvoiceCalculator();
|
||||
$sut = $this->getCalculator();
|
||||
$sut->setModel($model);
|
||||
|
||||
$this->assertEquals('date', $sut->getId());
|
||||
@@ -122,7 +123,6 @@ class DateInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
$this->assertEquals('EUR', $model->getCurrency());
|
||||
$this->assertEquals(2521.12, $sut->getSubtotal());
|
||||
$this->assertEquals(6600, $sut->getTimeWorked());
|
||||
$this->assertEquals(3, \count($sut->getEntries()));
|
||||
|
||||
$entries = $sut->getEntries();
|
||||
self::assertCount(3, $entries);
|
||||
@@ -132,8 +132,8 @@ class DateInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
self::assertEquals(2521.12, $entries[0]->getRate() + $entries[1]->getRate() + $entries[2]->getRate());
|
||||
}
|
||||
|
||||
public function testDescriptionByTimesheet()
|
||||
public function testDescriptionByTimesheet(): void
|
||||
{
|
||||
$this->assertDescription(new DateInvoiceCalculator(), false, false);
|
||||
$this->assertDescription($this->getCalculator(), false, false);
|
||||
}
|
||||
}
|
||||
|
||||
143
tests/Invoice/Calculator/DateUserInvoiceCalculatorTest.php
Normal file
143
tests/Invoice/Calculator/DateUserInvoiceCalculatorTest.php
Normal file
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Tests\Invoice\Calculator;
|
||||
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\InvoiceTemplate;
|
||||
use App\Entity\Project;
|
||||
use App\Entity\Timesheet;
|
||||
use App\Entity\User;
|
||||
use App\Invoice\Calculator\DateUserInvoiceCalculator;
|
||||
use App\Invoice\CalculatorInterface;
|
||||
use App\Repository\Query\InvoiceQuery;
|
||||
use App\Tests\Invoice\DebugFormatter;
|
||||
use App\Tests\Mocks\InvoiceModelFactoryFactory;
|
||||
use DateTime;
|
||||
|
||||
/**
|
||||
* @covers \App\Invoice\Calculator\DateUserInvoiceCalculator
|
||||
* @covers \App\Invoice\Calculator\AbstractSumInvoiceCalculator
|
||||
* @covers \App\Invoice\Calculator\AbstractMergedCalculator
|
||||
* @covers \App\Invoice\Calculator\AbstractCalculator
|
||||
*/
|
||||
class DateUserInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
{
|
||||
protected function getCalculator(): CalculatorInterface
|
||||
{
|
||||
return new DateUserInvoiceCalculator();
|
||||
}
|
||||
|
||||
public function testWithMultipleEntries(): void
|
||||
{
|
||||
$customer = new Customer('foo');
|
||||
$template = new InvoiceTemplate();
|
||||
$template->setVat(19);
|
||||
|
||||
$user1 = $this->getMockBuilder(User::class)->onlyMethods(['getId'])->disableOriginalConstructor()->getMock();
|
||||
$user1->method('getId')->willReturn(1);
|
||||
|
||||
$user2 = $this->getMockBuilder(User::class)->onlyMethods(['getId'])->disableOriginalConstructor()->getMock();
|
||||
$user2->method('getId')->willReturn(2);
|
||||
|
||||
$project1 = $this->getMockBuilder(Project::class)->onlyMethods(['getId'])->disableOriginalConstructor()->getMock();
|
||||
$project1->method('getId')->willReturn(1);
|
||||
|
||||
$project2 = $this->getMockBuilder(Project::class)->onlyMethods(['getId'])->disableOriginalConstructor()->getMock();
|
||||
$project2->method('getId')->willReturn(2);
|
||||
|
||||
$project3 = $this->getMockBuilder(Project::class)->onlyMethods(['getId'])->disableOriginalConstructor()->getMock();
|
||||
$project3->method('getId')->willReturn(3);
|
||||
|
||||
$timesheet = new Timesheet();
|
||||
$timesheet
|
||||
->setBegin(new DateTime('2018-11-29'))
|
||||
->setEnd(new DateTime())
|
||||
->setDuration(3600)
|
||||
->setRate(293.27)
|
||||
->setUser($user1)
|
||||
->setActivity((new Activity())->setName('sdsd'))
|
||||
->setProject($project1);
|
||||
|
||||
$timesheet2 = new Timesheet();
|
||||
$timesheet2
|
||||
->setBegin(new DateTime('2018-11-29'))
|
||||
->setEnd(new DateTime())
|
||||
->setDuration(400)
|
||||
->setRate(84.75)
|
||||
->setUser($user1)
|
||||
->setActivity((new Activity())->setName('bar'))
|
||||
->setProject($project2);
|
||||
|
||||
$timesheet3 = new Timesheet();
|
||||
$timesheet3
|
||||
->setBegin(new DateTime('2018-11-28'))
|
||||
->setEnd(new DateTime())
|
||||
->setDuration(1800)
|
||||
->setRate(111.11)
|
||||
->setUser($user1)
|
||||
->setActivity((new Activity())->setName('foo'))
|
||||
->setProject($project1);
|
||||
|
||||
$timesheet4 = new Timesheet();
|
||||
$timesheet4
|
||||
->setBegin(new DateTime())
|
||||
->setEnd(new DateTime())
|
||||
->setDuration(400)
|
||||
->setRate(1947.99)
|
||||
->setUser($user1)
|
||||
->setActivity((new Activity())->setName('blub'))
|
||||
->setProject($project2);
|
||||
|
||||
$timesheet5 = new Timesheet();
|
||||
$timesheet5
|
||||
->setBegin(new DateTime('2018-11-28'))
|
||||
->setEnd(new DateTime())
|
||||
->setDuration(400)
|
||||
->setRate(84)
|
||||
->setUser($user2)
|
||||
->setActivity(new Activity())
|
||||
->setProject($project3);
|
||||
|
||||
$entries = [$timesheet, $timesheet2, $timesheet3, $timesheet4, $timesheet5];
|
||||
|
||||
$query = new InvoiceQuery();
|
||||
$query->setProjects([$project1]);
|
||||
|
||||
$model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter());
|
||||
$model->setCustomer($customer);
|
||||
$model->setTemplate($template);
|
||||
$model->addEntries($entries);
|
||||
$model->setQuery($query);
|
||||
|
||||
$sut = $this->getCalculator();
|
||||
$sut->setModel($model);
|
||||
|
||||
$this->assertEquals('date_user', $sut->getId());
|
||||
$this->assertEquals(3000.13, $sut->getTotal());
|
||||
$this->assertEquals(19, $sut->getVat());
|
||||
$this->assertEquals('EUR', $model->getCurrency());
|
||||
$this->assertEquals(2521.12, $sut->getSubtotal());
|
||||
$this->assertEquals(6600, $sut->getTimeWorked());
|
||||
|
||||
$entries = $sut->getEntries();
|
||||
self::assertCount(4, $entries);
|
||||
$this->assertEquals(378.02, $entries[0]->getRate());
|
||||
$this->assertEquals(111.11, $entries[1]->getRate());
|
||||
$this->assertEquals(1947.99, $entries[2]->getRate());
|
||||
$this->assertEquals(84, $entries[3]->getRate());
|
||||
self::assertEquals(2521.12, $entries[0]->getRate() + $entries[1]->getRate() + $entries[2]->getRate() + $entries[3]->getRate());
|
||||
}
|
||||
|
||||
public function testDescriptionByTimesheet(): void
|
||||
{
|
||||
$this->assertDescription($this->getCalculator(), false, false);
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ use App\Entity\InvoiceTemplate;
|
||||
use App\Entity\Tag;
|
||||
use App\Entity\Timesheet;
|
||||
use App\Invoice\Calculator\DefaultCalculator;
|
||||
use App\Invoice\CalculatorInterface;
|
||||
use App\Repository\Query\InvoiceQuery;
|
||||
use App\Tests\Invoice\DebugFormatter;
|
||||
use App\Tests\Mocks\InvoiceModelFactoryFactory;
|
||||
@@ -25,12 +26,12 @@ use App\Tests\Mocks\InvoiceModelFactoryFactory;
|
||||
*/
|
||||
class DefaultCalculatorTest extends AbstractCalculatorTest
|
||||
{
|
||||
public function testEmptyModel()
|
||||
protected function getCalculator(): CalculatorInterface
|
||||
{
|
||||
$this->assertEmptyModel(new DefaultCalculator());
|
||||
return new DefaultCalculator();
|
||||
}
|
||||
|
||||
public function testWithMultipleEntries()
|
||||
public function testWithMultipleEntries(): void
|
||||
{
|
||||
$date = new \DateTime();
|
||||
$customer = new Customer('foo');
|
||||
@@ -69,7 +70,7 @@ class DefaultCalculatorTest extends AbstractCalculatorTest
|
||||
$model->addEntries($entries);
|
||||
$model->setQuery(new InvoiceQuery());
|
||||
|
||||
$sut = new DefaultCalculator();
|
||||
$sut = $this->getCalculator();
|
||||
$sut->setModel($model);
|
||||
|
||||
$this->assertEquals('default', $sut->getId());
|
||||
|
||||
@@ -15,8 +15,8 @@ use App\Entity\InvoiceTemplate;
|
||||
use App\Entity\Project;
|
||||
use App\Entity\Timesheet;
|
||||
use App\Entity\User;
|
||||
use App\Invoice\Calculator\DateInvoiceCalculator;
|
||||
use App\Invoice\Calculator\PriceInvoiceCalculator;
|
||||
use App\Invoice\CalculatorInterface;
|
||||
use App\Repository\Query\InvoiceQuery;
|
||||
use App\Tests\Invoice\DebugFormatter;
|
||||
use App\Tests\Mocks\InvoiceModelFactoryFactory;
|
||||
@@ -30,12 +30,12 @@ use DateTime;
|
||||
*/
|
||||
class PriceInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
{
|
||||
public function testEmptyModel()
|
||||
protected function getCalculator(): CalculatorInterface
|
||||
{
|
||||
$this->assertEmptyModel(new DateInvoiceCalculator());
|
||||
return new PriceInvoiceCalculator();
|
||||
}
|
||||
|
||||
public function testWithMultipleEntries()
|
||||
public function testWithMultipleEntries(): void
|
||||
{
|
||||
$customer = new Customer('foo');
|
||||
$template = new InvoiceTemplate();
|
||||
@@ -118,7 +118,7 @@ class PriceInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
$model->addEntries($entries);
|
||||
$model->setQuery($query);
|
||||
|
||||
$sut = new PriceInvoiceCalculator();
|
||||
$sut = $this->getCalculator();
|
||||
$sut->setModel($model);
|
||||
|
||||
$this->assertEquals('price', $sut->getId());
|
||||
@@ -136,8 +136,8 @@ class PriceInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
$this->assertEquals(84, $entries[3]->getRate());
|
||||
}
|
||||
|
||||
public function testDescriptionByTimesheet()
|
||||
public function testDescriptionByTimesheet(): void
|
||||
{
|
||||
$this->assertDescription(new PriceInvoiceCalculator(), false, false);
|
||||
$this->assertDescription($this->getCalculator(), false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ use App\Entity\Project;
|
||||
use App\Entity\Timesheet;
|
||||
use App\Entity\User;
|
||||
use App\Invoice\Calculator\ProjectInvoiceCalculator;
|
||||
use App\Invoice\CalculatorInterface;
|
||||
use App\Repository\Query\InvoiceQuery;
|
||||
use App\Tests\Invoice\DebugFormatter;
|
||||
use App\Tests\Mocks\InvoiceModelFactoryFactory;
|
||||
@@ -29,12 +30,12 @@ use DateTime;
|
||||
*/
|
||||
class ProjectInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
{
|
||||
public function testEmptyModel()
|
||||
protected function getCalculator(): CalculatorInterface
|
||||
{
|
||||
$this->assertEmptyModel(new ProjectInvoiceCalculator());
|
||||
return new ProjectInvoiceCalculator();
|
||||
}
|
||||
|
||||
public function testWithMultipleEntries()
|
||||
public function testWithMultipleEntries(): void
|
||||
{
|
||||
$customer = new Customer('foo');
|
||||
$template = new InvoiceTemplate();
|
||||
@@ -113,7 +114,7 @@ class ProjectInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
$model->addEntries($entries);
|
||||
$model->setQuery($query);
|
||||
|
||||
$sut = new ProjectInvoiceCalculator();
|
||||
$sut = $this->getCalculator();
|
||||
$sut->setModel($model);
|
||||
|
||||
$this->assertEquals('project', $sut->getId());
|
||||
@@ -122,7 +123,6 @@ class ProjectInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
$this->assertEquals('EUR', $model->getCurrency());
|
||||
$this->assertEquals(2521.12, $sut->getSubtotal());
|
||||
$this->assertEquals(6600, $sut->getTimeWorked());
|
||||
$this->assertEquals(3, \count($sut->getEntries()));
|
||||
|
||||
$entries = $sut->getEntries();
|
||||
self::assertCount(3, $entries);
|
||||
@@ -132,8 +132,8 @@ class ProjectInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
self::assertEquals(2521.12, $entries[0]->getRate() + $entries[1]->getRate() + $entries[2]->getRate());
|
||||
}
|
||||
|
||||
public function testDescriptionByProject()
|
||||
public function testDescriptionByProject(): void
|
||||
{
|
||||
$this->assertDescription(new ProjectInvoiceCalculator(), true, false);
|
||||
$this->assertDescription($this->getCalculator(), true, false);
|
||||
}
|
||||
}
|
||||
|
||||
142
tests/Invoice/Calculator/ProjectUserInvoiceCalculatorTest.php
Normal file
142
tests/Invoice/Calculator/ProjectUserInvoiceCalculatorTest.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Tests\Invoice\Calculator;
|
||||
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\InvoiceTemplate;
|
||||
use App\Entity\Project;
|
||||
use App\Entity\Timesheet;
|
||||
use App\Entity\User;
|
||||
use App\Invoice\Calculator\ProjectUserInvoiceCalculator;
|
||||
use App\Invoice\CalculatorInterface;
|
||||
use App\Repository\Query\InvoiceQuery;
|
||||
use App\Tests\Invoice\DebugFormatter;
|
||||
use App\Tests\Mocks\InvoiceModelFactoryFactory;
|
||||
use DateTime;
|
||||
|
||||
/**
|
||||
* @covers \App\Invoice\Calculator\ProjectUserInvoiceCalculator
|
||||
* @covers \App\Invoice\Calculator\AbstractSumInvoiceCalculator
|
||||
* @covers \App\Invoice\Calculator\AbstractMergedCalculator
|
||||
* @covers \App\Invoice\Calculator\AbstractCalculator
|
||||
*/
|
||||
class ProjectUserInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
{
|
||||
protected function getCalculator(): CalculatorInterface
|
||||
{
|
||||
return new ProjectUserInvoiceCalculator();
|
||||
}
|
||||
|
||||
public function testWithMultipleEntries(): void
|
||||
{
|
||||
$customer = new Customer('foo');
|
||||
$template = new InvoiceTemplate();
|
||||
$template->setVat(19);
|
||||
|
||||
$user1 = $this->getMockBuilder(User::class)->onlyMethods(['getId'])->disableOriginalConstructor()->getMock();
|
||||
$user1->method('getId')->willReturn(1);
|
||||
|
||||
$user2 = $this->getMockBuilder(User::class)->onlyMethods(['getId'])->disableOriginalConstructor()->getMock();
|
||||
$user2->method('getId')->willReturn(2);
|
||||
|
||||
$project1 = $this->getMockBuilder(Project::class)->onlyMethods(['getId'])->disableOriginalConstructor()->getMock();
|
||||
$project1->method('getId')->willReturn(1);
|
||||
|
||||
$project2 = $this->getMockBuilder(Project::class)->onlyMethods(['getId'])->disableOriginalConstructor()->getMock();
|
||||
$project2->method('getId')->willReturn(2);
|
||||
|
||||
$project3 = $this->getMockBuilder(Project::class)->onlyMethods(['getId'])->disableOriginalConstructor()->getMock();
|
||||
$project3->method('getId')->willReturn(3);
|
||||
|
||||
$timesheet = new Timesheet();
|
||||
$timesheet
|
||||
->setBegin(new DateTime())
|
||||
->setEnd(new DateTime())
|
||||
->setDuration(3600)
|
||||
->setRate(293.27)
|
||||
->setUser($user1)
|
||||
->setActivity((new Activity())->setName('sdsd'))
|
||||
->setProject($project1);
|
||||
|
||||
$timesheet2 = new Timesheet();
|
||||
$timesheet2
|
||||
->setBegin(new DateTime())
|
||||
->setEnd(new DateTime())
|
||||
->setDuration(400)
|
||||
->setRate(84.75)
|
||||
->setUser($user1)
|
||||
->setActivity((new Activity())->setName('bar'))
|
||||
->setProject($project2);
|
||||
|
||||
$timesheet3 = new Timesheet();
|
||||
$timesheet3
|
||||
->setBegin(new DateTime())
|
||||
->setEnd(new DateTime())
|
||||
->setDuration(1800)
|
||||
->setRate(111.11)
|
||||
->setUser($user1)
|
||||
->setActivity((new Activity())->setName('foo'))
|
||||
->setProject($project1);
|
||||
|
||||
$timesheet4 = new Timesheet();
|
||||
$timesheet4
|
||||
->setBegin(new DateTime())
|
||||
->setEnd(new DateTime())
|
||||
->setDuration(400)
|
||||
->setRate(1947.99)
|
||||
->setUser($user1)
|
||||
->setActivity((new Activity())->setName('blub'))
|
||||
->setProject($project2);
|
||||
|
||||
$timesheet5 = new Timesheet();
|
||||
$timesheet5
|
||||
->setBegin(new DateTime())
|
||||
->setEnd(new DateTime())
|
||||
->setDuration(400)
|
||||
->setRate(84)
|
||||
->setUser($user2)
|
||||
->setActivity(new Activity())
|
||||
->setProject($project3);
|
||||
|
||||
$entries = [$timesheet, $timesheet2, $timesheet3, $timesheet4, $timesheet5];
|
||||
|
||||
$query = new InvoiceQuery();
|
||||
$query->setProjects([$project1]);
|
||||
|
||||
$model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter());
|
||||
$model->setCustomer($customer);
|
||||
$model->setTemplate($template);
|
||||
$model->addEntries($entries);
|
||||
$model->setQuery($query);
|
||||
|
||||
$sut = $this->getCalculator();
|
||||
$sut->setModel($model);
|
||||
|
||||
$this->assertEquals('project_user', $sut->getId());
|
||||
$this->assertEquals(3000.13, $sut->getTotal());
|
||||
$this->assertEquals(19, $sut->getVat());
|
||||
$this->assertEquals('EUR', $model->getCurrency());
|
||||
$this->assertEquals(2521.12, $sut->getSubtotal());
|
||||
$this->assertEquals(6600, $sut->getTimeWorked());
|
||||
|
||||
$entries = $sut->getEntries();
|
||||
self::assertCount(3, $entries);
|
||||
$this->assertEquals(404.38, $entries[0]->getRate());
|
||||
$this->assertEquals(2032.74, $entries[1]->getRate());
|
||||
$this->assertEquals(84, $entries[2]->getRate());
|
||||
self::assertEquals(2521.12, $entries[0]->getRate() + $entries[1]->getRate() + $entries[2]->getRate());
|
||||
}
|
||||
|
||||
public function testDescriptionByProject(): void
|
||||
{
|
||||
$this->assertDescription($this->getCalculator(), true, false);
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ use App\Entity\Tag;
|
||||
use App\Entity\Timesheet;
|
||||
use App\Entity\User;
|
||||
use App\Invoice\Calculator\ShortInvoiceCalculator;
|
||||
use App\Invoice\CalculatorInterface;
|
||||
use App\Invoice\InvoiceItem;
|
||||
use App\Repository\Query\InvoiceQuery;
|
||||
use App\Tests\Invoice\DebugFormatter;
|
||||
@@ -29,12 +30,12 @@ use App\Tests\Mocks\InvoiceModelFactoryFactory;
|
||||
*/
|
||||
class ShortInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
{
|
||||
public function testEmptyModel()
|
||||
protected function getCalculator(): CalculatorInterface
|
||||
{
|
||||
$this->assertEmptyModel(new ShortInvoiceCalculator());
|
||||
return new ShortInvoiceCalculator();
|
||||
}
|
||||
|
||||
public function testWithMultipleEntries()
|
||||
public function testWithMultipleEntries(): void
|
||||
{
|
||||
$customer = new Customer('foo');
|
||||
$template = new InvoiceTemplate();
|
||||
@@ -97,7 +98,7 @@ class ShortInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
$model->addEntries($entries);
|
||||
$model->setQuery($query);
|
||||
|
||||
$sut = new ShortInvoiceCalculator();
|
||||
$sut = $this->getCalculator();
|
||||
$sut->setModel($model);
|
||||
|
||||
$this->assertEquals('short', $sut->getId());
|
||||
@@ -119,7 +120,7 @@ class ShortInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
$this->assertEquals(['foo', 'bar', 'bar1'], $result->getTags());
|
||||
}
|
||||
|
||||
public function testWithMultipleEntriesDifferentRates()
|
||||
public function testWithMultipleEntriesDifferentRates(): void
|
||||
{
|
||||
$customer = new Customer('foo');
|
||||
$template = new InvoiceTemplate();
|
||||
@@ -179,7 +180,7 @@ class ShortInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
$model->addEntries($entries);
|
||||
$model->setQuery($query);
|
||||
|
||||
$sut = new ShortInvoiceCalculator();
|
||||
$sut = $this->getCalculator();
|
||||
$sut->setModel($model);
|
||||
|
||||
$this->assertEquals('short', $sut->getId());
|
||||
@@ -200,7 +201,7 @@ class ShortInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
$this->assertEquals(1, $result->getAmount());
|
||||
}
|
||||
|
||||
public function testWithMixedRateTypes()
|
||||
public function testWithMixedRateTypes(): void
|
||||
{
|
||||
$customer = new Customer('foo');
|
||||
$template = new InvoiceTemplate();
|
||||
@@ -258,7 +259,7 @@ class ShortInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
$model->addEntries($entries);
|
||||
$model->setQuery($query);
|
||||
|
||||
$sut = new ShortInvoiceCalculator();
|
||||
$sut = $this->getCalculator();
|
||||
$sut->setModel($model);
|
||||
|
||||
$this->assertEquals('short', $sut->getId());
|
||||
@@ -279,8 +280,8 @@ class ShortInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
$this->assertEquals(1, $result->getAmount());
|
||||
}
|
||||
|
||||
public function testDescriptionByTimesheet()
|
||||
public function testDescriptionByTimesheet(): void
|
||||
{
|
||||
$this->assertDescription(new ShortInvoiceCalculator(), false, false);
|
||||
$this->assertDescription($this->getCalculator(), false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ use App\Entity\Project;
|
||||
use App\Entity\Timesheet;
|
||||
use App\Entity\User;
|
||||
use App\Invoice\Calculator\UserInvoiceCalculator;
|
||||
use App\Invoice\CalculatorInterface;
|
||||
use App\Repository\Query\InvoiceQuery;
|
||||
use App\Tests\Invoice\DebugFormatter;
|
||||
use App\Tests\Mocks\InvoiceModelFactoryFactory;
|
||||
@@ -27,12 +28,12 @@ use App\Tests\Mocks\InvoiceModelFactoryFactory;
|
||||
*/
|
||||
class UserInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
{
|
||||
public function testEmptyModel()
|
||||
protected function getCalculator(): CalculatorInterface
|
||||
{
|
||||
$this->assertEmptyModel(new UserInvoiceCalculator());
|
||||
return new UserInvoiceCalculator();
|
||||
}
|
||||
|
||||
public function testWithMultipleEntries()
|
||||
public function testWithMultipleEntries(): void
|
||||
{
|
||||
$customer = new Customer('foo');
|
||||
$template = new InvoiceTemplate();
|
||||
@@ -111,7 +112,7 @@ class UserInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
$model->addEntries($entries);
|
||||
$model->setQuery($query);
|
||||
|
||||
$sut = new UserInvoiceCalculator();
|
||||
$sut = $this->getCalculator();
|
||||
$sut->setModel($model);
|
||||
|
||||
$this->assertEquals('user', $sut->getId());
|
||||
@@ -120,16 +121,16 @@ class UserInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
$this->assertEquals('EUR', $model->getCurrency());
|
||||
$this->assertEquals(2521.12, $sut->getSubtotal());
|
||||
$this->assertEquals(6600, $sut->getTimeWorked());
|
||||
$this->assertEquals(3, \count($sut->getEntries()));
|
||||
|
||||
$entries = $sut->getEntries();
|
||||
self::assertCount(3, $entries);
|
||||
$this->assertEquals(404.38, $entries[0]->getRate());
|
||||
$this->assertEquals(2032.74, $entries[1]->getRate());
|
||||
$this->assertEquals(84, $entries[2]->getRate());
|
||||
}
|
||||
|
||||
public function testDescriptionByTimesheet()
|
||||
public function testDescriptionByTimesheet(): void
|
||||
{
|
||||
$this->assertDescription(new UserInvoiceCalculator(), false, false);
|
||||
$this->assertDescription($this->getCalculator(), false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ use App\Entity\Project;
|
||||
use App\Entity\Timesheet;
|
||||
use App\Entity\User;
|
||||
use App\Invoice\Calculator\WeeklyInvoiceCalculator;
|
||||
use App\Invoice\CalculatorInterface;
|
||||
use App\Repository\Query\InvoiceQuery;
|
||||
use App\Tests\Invoice\DebugFormatter;
|
||||
use App\Tests\Mocks\InvoiceModelFactoryFactory;
|
||||
@@ -29,12 +30,12 @@ use DateTime;
|
||||
*/
|
||||
class WeeklyInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
{
|
||||
public function testEmptyModel()
|
||||
protected function getCalculator(): CalculatorInterface
|
||||
{
|
||||
$this->assertEmptyModel(new WeeklyInvoiceCalculator());
|
||||
return new WeeklyInvoiceCalculator();
|
||||
}
|
||||
|
||||
public function testWithMultipleEntries()
|
||||
public function testWithMultipleEntries(): void
|
||||
{
|
||||
$customer = new Customer('foo');
|
||||
$template = new InvoiceTemplate();
|
||||
@@ -116,7 +117,7 @@ class WeeklyInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
$model->addEntries($entries);
|
||||
$model->setQuery($query);
|
||||
|
||||
$sut = new WeeklyInvoiceCalculator();
|
||||
$sut = $this->getCalculator();
|
||||
$sut->setModel($model);
|
||||
|
||||
$this->assertEquals('weekly', $sut->getId());
|
||||
@@ -133,8 +134,8 @@ class WeeklyInvoiceCalculatorTest extends AbstractCalculatorTest
|
||||
self::assertEquals(2521.12, $entries[0]->getRate() + $entries[1]->getRate());
|
||||
}
|
||||
|
||||
public function testDescriptionByTimesheet()
|
||||
public function testDescriptionByTimesheet(): void
|
||||
{
|
||||
$this->assertDescription(new WeeklyInvoiceCalculator(), false, false);
|
||||
$this->assertDescription($this->getCalculator(), false, false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user