added command to create invoices via bash (#1574)
This commit is contained in:
@@ -11,10 +11,17 @@ namespace App\Invoice;
|
||||
|
||||
use App\Entity\Invoice;
|
||||
use App\Entity\InvoiceDocument;
|
||||
use App\Event\InvoiceCreatedEvent;
|
||||
use App\Event\InvoicePostRenderEvent;
|
||||
use App\Event\InvoicePreRenderEvent;
|
||||
use App\Repository\InvoiceDocumentRepository;
|
||||
use App\Repository\InvoiceRepository;
|
||||
use App\Repository\Query\InvoiceQuery;
|
||||
use App\Timesheet\UserDateTimeFactory;
|
||||
use App\Utils\FileHelper;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
|
||||
|
||||
/**
|
||||
* Service to manage invoice dependencies.
|
||||
@@ -45,11 +52,26 @@ final class ServiceInvoice
|
||||
* @var FileHelper
|
||||
*/
|
||||
private $fileHelper;
|
||||
/**
|
||||
* @var UserDateTimeFactory
|
||||
*/
|
||||
private $dateTimeFactory;
|
||||
/**
|
||||
* @var InvoiceFormatter
|
||||
*/
|
||||
private $formatter;
|
||||
/**
|
||||
* @var InvoiceRepository
|
||||
*/
|
||||
private $invoiceRepository;
|
||||
|
||||
public function __construct(InvoiceDocumentRepository $repository, FileHelper $fileHelper)
|
||||
public function __construct(InvoiceDocumentRepository $repository, FileHelper $fileHelper, InvoiceRepository $invoiceRepository, UserDateTimeFactory $dateTimeFactory, InvoiceFormatter $formatter)
|
||||
{
|
||||
$this->documents = $repository;
|
||||
$this->fileHelper = $fileHelper;
|
||||
$this->invoiceRepository = $invoiceRepository;
|
||||
$this->dateTimeFactory = $dateTimeFactory;
|
||||
$this->formatter = $formatter;
|
||||
}
|
||||
|
||||
public function addNumberGenerator(NumberGeneratorInterface $generator): ServiceInvoice
|
||||
@@ -153,7 +175,7 @@ final class ServiceInvoice
|
||||
|
||||
private function getInvoicesDirectory(): string
|
||||
{
|
||||
return $this->fileHelper->getDataSubdirectory('invoices');
|
||||
return $this->fileHelper->getDataDirectory('invoices');
|
||||
}
|
||||
|
||||
public function getInvoiceFile(Invoice $invoice): ?\SplFileInfo
|
||||
@@ -208,4 +230,209 @@ final class ServiceInvoice
|
||||
|
||||
return $filename;
|
||||
}
|
||||
|
||||
public function changeInvoiceStatus(Invoice $invoice, string $status)
|
||||
{
|
||||
if (!in_array($status, [Invoice::STATUS_NEW, Invoice::STATUS_PENDING, Invoice::STATUS_PAID])) {
|
||||
throw new \InvalidArgumentException('Unknown invoice status');
|
||||
}
|
||||
|
||||
switch ($status) {
|
||||
case Invoice::STATUS_NEW:
|
||||
$invoice->setIsNew();
|
||||
break;
|
||||
|
||||
case Invoice::STATUS_PENDING:
|
||||
$invoice->setIsPending();
|
||||
break;
|
||||
|
||||
case Invoice::STATUS_PAID:
|
||||
$invoice->setIsPaid();
|
||||
break;
|
||||
}
|
||||
|
||||
$this->invoiceRepository->saveInvoice($invoice);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InvoiceQuery $query
|
||||
* @return InvoiceItemInterface[]
|
||||
*/
|
||||
private function findInvoiceItemsWithRepository(InvoiceQuery $query): array
|
||||
{
|
||||
// customer needs to be defined, as we need the currency for the invoice
|
||||
if (!$query->hasCustomers()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (null === $query->getBegin()) {
|
||||
$query->setBegin($this->dateTimeFactory->createDateTime('first day of this month'));
|
||||
}
|
||||
if (null === $query->getEnd()) {
|
||||
$query->setEnd($this->dateTimeFactory->createDateTime('last day of this month'));
|
||||
}
|
||||
$query->getBegin()->setTime(0, 0, 0);
|
||||
$query->getEnd()->setTime(23, 59, 59);
|
||||
|
||||
$repositories = $this->getInvoiceItemRepositories();
|
||||
$items = [];
|
||||
|
||||
foreach ($repositories as $repository) {
|
||||
$items[get_class($repository)] = $repository->getInvoiceItemsForQuery($query);
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InvoiceQuery $query
|
||||
* @return InvoiceItemInterface[]
|
||||
*/
|
||||
public function findInvoiceItems(InvoiceQuery $query): array
|
||||
{
|
||||
$entries = [];
|
||||
$temp = $this->findInvoiceItemsWithRepository($query);
|
||||
|
||||
foreach ($temp as $repo => $items) {
|
||||
$entries = array_merge($entries, $items);
|
||||
}
|
||||
|
||||
return $entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InvoiceItemInterface[] $entries
|
||||
*/
|
||||
private function markEntriesAsExported(iterable $entries)
|
||||
{
|
||||
$repositories = $this->getInvoiceItemRepositories();
|
||||
|
||||
foreach ($entries as $repo => $items) {
|
||||
foreach ($repositories as $repository) {
|
||||
if (get_class($repository) === $repo) {
|
||||
$repository->setExported($items);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function renderInvoice(InvoiceQuery $query, EventDispatcherInterface $dispatcher): Response
|
||||
{
|
||||
$entries = $this->findInvoiceItemsWithRepository($query);
|
||||
$model = $this->createModel($query);
|
||||
foreach ($entries as $repo => $items) {
|
||||
$model->addEntries($items);
|
||||
}
|
||||
|
||||
$document = $this->getDocumentByName($model->getTemplate()->getRenderer());
|
||||
if (null === $document) {
|
||||
throw new \Exception('Unknown invoice document: ' . $model->getTemplate()->getRenderer());
|
||||
}
|
||||
|
||||
foreach ($this->getRenderer() as $renderer) {
|
||||
if ($renderer->supports($document)) {
|
||||
$dispatcher->dispatch(new InvoicePreRenderEvent($model, $document, $renderer));
|
||||
|
||||
$response = $renderer->render($document, $model);
|
||||
|
||||
$dispatcher->dispatch(new InvoicePostRenderEvent($model, $document, $renderer, $response));
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
throw new \Exception(
|
||||
sprintf('Cannot render invoice: %s (%s)', $model->getTemplate()->getRenderer(), $document->getName())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InvoiceQuery $query
|
||||
* @param EventDispatcherInterface $dispatcher
|
||||
* @return Invoice
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function createInvoice(InvoiceQuery $query, EventDispatcherInterface $dispatcher): Invoice
|
||||
{
|
||||
$entries = $this->findInvoiceItemsWithRepository($query);
|
||||
$model = $this->createModel($query);
|
||||
foreach ($entries as $repo => $items) {
|
||||
$model->addEntries($items);
|
||||
}
|
||||
|
||||
$document = $this->getDocumentByName($model->getTemplate()->getRenderer());
|
||||
if (null === $document) {
|
||||
throw new \Exception('Unknown invoice document: ' . $model->getTemplate()->getRenderer());
|
||||
}
|
||||
|
||||
foreach ($this->getRenderer() as $renderer) {
|
||||
if ($renderer->supports($document)) {
|
||||
$dispatcher->dispatch(new InvoicePreRenderEvent($model, $document, $renderer));
|
||||
|
||||
$response = $renderer->render($document, $model);
|
||||
|
||||
if ($query->isMarkAsExported()) {
|
||||
$this->markEntriesAsExported($entries);
|
||||
}
|
||||
|
||||
$event = new InvoicePostRenderEvent($model, $document, $renderer, $response);
|
||||
$dispatcher->dispatch($event);
|
||||
|
||||
$invoiceFilename = $this->saveGeneratedInvoice($event);
|
||||
|
||||
$invoice = new Invoice();
|
||||
$invoice->setModel($model);
|
||||
$invoice->setFilename($invoiceFilename);
|
||||
$this->invoiceRepository->saveInvoice($invoice);
|
||||
|
||||
$dispatcher->dispatch(new InvoiceCreatedEvent($invoice));
|
||||
|
||||
return $invoice;
|
||||
}
|
||||
}
|
||||
|
||||
throw new \Exception(
|
||||
sprintf('Cannot render invoice: %s (%s)', $model->getTemplate()->getRenderer(), $document->getName())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InvoiceQuery $query
|
||||
* @return InvoiceModel
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function createModel(InvoiceQuery $query): InvoiceModel
|
||||
{
|
||||
$model = new InvoiceModel($this->formatter);
|
||||
$model
|
||||
->setInvoiceDate($this->dateTimeFactory->createDateTime())
|
||||
->setQuery($query)
|
||||
;
|
||||
|
||||
if (null !== $query->getCurrentUser()) {
|
||||
$model->setUser($query->getCurrentUser());
|
||||
}
|
||||
|
||||
if ($query->hasCustomers()) {
|
||||
$model->setCustomer($query->getCustomers()[0]);
|
||||
}
|
||||
|
||||
if ($query->getTemplate() !== null) {
|
||||
$generator = $this->getNumberGeneratorByName($query->getTemplate()->getNumberGenerator());
|
||||
if (null === $generator) {
|
||||
throw new \Exception('Unknown number generator: ' . $query->getTemplate()->getNumberGenerator());
|
||||
}
|
||||
|
||||
$calculator = $this->getCalculatorByName($query->getTemplate()->getCalculator());
|
||||
if (null === $calculator) {
|
||||
throw new \Exception('Unknown invoice calculator: ' . $query->getTemplate()->getCalculator());
|
||||
}
|
||||
|
||||
$model->setTemplate($query->getTemplate());
|
||||
$model->setCalculator($calculator);
|
||||
$model->setNumberGenerator($generator);
|
||||
}
|
||||
|
||||
return $model;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user