diff --git a/src/Invoice/Calculator/ActivityInvoiceCalculator.php b/src/Invoice/Calculator/ActivityInvoiceCalculator.php new file mode 100644 index 00000000..22a23229 --- /dev/null +++ b/src/Invoice/Calculator/ActivityInvoiceCalculator.php @@ -0,0 +1,51 @@ +model->getEntries(); + if (empty($entries)) { + return []; + } + + /** @var Timesheet[] $timesheets */ + $timesheets = []; + + foreach ($entries as $entry) { + if (!isset($timesheets[$entry->getActivity()->getId()])) { + $timesheets[$entry->getActivity()->getId()] = new Timesheet(); + } + $timesheet = $timesheets[$entry->getActivity()->getId()]; + $this->mergeTimesheets($timesheet, $entry); + } + + return array_values($timesheets); + } + + /** + * @return string + */ + public function getId(): string + { + return 'activity'; + } +} diff --git a/tests/Invoice/Calculator/ActivityInvoiceCalculatorTest.php b/tests/Invoice/Calculator/ActivityInvoiceCalculatorTest.php new file mode 100644 index 00000000..1e2928c0 --- /dev/null +++ b/tests/Invoice/Calculator/ActivityInvoiceCalculatorTest.php @@ -0,0 +1,129 @@ +assertEmptyModel(new ActivityInvoiceCalculator()); + } + + public function testWithMultipleEntries() + { + $customer = new Customer(); + $template = new InvoiceTemplate(); + $template->setVat(19); + + $user = $this->getMockBuilder(User::class)->setMethods(['getId'])->disableOriginalConstructor()->getMock(); + $user->method('getId')->willReturn(1); + + $activity1 = $this->getMockBuilder(Activity::class)->setMethods(['getId'])->disableOriginalConstructor()->getMock(); + $activity1->method('getId')->willReturn(1); + + $activity2 = $this->getMockBuilder(Activity::class)->setMethods(['getId'])->disableOriginalConstructor()->getMock(); + $activity2->method('getId')->willReturn(2); + + $timesheet = new Timesheet(); + $timesheet + ->setDuration(3600) + ->setRate(293.27) + ->setUser($user) + ->setActivity($activity1) + ; + + $timesheet2 = new Timesheet(); + $timesheet2 + ->setDuration(400) + ->setRate(84.75) + ->setUser($user) + ->setActivity($activity2) + ; + + $timesheet3 = new Timesheet(); + $timesheet3 + ->setDuration(1800) + ->setRate(111.11) + ->setUser($user) + ->setActivity($activity1) + ; + + $timesheet4 = new Timesheet(); + $timesheet4 + ->setDuration(400) + ->setRate(1947.99) + ->setUser($user) + ->setActivity($activity2) + ; + + $timesheet5 = new Timesheet(); + $timesheet5 + ->setDuration(400) + ->setRate(84) + ->setUser(new User()) + ->setActivity(new Activity()) + ; + + $entries = [$timesheet, $timesheet2, $timesheet3, $timesheet4, $timesheet5]; + + $query = new InvoiceQuery(); + $query->setActivity($activity1); + + $model = new InvoiceModel(); + $model->setCustomer($customer); + $model->setTemplate($template); + $model->setEntries($entries); + $model->setQuery($query); + + $sut = new ActivityInvoiceCalculator(); + $sut->setModel($model); + + $this->assertEquals('activity', $sut->getId()); + $this->assertEquals(3000.13, $sut->getTotal()); + $this->assertEquals(19, $sut->getVat()); + $this->assertEquals('EUR', $sut->getCurrency()); + $this->assertEquals(2521.12, $sut->getSubtotal()); + $this->assertEquals(6600, $sut->getTimeWorked()); + $this->assertEquals(3, count($sut->getEntries())); + + $entries = $sut->getEntries(); + $this->assertEquals(404.38, $entries[0]->getRate()); + $this->assertEquals(2032.74, $entries[1]->getRate()); + $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); + } +} diff --git a/translations/invoice-calculator.de.xliff b/translations/invoice-calculator.de.xliff index cd635696..a5b65df7 100644 --- a/translations/invoice-calculator.de.xliff +++ b/translations/invoice-calculator.de.xliff @@ -18,6 +18,10 @@ user Benutzer gruppiert - ein Eintrag pro Benutzer + + activity + Aktivitäten gruppiert - ein Eintrag pro Aktivität + diff --git a/translations/invoice-calculator.en.xliff b/translations/invoice-calculator.en.xliff index c9405b27..52cfbeae 100644 --- a/translations/invoice-calculator.en.xliff +++ b/translations/invoice-calculator.en.xliff @@ -18,6 +18,10 @@ user User grouped - one entry per user + + activity + Activity grouped - one entry per activity +