-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCalculateComissionsCommand.php
More file actions
96 lines (83 loc) · 2.87 KB
/
CalculateComissionsCommand.php
File metadata and controls
96 lines (83 loc) · 2.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<?php
declare(strict_types=1);
namespace Millon\PhpRefactoring\Command;
use LogicException;
use Millon\PhpRefactoring\Entity\Person;
use Millon\PhpRefactoring\Service\Comission\Exception\CalculationException;
use Millon\PhpRefactoring\Service\Contracts\ComissionCalculatorInterface;
use RuntimeException;
use SplFileObject;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\SerializerInterface;
#[AsCommand(
name: 'app:calculate-comissions',
description: 'Console command to calculate commissions for already made transactions',
)]
final class CalculateComissionsCommand extends Command
{
public function __construct(
private readonly SerializerInterface $serializer,
private readonly ComissionCalculatorInterface $commisionCalculator,
) {
parent::__construct();
}
protected function configure(): void
{
$this
->addArgument(
'filename',
InputArgument::REQUIRED,
'Filename of the file with financial data stored as json strings.'
)
;
}
/**
* @throws LogicException|RuntimeException|CalculationException
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$filename = $input->getArgument('filename');
$file = $this->open($filename, $io);
$this->proccess($file, $io);
return Command::SUCCESS;
}
/**
* @throws LogicException|RuntimeException
*/
private function open(mixed $filename, SymfonyStyle $io): SplFileObject
{
try {
return new SplFileObject($filename, 'r');
} catch (LogicException $e) {
$io->error(sprintf('File "%s" is a directory', $filename));
} catch (RuntimeException $e) {
$io->error(sprintf('File "%s" cannot be found', $filename));
}
throw $e;
}
/**
* Process file and print results line by line
*
* @throws CalculationException
*/
private function proccess(SplFileObject $file, SymfonyStyle $io): void
{
// Read file line by line
foreach ($file as $line) {
// If line is empty, skip it
if (empty($line)) {
continue;
}
$person = $this->serializer->deserialize($line, Person::class, JsonEncoder::FORMAT);
$comission = $this->commisionCalculator->calculate($person);
$io->writeln($comission->sum, OutputInterface::OUTPUT_PLAIN);
}
}
}