Release 2.36.1 (#5540)

* fix weekly hours for new entries with non-global activities
* bump packages
* prevent creating invoices with 0 entries
This commit is contained in:
Kevin Papst
2025-06-16 17:53:27 +02:00
committed by GitHub
parent da10099248
commit 59dc82351e
5 changed files with 136 additions and 91 deletions

93
composer.lock generated
View File

@@ -665,16 +665,16 @@
}, },
{ {
"name": "doctrine/dbal", "name": "doctrine/dbal",
"version": "3.9.4", "version": "3.9.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/doctrine/dbal.git", "url": "https://github.com/doctrine/dbal.git",
"reference": "ec16c82f20be1a7224e65ac67144a29199f87959" "reference": "4a4e2eed3134036ee36a147ee0dac037dfa17868"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/ec16c82f20be1a7224e65ac67144a29199f87959", "url": "https://api.github.com/repos/doctrine/dbal/zipball/4a4e2eed3134036ee36a147ee0dac037dfa17868",
"reference": "ec16c82f20be1a7224e65ac67144a29199f87959", "reference": "4a4e2eed3134036ee36a147ee0dac037dfa17868",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -687,14 +687,14 @@
"psr/log": "^1|^2|^3" "psr/log": "^1|^2|^3"
}, },
"require-dev": { "require-dev": {
"doctrine/coding-standard": "12.0.0", "doctrine/coding-standard": "13.0.0",
"fig/log-test": "^1", "fig/log-test": "^1",
"jetbrains/phpstorm-stubs": "2023.1", "jetbrains/phpstorm-stubs": "2023.1",
"phpstan/phpstan": "2.1.1", "phpstan/phpstan": "2.1.17",
"phpstan/phpstan-strict-rules": "^2", "phpstan/phpstan-strict-rules": "^2",
"phpunit/phpunit": "9.6.22", "phpunit/phpunit": "9.6.23",
"slevomat/coding-standard": "8.13.1", "slevomat/coding-standard": "8.16.2",
"squizlabs/php_codesniffer": "3.10.2", "squizlabs/php_codesniffer": "3.13.1",
"symfony/cache": "^5.4|^6.0|^7.0", "symfony/cache": "^5.4|^6.0|^7.0",
"symfony/console": "^4.4|^5.4|^6.0|^7.0" "symfony/console": "^4.4|^5.4|^6.0|^7.0"
}, },
@@ -756,7 +756,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/doctrine/dbal/issues", "issues": "https://github.com/doctrine/dbal/issues",
"source": "https://github.com/doctrine/dbal/tree/3.9.4" "source": "https://github.com/doctrine/dbal/tree/3.9.5"
}, },
"funding": [ "funding": [
{ {
@@ -772,7 +772,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-01-16T08:28:55+00:00" "time": "2025-06-15T22:40:05+00:00"
}, },
{ {
"name": "doctrine/deprecations", "name": "doctrine/deprecations",
@@ -824,16 +824,16 @@
}, },
{ {
"name": "doctrine/doctrine-bundle", "name": "doctrine/doctrine-bundle",
"version": "2.14.0", "version": "2.14.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/doctrine/DoctrineBundle.git", "url": "https://github.com/doctrine/DoctrineBundle.git",
"reference": "ca6a7350b421baf7fbdefbf9f4993292ed18effb" "reference": "0a118222ab21ba05bd9f17fbaa6a3800865274f4"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/ca6a7350b421baf7fbdefbf9f4993292ed18effb", "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/0a118222ab21ba05bd9f17fbaa6a3800865274f4",
"reference": "ca6a7350b421baf7fbdefbf9f4993292ed18effb", "reference": "0a118222ab21ba05bd9f17fbaa6a3800865274f4",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -860,9 +860,9 @@
"require-dev": { "require-dev": {
"doctrine/annotations": "^1 || ^2", "doctrine/annotations": "^1 || ^2",
"doctrine/cache": "^1.11 || ^2.0", "doctrine/cache": "^1.11 || ^2.0",
"doctrine/coding-standard": "^12", "doctrine/coding-standard": "^13",
"doctrine/deprecations": "^1.0", "doctrine/deprecations": "^1.0",
"doctrine/orm": "^2.17 || ^3.0", "doctrine/orm": "^2.17 || ^3.1",
"friendsofphp/proxy-manager-lts": "^1.0", "friendsofphp/proxy-manager-lts": "^1.0",
"phpstan/phpstan": "2.1.1", "phpstan/phpstan": "2.1.1",
"phpstan/phpstan-phpunit": "2.0.3", "phpstan/phpstan-phpunit": "2.0.3",
@@ -926,7 +926,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/doctrine/DoctrineBundle/issues", "issues": "https://github.com/doctrine/DoctrineBundle/issues",
"source": "https://github.com/doctrine/DoctrineBundle/tree/2.14.0" "source": "https://github.com/doctrine/DoctrineBundle/tree/2.14.1"
}, },
"funding": [ "funding": [
{ {
@@ -942,7 +942,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-03-22T17:28:21+00:00" "time": "2025-06-09T20:22:28+00:00"
}, },
{ {
"name": "doctrine/doctrine-migrations-bundle", "name": "doctrine/doctrine-migrations-bundle",
@@ -1463,16 +1463,16 @@
}, },
{ {
"name": "doctrine/orm", "name": "doctrine/orm",
"version": "2.20.3", "version": "2.20.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/doctrine/orm.git", "url": "https://github.com/doctrine/orm.git",
"reference": "17d28b5c4cac212ca92730d9a26e32a0b1516126" "reference": "71550106d491c3f888636b731c805473de3c8583"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/doctrine/orm/zipball/17d28b5c4cac212ca92730d9a26e32a0b1516126", "url": "https://api.github.com/repos/doctrine/orm/zipball/71550106d491c3f888636b731c805473de3c8583",
"reference": "17d28b5c4cac212ca92730d9a26e32a0b1516126", "reference": "71550106d491c3f888636b731c805473de3c8583",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1559,9 +1559,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/doctrine/orm/issues", "issues": "https://github.com/doctrine/orm/issues",
"source": "https://github.com/doctrine/orm/tree/2.20.3" "source": "https://github.com/doctrine/orm/tree/2.20.4"
}, },
"time": "2025-05-02T17:07:53+00:00" "time": "2025-06-09T20:24:12+00:00"
}, },
{ {
"name": "doctrine/persistence", "name": "doctrine/persistence",
@@ -3997,16 +3997,16 @@
}, },
{ {
"name": "phpoffice/math", "name": "phpoffice/math",
"version": "0.2.0", "version": "0.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/PHPOffice/Math.git", "url": "https://github.com/PHPOffice/Math.git",
"reference": "fc2eb6d1a61b058d5dac77197059db30ee3c8329" "reference": "fc31c8f57a7a81f962cbf389fd89f4d9d06fc99a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/PHPOffice/Math/zipball/fc2eb6d1a61b058d5dac77197059db30ee3c8329", "url": "https://api.github.com/repos/PHPOffice/Math/zipball/fc31c8f57a7a81f962cbf389fd89f4d9d06fc99a",
"reference": "fc2eb6d1a61b058d5dac77197059db30ee3c8329", "reference": "fc31c8f57a7a81f962cbf389fd89f4d9d06fc99a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -4043,9 +4043,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/PHPOffice/Math/issues", "issues": "https://github.com/PHPOffice/Math/issues",
"source": "https://github.com/PHPOffice/Math/tree/0.2.0" "source": "https://github.com/PHPOffice/Math/tree/0.3.0"
}, },
"time": "2024-08-12T07:30:45+00:00" "time": "2025-05-29T08:31:49+00:00"
}, },
{ {
"name": "phpoffice/phpspreadsheet", "name": "phpoffice/phpspreadsheet",
@@ -4154,44 +4154,43 @@
}, },
{ {
"name": "phpoffice/phpword", "name": "phpoffice/phpword",
"version": "1.3.0", "version": "1.4.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/PHPOffice/PHPWord.git", "url": "https://github.com/PHPOffice/PHPWord.git",
"reference": "8392134ce4b5dba65130ba956231a1602b848b7f" "reference": "6d75328229bc93790b37e93741adf70646cea958"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/PHPOffice/PHPWord/zipball/8392134ce4b5dba65130ba956231a1602b848b7f", "url": "https://api.github.com/repos/PHPOffice/PHPWord/zipball/6d75328229bc93790b37e93741adf70646cea958",
"reference": "8392134ce4b5dba65130ba956231a1602b848b7f", "reference": "6d75328229bc93790b37e93741adf70646cea958",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-dom": "*", "ext-dom": "*",
"ext-gd": "*",
"ext-json": "*", "ext-json": "*",
"ext-xml": "*", "ext-xml": "*",
"ext-zip": "*",
"php": "^7.1|^8.0", "php": "^7.1|^8.0",
"phpoffice/math": "^0.2" "phpoffice/math": "^0.3"
}, },
"require-dev": { "require-dev": {
"dompdf/dompdf": "^2.0", "dompdf/dompdf": "^2.0 || ^3.0",
"ext-gd": "*",
"ext-libxml": "*", "ext-libxml": "*",
"ext-zip": "*",
"friendsofphp/php-cs-fixer": "^3.3", "friendsofphp/php-cs-fixer": "^3.3",
"mpdf/mpdf": "^8.1", "mpdf/mpdf": "^7.0 || ^8.0",
"phpmd/phpmd": "^2.13", "phpmd/phpmd": "^2.13",
"phpstan/phpstan-phpunit": "@stable", "phpstan/phpstan": "^0.12.88 || ^1.0.0",
"phpstan/phpstan-phpunit": "^1.0 || ^2.0",
"phpunit/phpunit": ">=7.0", "phpunit/phpunit": ">=7.0",
"symfony/process": "^4.4 || ^5.0", "symfony/process": "^4.4 || ^5.0",
"tecnickcom/tcpdf": "^6.5" "tecnickcom/tcpdf": "^6.5"
}, },
"suggest": { "suggest": {
"dompdf/dompdf": "Allows writing PDF", "dompdf/dompdf": "Allows writing PDF",
"ext-gd2": "Allows adding images",
"ext-xmlwriter": "Allows writing OOXML and ODF", "ext-xmlwriter": "Allows writing OOXML and ODF",
"ext-xsl": "Allows applying XSL style sheet to headers, to main document part, and to footers of an OOXML template", "ext-xsl": "Allows applying XSL style sheet to headers, to main document part, and to footers of an OOXML template"
"ext-zip": "Allows writing OOXML and ODF"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@@ -4201,7 +4200,7 @@
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"LGPL-3.0" "LGPL-3.0-only"
], ],
"authors": [ "authors": [
{ {
@@ -4257,9 +4256,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/PHPOffice/PHPWord/issues", "issues": "https://github.com/PHPOffice/PHPWord/issues",
"source": "https://github.com/PHPOffice/PHPWord/tree/1.3.0" "source": "https://github.com/PHPOffice/PHPWord/tree/1.4.0"
}, },
"time": "2024-08-30T18:03:42+00:00" "time": "2025-06-05T10:32:36+00:00"
}, },
{ {
"name": "phpstan/phpdoc-parser", "name": "phpstan/phpdoc-parser",

View File

@@ -41,12 +41,12 @@ final class InvoiceCreateCommand extends Command
private bool $previewUniqueFile = false; private bool $previewUniqueFile = false;
public function __construct( public function __construct(
private ServiceInvoice $serviceInvoice, private readonly ServiceInvoice $serviceInvoice,
private CustomerRepository $customerRepository, private readonly CustomerRepository $customerRepository,
private ProjectRepository $projectRepository, private readonly ProjectRepository $projectRepository,
private InvoiceTemplateRepository $invoiceTemplateRepository, private readonly InvoiceTemplateRepository $invoiceTemplateRepository,
private UserRepository $userRepository, private readonly UserRepository $userRepository,
private EventDispatcherInterface $eventDispatcher private readonly EventDispatcherInterface $eventDispatcher
) { ) {
parent::__construct(); parent::__construct();
} }
@@ -256,9 +256,6 @@ final class InvoiceCreateCommand extends Command
/** /**
* @param Project[] $projects * @param Project[] $projects
* @param InvoiceQuery $defaultQuery
* @param InputInterface $input
* @param OutputInterface $output
* @return Invoice[] * @return Invoice[]
* @throws \Exception * @throws \Exception
*/ */
@@ -287,10 +284,16 @@ final class InvoiceCreateCommand extends Command
$query->setTemplate($tpl); $query->setTemplate($tpl);
try { try {
$model = $this->serviceInvoice->createModel($query);
// this check makes sure to only fetch invoices with records
if (\count($model->getEntries()) === 0) {
continue;
}
if (null !== $this->previewDirectory) { if (null !== $this->previewDirectory) {
$invoices[] = $this->saveInvoicePreview($this->serviceInvoice->renderInvoice($this->serviceInvoice->createModel($query), $this->eventDispatcher)); $invoices[] = $this->saveInvoicePreview($this->serviceInvoice->renderInvoice($model, $this->eventDispatcher));
} else { } else {
$invoices[] = $this->serviceInvoice->createInvoice($this->serviceInvoice->createModel($query), $this->eventDispatcher); $invoices[] = $this->serviceInvoice->createInvoice($model, $this->eventDispatcher);
} }
} catch (\Exception $ex) { } catch (\Exception $ex) {
$io->error(\sprintf('Failed to create invoice for project "%s" with: %s', $project->getName(), $ex->getMessage())); $io->error(\sprintf('Failed to create invoice for project "%s" with: %s', $project->getName(), $ex->getMessage()));
@@ -334,8 +337,6 @@ final class InvoiceCreateCommand extends Command
/** /**
* @param Customer[] $customers * @param Customer[] $customers
* @param InvoiceQuery $defaultQuery
* @param InputInterface $input
* @return Invoice[] * @return Invoice[]
* @throws \Exception * @throws \Exception
*/ */
@@ -358,10 +359,16 @@ final class InvoiceCreateCommand extends Command
$query->setTemplate($tpl); $query->setTemplate($tpl);
try { try {
$model = $this->serviceInvoice->createModel($query);
// this check makes sure to only fetch invoices with records
if (\count($model->getEntries()) === 0) {
continue;
}
if (null !== $this->previewDirectory) { if (null !== $this->previewDirectory) {
$invoices[] = $this->saveInvoicePreview($this->serviceInvoice->renderInvoice($this->serviceInvoice->createModel($query), $this->eventDispatcher)); $invoices[] = $this->saveInvoicePreview($this->serviceInvoice->renderInvoice($model, $this->eventDispatcher));
} else { } else {
$invoices[] = $this->serviceInvoice->createInvoice($this->serviceInvoice->createModel($query), $this->eventDispatcher); $invoices[] = $this->serviceInvoice->createInvoice($model, $this->eventDispatcher);
} }
} catch (\Exception $ex) { } catch (\Exception $ex) {
$io->error(\sprintf('Failed to create invoice for customer "%s" with: %s', $customer->getName(), $ex->getMessage())); $io->error(\sprintf('Failed to create invoice for customer "%s" with: %s', $customer->getName(), $ex->getMessage()));
@@ -372,10 +379,7 @@ final class InvoiceCreateCommand extends Command
} }
/** /**
* @param InputInterface $input
* @param OutputInterface $output
* @param Invoice[] $invoices * @param Invoice[] $invoices
* @return int
*/ */
protected function renderInvoiceResult(InputInterface $input, OutputInterface $output, array $invoices): int protected function renderInvoiceResult(InputInterface $input, OutputInterface $output, array $invoices): int
{ {
@@ -449,7 +453,6 @@ final class InvoiceCreateCommand extends Command
} }
/** /**
* @param InvoiceQuery $invoiceQuery
* @return Customer[] * @return Customer[]
*/ */
private function getActiveCustomers(InvoiceQuery $invoiceQuery): array private function getActiveCustomers(InvoiceQuery $invoiceQuery): array
@@ -467,7 +470,6 @@ final class InvoiceCreateCommand extends Command
} }
/** /**
* @param InvoiceQuery $invoiceQuery
* @return Project[] * @return Project[]
*/ */
private function getActiveProjects(InvoiceQuery $invoiceQuery): array private function getActiveProjects(InvoiceQuery $invoiceQuery): array

View File

@@ -17,11 +17,11 @@ final class Constants
/** /**
* The current release version * The current release version
*/ */
public const VERSION = '2.36.0'; public const VERSION = '2.36.1';
/** /**
* The current release: major * 10000 + minor * 100 + patch * The current release: major * 10000 + minor * 100 + patch
*/ */
public const VERSION_ID = 23600; public const VERSION_ID = 23601;
/** /**
* The software name * The software name
*/ */

View File

@@ -76,6 +76,24 @@ final class QuickEntryWeekType extends AbstractType
}; };
$builder->addEventListener(FormEvents::PRE_SET_DATA, $activityFunction); $builder->addEventListener(FormEvents::PRE_SET_DATA, $activityFunction);
// make sure to pre-fill the form, so non-global activities can be loaded for the select project
$activityPreSubmitFunction = function (FormEvent $event) use ($activityOptions) {
$data = $event->getData();
if (\is_array($data)) {
if (!empty($data['project'])) {
$activityOptions['projects'] = [$data['project']];
}
if (!empty($data['activity'])) {
$activityOptions['activities'] = [$data['activity']];
}
}
$event->getForm()->add('activity', ActivityType::class, $activityOptions);
};
$builder->addEventListener(FormEvents::PRE_SUBMIT, $activityPreSubmitFunction);
$builder->add('metaFields', MetaFieldsCollectionType::class); $builder->add('metaFields', MetaFieldsCollectionType::class);
$builder->add('timesheets', CollectionType::class, [ $builder->add('timesheets', CollectionType::class, [

View File

@@ -158,20 +158,21 @@ class InvoiceCreateCommandTest extends KernelTestCase
public function testCreateWithInvalidCustomer(): void public function testCreateWithInvalidCustomer(): void
{ {
$this->assertCommandErrors(['--user' => UserFixtures::USERNAME_SUPER_ADMIN, '--customer' => 3, '--template' => 'x'], 'Unknown customer ID: 3'); $this->assertCommandErrors(['--user' => UserFixtures::USERNAME_SUPER_ADMIN, '--customer' => PHP_INT_MAX, '--template' => 'x'], 'Unknown customer ID: ' . PHP_INT_MAX);
} }
public function testCreateWithInvalidProject(): void public function testCreateWithInvalidProject(): void
{ {
$this->assertCommandErrors(['--user' => UserFixtures::USERNAME_SUPER_ADMIN, '--project' => 3, '--template' => 'x'], 'Unknown project ID: 3'); $this->assertCommandErrors(['--user' => UserFixtures::USERNAME_SUPER_ADMIN, '--project' => PHP_INT_MAX, '--template' => 'x'], 'Unknown project ID: ' . PHP_INT_MAX);
} }
public function testCreateInvoice(): void public function testCreateInvoice(): void
{ {
$fixture = new InvoiceTemplateFixtures(); $start = new \DateTime('2020-01-01');
$this->importFixture($fixture);
$commandTester = $this->createInvoice(['--user' => UserFixtures::USERNAME_SUPER_ADMIN, '--customer' => 1, '--template' => 'Invoice', '--start' => '2020-01-01', '--end' => '2020-03-01']); $customer = $this->prepareFixtures($start)[0];
$commandTester = $this->createInvoice(['--user' => UserFixtures::USERNAME_SUPER_ADMIN, '--customer' => $customer->getId(), '--template' => 'Invoice', '--start' => '2020-01-01', '--end' => '2020-03-01']);
$output = $commandTester->getDisplay(); $output = $commandTester->getDisplay();
self::assertStringContainsString('Created 1 invoice(s)', $output); self::assertStringContainsString('Created 1 invoice(s)', $output);
@@ -179,15 +180,13 @@ class InvoiceCreateCommandTest extends KernelTestCase
self::assertStringContainsString('| Customer', $output); self::assertStringContainsString('| Customer', $output);
self::assertStringContainsString('| Total', $output); self::assertStringContainsString('| Total', $output);
self::assertStringContainsString('| Filename', $output); self::assertStringContainsString('| Filename', $output);
self::assertStringContainsString('0 EUR', $output); self::assertStringContainsString('/tests/_data/invoices/' . ((new \DateTime())->format('Y')) . '-001', $output);
self::assertStringContainsString('/tests/_data/invoices/' . ((new \DateTime())->format('Y')) . '-001-Test.html |', $output);
} }
/** /**
* @param \DateTime $start * @return array{0: Customer, 1: Project}
* @return array<Customer>
*/ */
protected function prepareFixtures(\DateTime $start): array protected function prepareFixtures(\DateTime $start, bool $withTimesheets = true): array
{ {
$fixture = new InvoiceTemplateFixtures(); $fixture = new InvoiceTemplateFixtures();
$invoiceTemplate = $this->importFixture($fixture); $invoiceTemplate = $this->importFixture($fixture);
@@ -204,14 +203,16 @@ class InvoiceCreateCommandTest extends KernelTestCase
$fixture->setAmount(1); $fixture->setAmount(1);
$projects = $this->importFixture($fixture); $projects = $this->importFixture($fixture);
$fixture = new TimesheetFixtures(); if ($withTimesheets) {
$fixture->setUser($this->getUserByName(UserFixtures::USERNAME_SUPER_ADMIN)); $fixture = new TimesheetFixtures();
$fixture->setAmount(20); $fixture->setUser($this->getUserByName(UserFixtures::USERNAME_SUPER_ADMIN));
$fixture->setStartDate($start); $fixture->setAmount(20);
$fixture->setProjects($projects); $fixture->setStartDate($start);
$this->importFixture($fixture); $fixture->setProjects($projects);
$this->importFixture($fixture);
}
return [$customer]; return [$customer, $projects[0]];
} }
public function testCreateInvoiceByCustomer(): void public function testCreateInvoiceByCustomer(): void
@@ -232,15 +233,27 @@ class InvoiceCreateCommandTest extends KernelTestCase
$start = new \DateTime('-2 months'); $start = new \DateTime('-2 months');
$end = new \DateTime(); $end = new \DateTime();
$imports = $this->prepareFixtures($start); $customer = $this->prepareFixtures($start)[0];
$customer = $imports[0]->getId();
$commandTester = $this->createInvoice(['--user' => UserFixtures::USERNAME_SUPER_ADMIN, '--customer' => $customer . ',1', '--start' => $start->format('Y-m-d'), '--end' => $end->format('Y-m-d')]); $commandTester = $this->createInvoice(['--user' => UserFixtures::USERNAME_SUPER_ADMIN, '--customer' => $customer->getId(), '--start' => $start->format('Y-m-d'), '--end' => $end->format('Y-m-d')]);
$output = $commandTester->getDisplay(); $output = $commandTester->getDisplay();
self::assertStringContainsString('Created 1 invoice(s) ', $output); self::assertStringContainsString('Created 1 invoice(s) ', $output);
} }
public function testCreateInvoiceByCustomerIdWithoutTimesheets(): void
{
$start = new \DateTime('-2 months');
$end = new \DateTime();
$customer = $this->prepareFixtures($start, false)[0];
$commandTester = $this->createInvoice(['--user' => UserFixtures::USERNAME_SUPER_ADMIN, '--customer' => $customer->getId(), '--start' => $start->format('Y-m-d'), '--end' => $end->format('Y-m-d')]);
$output = $commandTester->getDisplay();
self::assertStringContainsString('No invoice was generated', $output);
}
public function testCreateInvoiceByProject(): void public function testCreateInvoiceByProject(): void
{ {
$start = new \DateTime('-2 months'); $start = new \DateTime('-2 months');
@@ -259,14 +272,27 @@ class InvoiceCreateCommandTest extends KernelTestCase
$start = new \DateTime('-2 months'); $start = new \DateTime('-2 months');
$end = new \DateTime(); $end = new \DateTime();
$this->prepareFixtures($start); $project = $this->prepareFixtures($start)[1];
$commandTester = $this->createInvoice(['--user' => UserFixtures::USERNAME_SUPER_ADMIN, '--exported' => 'all', '--project' => '1', '--template' => 'Invoice', '--start' => $start->format('Y-m-d'), '--end' => $end->format('Y-m-d')]); $commandTester = $this->createInvoice(['--user' => UserFixtures::USERNAME_SUPER_ADMIN, '--exported' => 'all', '--project' => $project->getId(), '--template' => 'Invoice', '--start' => $start->format('Y-m-d'), '--end' => $end->format('Y-m-d')]);
$output = $commandTester->getDisplay(); $output = $commandTester->getDisplay();
self::assertStringContainsString('Created 1 invoice(s) ', $output); self::assertStringContainsString('Created 1 invoice(s) ', $output);
} }
public function testCreateInvoiceByProjectIdWithoutTimesheets(): void
{
$start = new \DateTime('-2 months');
$end = new \DateTime();
$project = $this->prepareFixtures($start, false)[1];
$commandTester = $this->createInvoice(['--user' => UserFixtures::USERNAME_SUPER_ADMIN, '--exported' => 'all', '--project' => $project->getId(), '--template' => 'Invoice', '--start' => $start->format('Y-m-d'), '--end' => $end->format('Y-m-d')]);
$output = $commandTester->getDisplay();
self::assertStringContainsString('No invoice was generated', $output);
}
public function testCreateInvoiceByProjectWithPreview(): void public function testCreateInvoiceByProjectWithPreview(): void
{ {
$start = new \DateTime('-2 months'); $start = new \DateTime('-2 months');