getInvoiceTemplatePath() . $filename) ); } return new InvoiceDocument( new \SplFileInfo(__DIR__ . '/../templates/' . $filename) ); } /** * @param class-string $classname */ protected function getAbstractRenderer(string $classname): AbstractRenderer { $t = new $classname(); if (!$t instanceof AbstractRenderer) { throw new \InvalidArgumentException('Not an instance of AbstractRenderer: ' . \get_class($t)); } return $t; } protected function getFormatter(): InvoiceFormatter { $languages = [ 'en' => [ 'date' => 'yy.MM.dd', 'time' => 'H:i', 'rtl' => false, 'translation' => true, ] ]; $formattings = new LocaleService($languages); return new DefaultInvoiceFormatter($formattings, 'en'); } protected function getInvoiceModel(): InvoiceModel { $user = new User(); $user->setUserIdentifier('one-user'); $user->setTitle('user title'); $user->setAlias('genious alias'); $user->setEmail('fantastic@four'); $user->addPreference(new UserPreference('kitty', 'kat')); $user->addPreference(new UserPreference('hello', 'world')); $customer = new Customer('customer,with/special#name'); $customer->setAddress('Foo' . PHP_EOL . 'Street' . PHP_EOL . '1111 City'); $customer->setCurrency('EUR'); $customer->setCountry('AT'); $customer->setMetaField((new CustomerMeta())->setName('foo-customer')->setValue('bar-customer')->setIsVisible(true)); $template = new InvoiceTemplate(); $template->setTitle('a very *long* test invoice / template title with [ßpecial] chäracter'); $template->setVat(19); $template->setLanguage('en'); $template->setCustomer($customer); $pMeta = new ProjectMeta(); $pMeta->setName('foo-project')->setValue('bar-project')->setIsVisible(true); $project = $this->createMock(Project::class); $project->method('getId')->willReturn(0); $project->method('getName')->willReturn('project name'); $project->method('getCustomer')->willReturn($customer); $project->method('getMetaFields')->willReturn(new ArrayCollection([$pMeta])); $project->method('getVisibleMetaFields')->willReturn([$pMeta]); $aMeta = new ActivityMeta(); $aMeta->setName('foo-activity'); $aMeta->setValue('bar-activity'); $aMeta->setIsVisible(true); $activity = $this->createMock(Activity::class); $activity->method('getId')->willReturn(0); $activity->method('getName')->willReturn('activity description'); $activity->method('getProject')->willReturn($project); $activity->method('getMetaFields')->willReturn(new ArrayCollection([$aMeta])); $activity->method('getVisibleMetaFields')->willReturn([$aMeta]); $pMeta2 = new ProjectMeta(); $pMeta2->setName('foo-project')->setValue('bar-project2')->setIsVisible(true); $project2 = $this->createMock(Project::class); $project2->method('getId')->willReturn(1); $project2->method('getName')->willReturn('project 2 name'); $project2->method('getCustomer')->willReturn($customer); $project2->method('getMetaFields')->willReturn(new ArrayCollection([$pMeta2])); $project2->method('getVisibleMetaFields')->willReturn([$pMeta2]); $aMeta2 = new ActivityMeta(); $aMeta2->setName('foo-activity'); $aMeta2->setValue('bar-activity2'); $aMeta2->setIsVisible(true); $activity2 = $this->createMock(Activity::class); $activity2->method('getId')->willReturn(1); $activity2->method('getName')->willReturn('activity 1 description'); $activity2->method('getProject')->willReturn($project2); $activity2->method('getMetaFields')->willReturn(new ArrayCollection([$aMeta2])); $activity2->method('getVisibleMetaFields')->willReturn([$aMeta2]); $pref1 = new UserPreference('foo', 'bar'); $pref2 = new UserPreference('mad', 123.45); $userMethods = ['getId', 'getPreferenceValue', 'getVisiblePreferences', 'getUsername', 'getUserIdentifier']; $user1 = $this->getMockBuilder(User::class)->onlyMethods($userMethods)->disableOriginalConstructor()->getMock(); $user1->method('getId')->willReturn(1); $user1->method('getPreferenceValue')->willReturn('50'); $user1->method('getUsername')->willReturn('foo-bar'); $user1->method('getUserIdentifier')->willReturn('foo-bar'); $user1->method('getVisiblePreferences')->willReturn([$pref1, $pref2]); $user2 = $this->createMock(User::class); $user2->method('getId')->willReturn(2); $user2->method('getUsername')->willReturn('hello-world'); $user2->method('getUserIdentifier')->willReturn('hello-world'); $user2->method('getVisiblePreferences')->willReturn([$pref1, $pref2]); $timesheet = new Timesheet(); $timesheet->setDuration(3600); $timesheet->setRate(293.27); $timesheet->setUser($user1); $timesheet->setActivity($activity); $timesheet->setProject($project); $timesheet->setBegin(new \DateTime('2020-12-13 14:00:00')); $timesheet->setEnd(new \DateTime('2020-12-13 15:00:00')); $timesheet->setMetaField((new TimesheetMeta())->setName('foo-timesheet')->setValue('bar-timesheet')->setIsVisible(true)); $timesheet2 = new Timesheet(); $timesheet2->setDuration(400); $timesheet2->setRate(84.75); $timesheet2->setUser($user2); $timesheet2->setActivity($activity); $timesheet2->setProject($project); $timesheet2->setBegin(new \DateTime('2020-08-13 14:00:00')); $timesheet2->setEnd(new \DateTime('2020-08-13 14:06:40')); $timesheet2->setMetaField((new TimesheetMeta())->setName('foo-timesheet')->setValue('bar-timesheet')); $timesheet2->setMetaField((new TimesheetMeta())->setName('foo-timesheet2')->setValue('bar-timesheet2')->setIsVisible(true)); $timesheet3 = new Timesheet(); $timesheet3->setDuration(1800); $timesheet3->setRate(111.11); $timesheet3->setUser($user1); $timesheet3->setActivity($activity2); $timesheet3->setDescription('== jhg ljhg '); // make sure that spreadsheets don't render it as formula $timesheet3->setProject($project2); $timesheet3->setBegin(new \DateTime('2020-08-12 18:00:00')); $timesheet3->setEnd(new \DateTime('2020-08-12 18:30:00')); $timesheet3->setMetaField((new TimesheetMeta())->setName('foo-timesheet')->setValue('bar-timesheet1')->setIsVisible(true)); $timesheet4 = new Timesheet(); $timesheet4->setDuration(400); $timesheet4->setRate(1947.99); $timesheet4->setUser($user2); $timesheet4->setActivity($activity); $timesheet4->setProject($project); $timesheet4->setBegin(new \DateTime('2020-12-13 14:00:00')); $timesheet4->setEnd(new \DateTime('2020-12-13 14:06:40')); $timesheet4->setDescription( "foo\n" . "foo\r\n" . 'foo' . PHP_EOL . "bar\n" . "bar\r\n" . 'Hello' ); $timesheet4->setMetaField((new TimesheetMeta())->setName('foo-timesheet3')->setValue('bluuuub')->setIsVisible(true)); $userKevin = new User(); $userKevin->setUserIdentifier('kevin'); $userKevin->addPreference($pref1); $userKevin->addPreference($pref2); $timesheet5 = new Timesheet(); $timesheet5->setDuration(400); $timesheet5->setFixedRate(84); $timesheet5->setUser($userKevin); $timesheet5->setActivity($activity); $timesheet5->setProject($project); $timesheet5->setBegin(new \DateTime('2021-03-12 12:13:00')); $timesheet5->setEnd(new \DateTime('2021-03-12 12:17:40')); $timesheet5->setDescription( "foo\n" . "foo\r\n" . 'foo' . PHP_EOL . "bar\n" . "bar\r\n" . 'Hello' ); $entries = [$timesheet, $timesheet2, $timesheet3, $timesheet4, $timesheet5]; $query = new InvoiceQuery(); $query->setActivities([$activity, $activity2]); $query->setBegin(new \DateTime()); $query->setEnd(new \DateTime()); $query->setProjects([$project, $project2]); $model = (new InvoiceModelFactoryFactory($this))->create()->createModel($this->getFormatter(), $customer, $template, $query); $model->addEntries($entries); $model->setUser($user); $calculator = new DefaultCalculator(); $calculator->setModel($model); $model->setCalculator($calculator); $numberGenerator = $this->getNumberGeneratorSut(); $numberGenerator->setModel($model); $model->setNumberGenerator($numberGenerator); return $model; } private function getNumberGeneratorSut(): NumberGeneratorInterface { $repository = $this->createMock(InvoiceRepository::class); $repository ->expects($this->any()) ->method('hasInvoice') ->willReturn(false); return new DateNumberGenerator($repository); } protected function getInvoiceModelOneEntry(): InvoiceModel { $user = new User(); $user->setUserIdentifier('one-user'); $user->setTitle('user title'); $user->setAlias('genious alias'); $user->setEmail('fantastic@four'); $user->addPreference(new UserPreference('kitty', 'kat')); $user->addPreference(new UserPreference('hello', 'world')); $customer = new Customer('customer,with/special#name'); $customer->setCountry('DE'); $customer->setCurrency('USD'); $customer->setMetaField((new CustomerMeta())->setName('foo-customer')->setValue('bar-customer')->setIsVisible(true)); $template = new InvoiceTemplate(); $template->setTitle('a test invoice template title'); $template->setVat(19); $template->setLanguage('it'); $template->setCustomer($customer); $project = new Project(); $project->setName('project name'); $project->setCustomer($customer); $project->setMetaField((new ProjectMeta())->setName('foo-project')->setValue('bar-project')->setIsVisible(true)); $activity = new Activity(); $activity->setName('activity description'); $activity->setProject($project); $activity->setMetaField((new ActivityMeta())->setName('foo-activity')->setValue('bar-activity')->setIsVisible(true)); $pref1 = new UserPreference('foo', 'bar'); $pref2 = new UserPreference('mad', 123.45); $user1 = $this->createMock(User::class); $user1->method('getId')->willReturn(1); $user1->method('getPreferenceValue')->willReturn('50'); $user1->method('getUsername')->willReturn('foo-bar'); $user1->method('getUserIdentifier')->willReturn('foo-bar'); $user1->method('getVisiblePreferences')->willReturn([$pref1, $pref2]); $timesheet = new Timesheet(); $timesheet->setDuration(3600); $timesheet->setRate(293.27); $timesheet->setUser($user1); $timesheet->setActivity($activity); $timesheet->setProject($project); $timesheet->setBegin(new \DateTime('2020-08-12 18:00:00')); $timesheet->setEnd(new \DateTime('2021-03-12 18:30:00')); $entries = [$timesheet]; $query = new InvoiceQuery(); $query->addActivity($activity); $query->addProject($project); $query->setBegin(new \DateTime()); $query->setEnd(new \DateTime()); $model = (new InvoiceModelFactoryFactory($this))->create()->createModel($this->getFormatter(), $customer, $template, $query); $model->addEntries($entries); $model->setUser($user); $calculator = new DefaultCalculator(); $calculator->setModel($model); $model->setCalculator($calculator); $numberGenerator = $this->getNumberGeneratorSut(); $numberGenerator->setModel($model); $model->setNumberGenerator($numberGenerator); return $model; } }