ImportXmlMandatesConsole::processMandate()   B
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 121
Code Lines 76

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 76
nc 4
nop 1
dl 0
loc 121
rs 8.2125
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * This file is part of byrokrat\giroapp.
5
 *
6
 * byrokrat\giroapp is free software: you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License as published
8
 * by the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * byrokrat\giroapp is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with byrokrat\giroapp. If not, see <http://www.gnu.org/licenses/>.
18
 *
19
 * Copyright 2016-21 Hannes Forsgård
20
 */
21
22
declare(strict_types=1);
23
24
namespace byrokrat\giroapp\Console;
25
26
use byrokrat\giroapp\CommandBus;
27
use byrokrat\giroapp\DependencyInjection;
28
use byrokrat\giroapp\Validator;
29
use byrokrat\giroapp\Xml;
30
use Symfony\Component\Console\Command\Command;
31
use Symfony\Component\Console\Input\InputArgument;
32
use Symfony\Component\Console\Input\InputInterface;
33
use Symfony\Component\Console\Output\OutputInterface;
34
use Symfony\Component\Console\Helper\QuestionHelper;
35
use Money\Currency;
36
37
final class ImportXmlMandatesConsole implements ConsoleInterface, Xml\CompilerPassInterface
38
{
39
    use DependencyInjection\AccountFactoryProperty;
40
    use DependencyInjection\CommandBusProperty;
41
    use DependencyInjection\MoneyFormatterProperty;
42
    use DependencyInjection\MoneyParserProperty;
43
    use DependencyInjection\IdFactoryProperty;
44
    use Helper\DryRun;
45
46
    /** @var ImportTransactionManager */
47
    private $importTransactionManager;
48
49
    /** @var Helper\FileOrStdinInputLocator */
50
    private $inputLocator;
51
52
    /** @var Xml\XmlMandateCompiler */
53
    private $xmlMandateCompiler;
54
55
    /** @var ?InputInterface */
56
    private $input = null;
57
58
    /** @var ?OutputInterface */
59
    private $output = null;
60
61
    public function __construct(
62
        ImportTransactionManager $importTransactionManager,
63
        Helper\FileOrStdinInputLocator $inputLocator,
64
        Xml\XmlMandateCompiler $xmlMandateCompiler
65
    ) {
66
        $this->importTransactionManager = $importTransactionManager;
67
        $this->inputLocator = $inputLocator;
68
        $this->xmlMandateCompiler = $xmlMandateCompiler;
69
    }
70
71
    public function configure(Command $command): void
72
    {
73
        $command
74
            ->setName('import-xml-mandates')
75
            ->setDescription('Import xml formatted mandates')
76
            ->setHelp('Import one or more xml formatted mandates from autogirot')
77
            ->addArgument(
78
                self::OPTION_PATH,
79
                InputArgument::OPTIONAL | InputArgument::IS_ARRAY,
80
                self::OPTION_DESCS[self::OPTION_PATH]
81
            );
82
83
        $this->importTransactionManager->configure($command);
84
85
        $this->configureDryRun($command);
86
    }
87
88
    public function execute(InputInterface $input, OutputInterface $output): void
89
    {
90
        $this->input = $input;
91
        $this->output = $output;
92
93
        // Register interactive mandate processor
94
        $this->xmlMandateCompiler->addCompilerPass($this);
95
96
        // Execute command
97
        foreach ($this->inputLocator->getFiles((array)$input->getArgument(self::OPTION_PATH)) as $file) {
98
            $this->commandBus->handle(new CommandBus\ImportXmlMandateFile($file));
99
        }
100
101
        // Rollback on errors
102
        $this->importTransactionManager->manageTransaction($input);
103
104
        // Rollback on dry run
105
        $this->evaluateDryRun($input);
106
    }
107
108
    public function processMandate(Xml\XmlMandate $xmlMandate): Xml\XmlMandate
109
    {
110
        if (is_null($this->input) || is_null($this->output)) {
111
            throw new \LogicException("Input or output not set, did you call execute() prior to processMandate()?");
112
        }
113
114
        $this->output->writeln('<info>New mandate</info>');
115
116
        $this->output->writeln(
117
            (new Xml\HumanDumper($this->moneyFormatter))->dump($xmlMandate)
118
        );
119
120
        $inputReader = new Helper\InputReader($this->input, $this->output, new QuestionHelper());
121
122
        if (!$inputReader->confirm("Edit [<info>y/N</info>]? ", false)) {
123
            return $xmlMandate;
124
        }
125
126
        $inputReader->readOptionalInput(
127
            self::OPTION_ID,
128
            $xmlMandate->donorId->format('CS-sk'),
129
            new Validator\ValidatorCollection(
130
                new Validator\IdValidator(),
131
                new Validator\CallbackValidator(function (string $value) use (&$xmlMandate) {
132
                    $xmlMandate->donorId = $this->idFactory->createId($value);
133
                })
134
            )
135
        );
136
137
        $xmlMandate->payerNumber = $inputReader->readOptionalInput(
138
            self::OPTION_PAYER_NUMBER,
139
            $xmlMandate->payerNumber,
140
            new Validator\PayerNumberValidator()
141
        );
142
143
        $inputReader->readOptionalInput(
144
            self::OPTION_ACCOUNT,
145
            $xmlMandate->account->prettyprint(),
146
            new Validator\ValidatorCollection(
147
                new Validator\AccountValidator(),
148
                new Validator\CallbackValidator(function (string $value) use (&$xmlMandate) {
149
                    $xmlMandate->account = $this->accountFactory->createAccount($value);
150
                })
151
            )
152
        );
153
154
        $xmlMandate->donationAmount = $this->moneyParser->parse(
155
            $inputReader->readOptionalInput(
156
                self::OPTION_AMOUNT,
157
                $this->moneyFormatter->format($xmlMandate->donationAmount),
158
                new Validator\ValidatorCollection(
159
                    new Validator\NotEmptyValidator(),
160
                    new Validator\NumericValidator()
161
                )
162
            ),
163
            new Currency('SEK')
164
        );
165
166
        $xmlMandate->name = $inputReader->readOptionalInput(
167
            self::OPTION_NAME,
168
            $xmlMandate->name,
169
            new Validator\ValidatorCollection(
170
                new Validator\StringValidator(),
171
                new Validator\NotEmptyValidator()
172
            )
173
        );
174
175
        $xmlMandate->address['line1'] = $inputReader->readOptionalInput(
176
            self::OPTION_ADDRESS1,
177
            $xmlMandate->address['line1'],
178
            new Validator\StringValidator()
179
        );
180
181
        $xmlMandate->address['line2'] = $inputReader->readOptionalInput(
182
            self::OPTION_ADDRESS2,
183
            $xmlMandate->address['line2'],
184
            new Validator\StringValidator()
185
        );
186
187
        $xmlMandate->address['line3'] = $inputReader->readOptionalInput(
188
            self::OPTION_ADDRESS3,
189
            $xmlMandate->address['line3'],
190
            new Validator\StringValidator()
191
        );
192
193
        $xmlMandate->address['postalCode'] = $inputReader->readOptionalInput(
194
            self::OPTION_POSTAL_CODE,
195
            $xmlMandate->address['postalCode'],
196
            new Validator\PostalCodeValidator()
197
        );
198
199
        $xmlMandate->address['postalCity'] = $inputReader->readOptionalInput(
200
            self::OPTION_POSTAL_CITY,
201
            $xmlMandate->address['postalCity'],
202
            new Validator\StringValidator()
203
        );
204
205
        $xmlMandate->email = $inputReader->readOptionalInput(
206
            self::OPTION_EMAIL,
207
            $xmlMandate->email,
208
            new Validator\EmailValidator()
209
        );
210
211
        $xmlMandate->phone = $inputReader->readOptionalInput(
212
            self::OPTION_PHONE,
213
            $xmlMandate->phone,
214
            new Validator\PhoneValidator()
215
        );
216
217
        $xmlMandate->comment = $inputReader->readOptionalInput(
218
            self::OPTION_COMMENT,
219
            $xmlMandate->comment,
220
            new Validator\StringValidator()
221
        );
222
223
        foreach ($xmlMandate->attributes as $attrKey => $attrValue) {
224
            $xmlMandate->attributes[$attrKey] =
225
                $inputReader->readOptionalInput("attribute.$attrKey", $attrValue, new Validator\StringValidator());
226
        }
227
228
        return $xmlMandate;
229
    }
230
}
231