Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better invoices #3079

Merged
merged 5 commits into from
Jan 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/Command/InvoiceCreateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -337,9 +337,10 @@ protected function createInvoicesForProjects(array $projects, InvoiceQuery $defa
return $invoices;
}

private function saveInvoicePreview(Response $response)
private function saveInvoicePreview(Response $response): string
{
$filename = uniqid('invoice_');
$directory = rtrim($this->previewDirectory, '/') . '/';

if ($response->headers->has('Content-Disposition')) {
$disposition = $response->headers->get('Content-Disposition');
Expand All @@ -360,12 +361,12 @@ private function saveInvoicePreview(Response $response)

if ($response instanceof BinaryFileResponse) {
$file = $response->getFile();
$file->move($this->previewDirectory, $filename);
$file->move($directory, $filename);
} else {
(new Filesystem())->dumpFile($this->previewDirectory . $filename, $response->getContent());
(new Filesystem())->dumpFile($directory . $filename, $response->getContent());
}

return $this->previewDirectory . $filename;
return $directory . $filename;
}

/**
Expand Down
13 changes: 9 additions & 4 deletions src/Event/InvoiceCreatedEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,27 @@
namespace App\Event;

use App\Entity\Invoice;
use App\Invoice\InvoiceModel;
use Symfony\Contracts\EventDispatcher\Event;

final class InvoiceCreatedEvent extends Event
{
/**
* @var Invoice
*/
private $invoice;
private $model;

public function __construct(Invoice $invoice)
public function __construct(Invoice $invoice, InvoiceModel $model)
{
$this->invoice = $invoice;
$this->model = $model;
}

public function getInvoice(): Invoice
{
return $this->invoice;
}

public function getInvoiceModel(): InvoiceModel
{
return $this->model;
}
}
79 changes: 38 additions & 41 deletions src/Invoice/DefaultInvoiceFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,74 +14,71 @@

final class DefaultInvoiceFormatter implements InvoiceFormatter
{
private $locale;
private $formats;
/**
* @var LocaleFormatter
* @var LocaleFormatter|null
*/
private $formatter;

public function __construct(LanguageFormattings $formats, string $locale)
{
$this->formatter = new LocaleFormatter($formats, $locale);
$this->formats = $formats;
$this->locale = $locale;
}

/**
* @param \DateTime $date
* @return mixed
*/
public function getFormattedDateTime(\DateTime $date)
private function getFormatter(): LocaleFormatter
{
return $this->formatter->dateShort($date);
if ($this->formatter === null) {
$this->formatter = new LocaleFormatter($this->formats, $this->locale);
}

return $this->formatter;
}

/**
* @param \DateTime $date
* @return mixed
*/
public function getFormattedTime(\DateTime $date)
public function getFormattedDateTime(\DateTime $date): string
{
return $this->formatter->time($date);
return $this->getFormatter()->dateShort($date);
}

/**
* @param \DateTime $date
* @return mixed
*/
public function getFormattedMonthName(\DateTime $date)
public function getFormattedTime(\DateTime $date): string
{
return $this->formatter->monthName($date);
return $this->getFormatter()->time($date);
}

/**
* @param float|int $amount
* @param string|null $currency
* @param bool $withCurrency
* @return string
*/
public function getFormattedMoney($amount, ?string $currency, bool $withCurrency = true)
public function getFormattedMonthName(\DateTime $date): string
{
return $this->formatter->money($amount, $currency, $withCurrency);
return $this->getFormatter()->monthName($date);
}

/**
* @param int $seconds
* @return mixed
*/
public function getFormattedDuration($seconds)
public function getFormattedMoney(float $amount, ?string $currency, bool $withCurrency = true): string
{
return $this->formatter->duration($seconds);
return $this->getFormatter()->money($amount, $currency, $withCurrency);
}

/**
* @param int $seconds
* @return mixed
*/
public function getFormattedDecimalDuration($seconds)
public function getFormattedDuration(int $seconds): string
{
return $this->getFormatter()->duration($seconds);
}

public function getFormattedDecimalDuration(int $seconds): string
{
return $this->formatter->durationDecimal($seconds);
return $this->getFormatter()->durationDecimal($seconds);
}

public function getCurrencySymbol(string $currency): string
{
return $this->formatter->currency($currency);
return $this->getFormatter()->currency($currency);
}

public function getLocale(): string
{
return $this->locale;
}

public function setLocale(string $locale): void
{
$this->locale = $locale;
$this->formatter = null;
}
}
48 changes: 10 additions & 38 deletions src/Invoice/InvoiceFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,49 +16,21 @@
*/
interface InvoiceFormatter
{
/**
* @param DateTime $date
* @return mixed
*/
public function getFormattedDateTime(DateTime $date);
public function getLocale(): string;

/**
* @param DateTime $date
* @return mixed
*/
public function getFormattedTime(DateTime $date);
public function setLocale(string $locale): void;

/**
* @param int|float $amount
* @param string|null $currency
* @param bool $withCurrency
* @return string
*/
public function getFormattedMoney($amount, ?string $currency, bool $withCurrency = true);
public function getFormattedDateTime(DateTime $date): string;

/**
* @param DateTime $date
* @return mixed
*/
public function getFormattedMonthName(DateTime $date);
public function getFormattedTime(DateTime $date): string;

/**
* @param int $seconds
* @return mixed
*/
public function getFormattedDuration($seconds);
public function getFormattedMoney(float $amount, ?string $currency, bool $withCurrency = true): string;

/**
* @param int $seconds
* @return mixed
*/
public function getFormattedDecimalDuration($seconds);
public function getFormattedMonthName(DateTime $date): string;

public function getFormattedDuration(int $seconds): string;

public function getFormattedDecimalDuration(int $seconds): string;

/**
* Returns the currency symbol for the given currency by name.
*
* @param string $currency
* @return string
*/
public function getCurrencySymbol(string $currency): string;
}
2 changes: 1 addition & 1 deletion src/Invoice/ServiceInvoice.php
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ public function createInvoiceFromModel(InvoiceModel $model, EventDispatcherInter
$this->markEntriesAsExported($model->getEntries());
}

