Passed
Branch master (613786)
by Hannes
02:27
created

ImportXmlMandatesConsole::configure()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 10
nc 1
nop 1
dl 0
loc 15
rs 9.9332
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of byrokrat\giroapp.
4
 *
5
 * byrokrat\giroapp is free software: you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License as published
7
 * by the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * byrokrat\giroapp is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with byrokrat\giroapp. If not, see <http://www.gnu.org/licenses/>.
17
 *
18
 * Copyright 2016-20 Hannes Forsgård
19
 */
20
21
declare(strict_types = 1);
22
23
namespace byrokrat\giroapp\Console;
24
25
use byrokrat\giroapp\CommandBus;
26
use byrokrat\giroapp\DependencyInjection;
27
use byrokrat\giroapp\Validator;
28
use byrokrat\giroapp\Xml;
29
use Symfony\Component\Console\Command\Command;
30
use Symfony\Component\Console\Input\InputArgument;
31
use Symfony\Component\Console\Input\InputInterface;
32
use Symfony\Component\Console\Output\OutputInterface;
33
use Symfony\Component\Console\Helper\QuestionHelper;
34
35
final class ImportXmlMandatesConsole implements ConsoleInterface, Xml\CompilerPassInterface
36
{
37
    use DependencyInjection\AccountFactoryProperty,
38
        DependencyInjection\CommandBusProperty,
39
        DependencyInjection\MoneyFormatterProperty,
40
        DependencyInjection\MoneyParserProperty,
41
        DependencyInjection\IdFactoryProperty,
42
        Helper\DryRun;
43
44
    /** @var ImportTransactionManager */
45
    private $importTransactionManager;
46
47
    /** @var Helper\FileOrStdinInputLocator */
48
    private $inputLocator;
49
50
    /** @var Xml\XmlMandateCompiler */
51
    private $xmlMandateCompiler;
52
53
    /** @var ?InputInterface */
54
    private $input;
55
56
    /** @var ?OutputInterface */
57
    private $output;
58
59
    public function __construct(
60
        ImportTransactionManager $importTransactionManager,
61
        Helper\FileOrStdinInputLocator $inputLocator,
62
        Xml\XmlMandateCompiler $xmlMandateCompiler
63
    ) {
64
        $this->importTransactionManager = $importTransactionManager;
65
        $this->inputLocator = $inputLocator;
66
        $this->xmlMandateCompiler = $xmlMandateCompiler;
67
    }
68
69
    public function configure(Command $command): void
70
    {
71
        $command
72
            ->setName('import-xml-mandates')
73
            ->setDescription('Import xml formatted mandates')
74
            ->setHelp('Import one or more xml formatted mandates from autogirot')
75
            ->addArgument(
76
                self::OPTION_PATH,
77
                InputArgument::OPTIONAL | InputArgument::IS_ARRAY,
78
                self::OPTION_DESCS[self::OPTION_PATH]
79
            );
80
81
        $this->importTransactionManager->configure($command);
82
83
        $this->configureDryRun($command);
84
    }
85
86
    public function execute(InputInterface $input, OutputInterface $output): void
87
    {
88
        $this->input = $input;
89
        $this->output = $output;
90
91
        // Register interactive mandate processor
92
        $this->xmlMandateCompiler->addCompilerPass($this);
93
94
        // Execute command
95
        foreach ($this->inputLocator->getFiles((array)$input->getArgument(self::OPTION_PATH)) as $file) {
96
            $this->commandBus->handle(new CommandBus\ImportXmlMandateFile($file));
97
        }
98
99
        // Rollback on errors
100
        $this->importTransactionManager->manageTransaction($input);
101
102
        // Rollback on dry run
103
        $this->evaluateDryRun($input);
104
    }
105
106
    public function processMandate(Xml\XmlMandate $xmlMandate): Xml\XmlMandate
107
    {
108
        if (!isset($this->input) || !isset($this->output)) {
109
            throw new \LogicException("Input or output not set, did you call execute() prior to processMandate()?");
110
        }
111
112
        $this->output->writeln('<info>New mandate</info>');
0 ignored issues
show
Bug introduced by
The method writeln() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

112
        $this->output->/** @scrutinizer ignore-call */ 
113
                       writeln('<info>New mandate</info>');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
113
114
        $this->output->writeln(
115
            (new Xml\HumanDumper($this->moneyFormatter))->dump($xmlMandate)
116
        );
117
118
        $inputReader = new Helper\InputReader($this->input, $this->output, new QuestionHelper);
0 ignored issues
show
Bug introduced by
It seems like $this->output can also be of type null; however, parameter $output of byrokrat\giroapp\Console...utReader::__construct() does only seem to accept Symfony\Component\Console\Output\OutputInterface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

118
        $inputReader = new Helper\InputReader($this->input, /** @scrutinizer ignore-type */ $this->output, new QuestionHelper);
Loading history...
Bug introduced by
It seems like $this->input can also be of type null; however, parameter $input of byrokrat\giroapp\Console...utReader::__construct() does only seem to accept Symfony\Component\Console\Input\InputInterface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

118
        $inputReader = new Helper\InputReader(/** @scrutinizer ignore-type */ $this->input, $this->output, new QuestionHelper);
Loading history...
119
120
        if (!$inputReader->confirm("Edit [<info>y/N</info>]? ", false)) {
121
            return $xmlMandate;
122
        }
123
124
        $inputReader->readOptionalInput(
125
            self::OPTION_ID,
126
            $xmlMandate->donorId->format('CS-sk'),
127
            new Validator\ValidatorCollection(
128
                new Validator\IdValidator,
129
                new Validator\CallbackValidator(function (string $value) use (&$xmlMandate) {
130
                    $xmlMandate->donorId = $this->idFactory->createId($value);
131
                })
132
            )
133
        );
134
135
        $xmlMandate->payerNumber = $inputReader->readOptionalInput(
136
            self::OPTION_PAYER_NUMBER,
137
            $xmlMandate->payerNumber,
138
            new Validator\PayerNumberValidator
139
        );
140
141
        $inputReader->readOptionalInput(
142
            self::OPTION_ACCOUNT,
143
            $xmlMandate->account->prettyprint(),
144
            new Validator\ValidatorCollection(
145
                new Validator\AccountValidator,
146
                new Validator\CallbackValidator(function (string $value) use (&$xmlMandate) {
147
                    $xmlMandate->account = $this->accountFactory->createAccount($value);
148
                })
149
            )
150
        );
151
152
        $xmlMandate->donationAmount = $this->moneyParser->parse(
153
            $inputReader->readOptionalInput(
154
                self::OPTION_AMOUNT,
155
                $this->moneyFormatter->format($xmlMandate->donationAmount),
156
                new Validator\ValidatorCollection(
157
                    new Validator\NotEmptyValidator,
158
                    new Validator\NumericValidator
159
                )
160
            ),
161
            'SEK'
162
        );
163
164
        $xmlMandate->name = $inputReader->readOptionalInput(
165
            self::OPTION_NAME,
166
            $xmlMandate->name,
167
            new Validator\ValidatorCollection(
168
                new Validator\StringValidator,
169
                new Validator\NotEmptyValidator
170
            )
171
        );
172
173
        $xmlMandate->address['line1'] = $inputReader->readOptionalInput(
174
            self::OPTION_ADDRESS1,
175
            $xmlMandate->address['line1'],
176
            new Validator\StringValidator
177
        );
178
179
        $xmlMandate->address['line2'] = $inputReader->readOptionalInput(
180
            self::OPTION_ADDRESS2,
181
            $xmlMandate->address['line2'],
182
            new Validator\StringValidator
183
        );
184
185
        $xmlMandate->address['line3'] = $inputReader->readOptionalInput(
186
            self::OPTION_ADDRESS3,
187
            $xmlMandate->address['line3'],
188
            new Validator\StringValidator
189
        );
190
191
        $xmlMandate->address['postalCode'] = $inputReader->readOptionalInput(
192
            self::OPTION_POSTAL_CODE,
193
            $xmlMandate->address['postalCode'],
194
            new Validator\PostalCodeValidator
195
        );
196
197
        $xmlMandate->address['postalCity'] = $inputReader->readOptionalInput(
198
            self::OPTION_POSTAL_CITY,
199
            $xmlMandate->address['postalCity'],
200
            new Validator\StringValidator
201
        );
202
203
        $xmlMandate->email = $inputReader->readOptionalInput(
204
            self::OPTION_EMAIL,
205
            $xmlMandate->email,
206
            new Validator\EmailValidator
207
        );
208
209
        $xmlMandate->phone = $inputReader->readOptionalInput(
210
            self::OPTION_PHONE,
211
            $xmlMandate->phone,
212
            new Validator\PhoneValidator
213
        );
214
215
        $xmlMandate->comment = $inputReader->readOptionalInput(
216
            self::OPTION_COMMENT,
217
            $xmlMandate->comment,
218
            new Validator\StringValidator
219
        );
220
221
        foreach ($xmlMandate->attributes as $attrKey => $attrValue) {
222
            $xmlMandate->attributes[$attrKey] =
223
                $inputReader->readOptionalInput("attribute.$attrKey", $attrValue, new Validator\StringValidator);
224
        }
225
226
        return $xmlMandate;
227
    }
228
}
229