Skip to content

Commit d4636b4

Browse files
committed
Add support for configurable invoice sequence scopes (global, monthly, annually)
1 parent 31765e1 commit d4636b4

File tree

8 files changed

+106
-4
lines changed

8 files changed

+106
-4
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/var/
12
/vendor/
23
/node_modules/
34
/composer.lock

config/config.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ imports:
55
parameters:
66
sylius_invoicing.invoice_save_path: "%kernel.project_dir%/private/invoices/"
77
sylius_invoicing.filesystem_adapter.invoice: "sylius_invoicing_invoice"
8+
sylius_invoicing.sequence_scope: '%env(default::SYLIUS_INVOICING_SEQUENCE_SCOPE)%'
9+
env(SYLIUS_INVOICING_SEQUENCE_SCOPE): 'global'
810

911
sylius_invoicing:
1012
pdf_generator:

config/services/generators.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<argument type="service" id="sylius_invoicing.factory.invoice_sequence" />
2323
<argument type="service" id="sylius_invoicing.manager.invoice_sequence" />
2424
<argument type="service" id="clock" />
25+
<argument type="string">%sylius_invoicing.sequence_scope%</argument>
2526
</service>
2627

2728
<service id="sylius_invoicing.generator.invoice_identifier" class="Sylius\InvoicingPlugin\Generator\UuidInvoiceIdentifierGenerator" />

src/Entity/InvoiceSequence.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ class InvoiceSequence implements InvoiceSequenceInterface
2323

2424
protected ?int $version = 1;
2525

26+
protected int $year;
27+
28+
protected int $month;
29+
2630
/** @return mixed */
2731
public function getId()
2832
{
@@ -48,4 +52,24 @@ public function setVersion(?int $version): void
4852
{
4953
$this->version = $version;
5054
}
55+
56+
public function getYear(): int
57+
{
58+
return $this->year;
59+
}
60+
61+
public function getMonth(): int
62+
{
63+
return $this->month;
64+
}
65+
66+
public function setYear(int $year): void
67+
{
68+
$this->year = $year;
69+
}
70+
71+
public function setMonth(int $month): void
72+
{
73+
$this->month = $month;
74+
}
5175
}

src/Entity/InvoiceSequenceInterface.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,12 @@ interface InvoiceSequenceInterface extends ResourceInterface, VersionedInterface
2121
public function getIndex(): int;
2222

2323
public function incrementIndex(): void;
24+
25+
public function getYear(): int;
26+
27+
public function getMonth(): int;
28+
29+
public function setYear(int $year): void;
30+
31+
public function setMonth(int $month): void;
2432
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Sylius package.
5+
*
6+
* (c) Sylius Sp. z o.o.
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace Sylius\InvoicingPlugin\Enum;
15+
16+
enum InvoiceSequenceScopeEnum: string
17+
{
18+
case GLOBAL = 'global';
19+
case MONTHLY = 'monthly';
20+
case ANNUALLY = 'annually';
21+
22+
public static function fromString(?string $value): self
23+
{
24+
return match ($value) {
25+
'monthly' => self::MONTHLY,
26+
'annually' => self::ANNUALLY,
27+
default => self::GLOBAL,
28+
};
29+
}
30+
}

src/Generator/SequentialInvoiceNumberGenerator.php

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Sylius\Component\Resource\Factory\FactoryInterface;
1919
use Sylius\Component\Resource\Repository\RepositoryInterface;
2020
use Sylius\InvoicingPlugin\Entity\InvoiceSequenceInterface;
21+
use Sylius\InvoicingPlugin\Enum\InvoiceSequenceScopeEnum;
2122
use Symfony\Component\Clock\ClockInterface;
2223

2324
final class SequentialInvoiceNumberGenerator implements InvoiceNumberGenerator
@@ -29,7 +30,17 @@ public function __construct(
2930
private readonly ClockInterface $clock,
3031
private readonly int $startNumber = 1,
3132
private readonly int $numberLength = 9,
33+
private readonly ?string $scope = null,
3234
) {
35+
if (null === $this->scope) {
36+
trigger_deprecation(
37+
'sylius/invoicing-plugin',
38+
'2.1',
39+
'Not passing a "%s" to "%s" is deprecated and will be required in SyliusInvoicingPlugin 3.0.',
40+
InvoiceSequenceScopeEnum::class,
41+
self::class,
42+
);
43+
}
3344
}
3445

3546
public function generate(): string
@@ -56,15 +67,38 @@ private function generateNumber(int $index): string
5667

5768
private function getSequence(): InvoiceSequenceInterface
5869
{
59-
/** @var InvoiceSequenceInterface $sequence */
60-
$sequence = $this->sequenceRepository->findOneBy([]);
61-
62-
if (null != $sequence) {
70+
$now = $this->clock->now();
71+
$scope = InvoiceSequenceScopeEnum::tryFrom($this->scope ?? '') ?? InvoiceSequenceScopeEnum::GLOBAL;
72+
73+
$criteria = match ($scope) {
74+
InvoiceSequenceScopeEnum::MONTHLY => [
75+
'year' => (int) $now->format('Y'),
76+
'month' => (int) $now->format('m'),
77+
],
78+
InvoiceSequenceScopeEnum::ANNUALLY => [
79+
'year' => (int) $now->format('Y'),
80+
],
81+
InvoiceSequenceScopeEnum::GLOBAL => [],
82+
};
83+
84+
/** @var InvoiceSequenceInterface|null $sequence */
85+
$sequence = $this->sequenceRepository->findOneBy($criteria);
86+
87+
if (null !== $sequence) {
6388
return $sequence;
6489
}
6590

6691
/** @var InvoiceSequenceInterface $sequence */
6792
$sequence = $this->sequenceFactory->createNew();
93+
94+
if (isset($criteria['year'])) {
95+
$sequence->setYear($criteria['year']);
96+
}
97+
98+
if (isset($criteria['month'])) {
99+
$sequence->setMonth($criteria['month']);
100+
}
101+
68102
$this->sequenceManager->persist($sequence);
69103

70104
return $sequence;

tests/TestApplication/.env

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ WKHTMLTOPDF_PATH=/usr/local/bin/wkhtmltopdf
99
###< knplabs/knp-snappy-bundle ###
1010

1111
TEST_SYLIUS_INVOICING_PDF_GENERATION_DISABLED=false
12+
TEST_SYLIUS_INVOICING_PDF_GENERATION_DISABLED=false
13+
SYLIUS_INVOICING_SEQUENCE_SCOPE='monthly'

0 commit comments

Comments
 (0)