$dispatcher->dispatch(new InvoiceCreatedEvent($invoice));
$dispatcher->dispatch(new InvoiceCreatedEvent($invoice, $model));

return $invoice;
}
Expand Down
6 changes: 5 additions & 1 deletion tests/Event/InvoiceCreatedEventTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

use App\Entity\Invoice;
use App\Event\InvoiceCreatedEvent;
use App\Tests\Invoice\DebugFormatter;
use App\Tests\Mocks\InvoiceModelFactoryFactory;
use PHPUnit\Framework\TestCase;

/**
Expand All @@ -21,9 +23,11 @@ class InvoiceCreatedEventTest extends TestCase
public function testDefaultValues()
{
$invoice = new Invoice();
$model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter());

$sut = new InvoiceCreatedEvent($invoice);
$sut = new InvoiceCreatedEvent($invoice, $model);

self::assertSame($invoice, $sut->getInvoice());
self::assertSame($model, $sut->getInvoiceModel());
}
}
23 changes: 23 additions & 0 deletions tests/EventSubscriber/Actions/InvoiceSubscriberTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?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\EventSubscriber\Actions;

use App\EventSubscriber\Actions\InvoiceSubscriber;

/**
* @covers \App\EventSubscriber\Actions\InvoiceSubscriber
*/
class InvoiceSubscriberTest extends AbstractActionsSubscriberTest
{
public function testEventName()
{
$this->assertGetSubscribedEvent(InvoiceSubscriber::class, 'invoice');
}
}
52 changes: 18 additions & 34 deletions tests/Invoice/DebugFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,17 @@

class DebugFormatter implements InvoiceFormatter
{
/**
* @param \DateTime $date
* @return mixed
*/
public function getFormattedDateTime(\DateTime $date)
public function getFormattedDateTime(\DateTime $date): string
{
return $date->format('d.m.Y');
}

/**
* @param \DateTime $date
* @return mixed
*/
public function getFormattedTime(\DateTime $date)
public function getFormattedTime(\DateTime $date): string
{
return $date->format('H:i');
}

/**
* @param int|float $amount
* @param string|null $currency
* @param bool $withCurrency
* @return string
*/
public function getFormattedMoney($amount, ?string $currency, bool $withCurrency = true)
public function getFormattedMoney(float $amount, ?string $currency, bool $withCurrency = true): string
{
if (null === $currency) {
$withCurrency = false;
Expand All @@ -50,35 +36,33 @@ public function getFormattedMoney($amount, ?string $currency, bool $withCurrency
return (string) $amount;
}

/**
* @param \DateTime $date
* @return mixed
*/
public function getFormattedMonthName(\DateTime $date)
public function getFormattedMonthName(\DateTime $date): string
{
return $date->format('m');
}

/**
* @param mixed $seconds
* @return mixed
*/
public function getFormattedDuration($seconds)
public function getFormattedDuration(int $seconds): string
{
return $seconds;
return (string) $seconds;
}

/**
* @param mixed $seconds
* @return mixed
*/
public function getFormattedDecimalDuration($seconds)
public function getFormattedDecimalDuration(int $seconds): string
{
return $seconds;
return (string) $seconds;
}

public function getCurrencySymbol(string $currency): string
{
return $currency;
}

public function getLocale(): string
{
return 'en';
}

public function setLocale(string $locale): void
{
// does nothing
}
}