File::read()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 64
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 3.6908

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 40
c 1
b 0
f 0
nc 4
nop 0
dl 0
loc 64
ccs 23
cts 40
cp 0.575
crap 3.6908
rs 9.28

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
namespace MrPrompt\Celesc\Shipment;
3
4
use MrPrompt\ShipmentCommon\Base\Dealership;
5
use MrPrompt\ShipmentCommon\Base\Authorization;
6
use MrPrompt\ShipmentCommon\Base\Cart;
7
use MrPrompt\ShipmentCommon\Base\ConsumerUnity;
8
use MrPrompt\ShipmentCommon\Base\Customer;
9
use MrPrompt\ShipmentCommon\Base\Parcel;
10
use MrPrompt\ShipmentCommon\Base\Parcels;
11
use MrPrompt\ShipmentCommon\Base\Purchaser;
12
use MrPrompt\ShipmentCommon\Base\Seller;
13
use MrPrompt\ShipmentCommon\Base\Sequence;
14
use MrPrompt\Celesc\Shipment\Partial\Detail;
15
use MrPrompt\Celesc\Shipment\Partial\Footer;
16
use MrPrompt\Celesc\Shipment\Partial\Header;
17
use DateTime;
18
19
/**
20
 * Shipment file class
21
 *
22
 * @author Thiago Paes <[email protected]>
23
 */
24
class File
25
{
26
    /**
27
     * File name template
28
     *
29
     * @var string
30
     */
31
    const TEMPLATE_GENERATED = 'e{CLIENT}{SEQUENCE}.{SUBTYPE}';
32
33
    /**
34
     * @var DateTime
35
     */
36
    private $now;
37
38
    /**
39
     * @var string
40
     */
41
    private $content;
42
43
    /**
44
     * @var Header
45
     */
46
    private $header;
47
48
    /**
49
     * @var Cart
50
     */
51
    private $cart;
52
53
    /**
54
     * @var Footer
55
     */
56
    private $footer;
57
58
    /**
59
     * @var Sequence
60
     */
61
    private $sequence;
62
63
    /**
64
     * @var Customer
65
     */
66
    private $customer;
67
68
    /**
69
     * @var Dealership
70
     */
71
    private $dealership;
72
73
    /**
74
     * @var string
75
     */
76
    private $storage;
77
78
    /**
79
     * @var string
80
     */
81
    private $template;
82
83
    /**
84
     * @param Customer $customer
85
     * @param Dealership $dealership
86
     * @param Sequence $sequence
87
     * @param DateTime $today
88
     * @param string   $storageDir
89
     */
90 8
    public function __construct(
91
        Customer $customer,
92
        Dealership $dealership,
93
        Sequence $sequence,
94
        DateTime $today,
95
        string $storageDir = null
96
    ) {
97 8
        $this->customer     = $customer;
98 8
        $this->dealership   = $dealership;
99 8
        $this->now          = $today;
100 8
        $this->sequence     = $sequence;
101 8
        $this->storage      = $storageDir;
102 8
        $this->content      = null;
103 8
    }
104
105
    /**
106
     * @return Cart
107
     */
108 1
    public function getCart()
109
    {
110 1
        return $this->cart;
111
    }
112
113
    /**
114
     * @param Cart $cart
115
     */
116 1
    public function setCart(Cart $cart)
117
    {
118 1
        $this->cart = $cart;
119 1
    }
120
121
    /**
122
     * @return Footer
123
     */
124 1
    public function getFooter()
125
    {
126 1
        return $this->footer;
127
    }
128
129
    /**
130
     * @param Footer $footer
131
     */
132 1
    public function setFooter(Footer $footer)
133
    {
134 1
        $this->footer = $footer;
135 1
    }
136
137
    /**
138
     * @return Header
139
     */
140 1
    public function getHeader()
141
    {
142 1
        return $this->header;
143
    }
144
145
    /**
146
     * @param Header $header
147
     */
148 1
    public function setHeader(Header $header)
149
    {
150 1
        $this->header = $header;
151 1
    }
152
153
    /**
154
     * Create the file name
155
     *
156
     * @return string
157
     */
158
    private function createFilename()
159
    {
160
        $type = self::TEMPLATE_GENERATED;
161
        
162
        $search = [
163
            '{CLIENT}',
164
            '{SEQUENCE}',
165
            '{SUBTYPE}'
166
        ];
167
168
        $replace = [
169
            'CEL',
170
            $this->sequence->getValue(),
171
            '063',
172
        ];
173
174
        return str_replace($search, $replace, $type);
175
    }
176
177
    /**
178
     * @param $parcels
179
     * @return int
180
     */
181
    private function getTotalPrice($parcels)
182
    {
183
        $price = 0;
184
185
        foreach ($parcels as $parcel) {
186
            $price += $parcel->getPrice();
187
        }
188
189
        return $price;
190
    }
191
192
    /**
193
     * @return string
194
     */
195
    private function generateContent()
196
    {
197
        $totalPrice     = 0;
198
        $counter        = 2;
199
200
        $this->header = new Header($this->customer, $this->dealership, $this->sequence, $this->now);
201
        $this->content  = $this->header->render() . PHP_EOL;
202
203
        /* @var $detail \MrPrompt\Celesc\Shipment\Partial\Detail */
204
        foreach ($this->cart as $detail) {
205
            $detail->getSequence()->setValue($counter);
206
207
            $this->content .= $detail->render() . PHP_EOL;
208
209
            $totalPrice += $this->getTotalPrice( $detail->getParcels() );
210
            $counter++;
211
        }
212
213
        $sequence = clone $this->sequence;
214
        $sequence->setValue($counter);
215
216
        $this->footer = new Footer(($counter - 1), preg_replace('/[^0-9]+/', '', $totalPrice), $sequence);
217
218
        $this->content .= $this->footer->render();
219
220
        return $this->content;
221
    }
222
223
    /**
224
     * @return string
225
     */
226 1
    public function save()
227
    {
228 1
        if (null === $this->content) {
229 1
            $this->content = $this->generateContent();
230
        }
231
232 1
        $this->template = self::TEMPLATE_GENERATED;
233
234 1
        $this->header->setSequence($this->sequence);
235
236 1
        $filename   = $this->createFilename($this->template);
0 ignored issues
show
Unused Code introduced by
The call to MrPrompt\Celesc\Shipment\File::createFilename() has too many arguments starting with $this->template. ( Ignorable by Annotation )

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

236
        /** @scrutinizer ignore-call */ 
237
        $filename   = $this->createFilename($this->template);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
237 1
        $outputFile = $this->storage . DIRECTORY_SEPARATOR . $filename;
238
239 1
        file_put_contents($outputFile, $this->content . PHP_EOL);
240
241 1
        return $outputFile;
242
    }
243
244
    /**
245
     * @return string
246
     */
247 1
    public function read()
248
    {
249 1
        $this->template = self::TEMPLATE_GENERATED;
250
251 1
        $file = $this->storage . DIRECTORY_SEPARATOR . $this->createFilename($this->template);
0 ignored issues
show
Unused Code introduced by
The call to MrPrompt\Celesc\Shipment\File::createFilename() has too many arguments starting with $this->template. ( Ignorable by Annotation )

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

251
        $file = $this->storage . DIRECTORY_SEPARATOR . $this->/** @scrutinizer ignore-call */ createFilename($this->template);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
252
253 1
        $this->content  = file_get_contents($file);
254
255 1
        $details        = explode(PHP_EOL, $this->content);
256 1
        $headerLine     = array_shift($details);
257 1
        $footerLine     = array_pop($details);
258
259 1
        if (null == $footerLine) {
260 1
            $footerLine = array_pop($details);
261
        }
262
263 1
        $this->header   = new Header(
264 1
            $this->customer,
265 1
            $this->dealership,
266 1
            new Sequence(substr($headerLine, 144, 6)),
0 ignored issues
show
Bug introduced by
substr($headerLine, 144, 6) of type string is incompatible with the type integer expected by parameter $value of MrPrompt\ShipmentCommon\...Sequence::__construct(). ( Ignorable by Annotation )

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

266
            new Sequence(/** @scrutinizer ignore-type */ substr($headerLine, 144, 6)),
Loading history...
267 1
            $this->now
268
        );
269
270 1
        $this->footer   = new Footer(
271 1
            substr($footerLine, 1, 6),
0 ignored issues
show
Bug introduced by
substr($footerLine, 1, 6) of type string is incompatible with the type integer expected by parameter $totalCharges of MrPrompt\Celesc\Shipment...l\Footer::__construct(). ( Ignorable by Annotation )

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

271
            /** @scrutinizer ignore-type */ substr($footerLine, 1, 6),
Loading history...
272 1
            substr($footerLine, 7, 10),
0 ignored issues
show
Bug introduced by
substr($footerLine, 7, 10) of type string is incompatible with the type integer expected by parameter $sumCharges of MrPrompt\Celesc\Shipment...l\Footer::__construct(). ( Ignorable by Annotation )

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

272
            /** @scrutinizer ignore-type */ substr($footerLine, 7, 10),
Loading history...
273 1
            (new Sequence(substr($footerLine, 144, 6)))
274
        );
275
276 1
        $this->cart = new Cart();
277
278
        /* @var $detail \MrPrompt\Celesc\Shipment\Partial\Detail */
279 1
        foreach ($details as $row) {
280
            $unity          = new ConsumerUnity();
281
            $unity->setNumber(substr($row, 1, 13));
0 ignored issues
show
Bug introduced by
substr($row, 1, 13) of type string is incompatible with the type integer expected by parameter $number of MrPrompt\ShipmentCommon\...sumerUnity::setNumber(). ( Ignorable by Annotation )

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

281
            $unity->setNumber(/** @scrutinizer ignore-type */ substr($row, 1, 13));
Loading history...
282
283
            $seller         = new Seller();
284
285
            $parcels        = $this->createParcels($row);
286
            $authorization  = $this->createAuthorization($row);
287
            $sequence       = new Sequence(substr($row, 144, 6));
288
289
            // extracting object from line
290
            $unity->setNumber(substr($row, 0, 1));
291
            $unity->setMaturity(DateTime::createFromFormat('dmY', substr($row, 23, 8)));
292
293
            $purchaser = $this->createPurchaser($row);
294
295
            $detail = new Detail(
296
                $seller,
297
                $purchaser,
298
                $parcels,
299
                $authorization,
300
                $unity,
301
                $sequence
302
            );
303
304
            $this->cart->append($detail);
305
        }
306
307
        return [
308 1
            $this->header,
309 1
            $this->cart,
310 1
            $this->footer
311
        ];
312
    }
313
314
    /**
315
     * @param string $row
316
     * @return Purchaser
317
     */
318
    private function createPurchaser($row)
0 ignored issues
show
Unused Code introduced by
The parameter $row is not used and could be removed. ( Ignorable by Annotation )

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

318
    private function createPurchaser(/** @scrutinizer ignore-unused */ $row)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
319
    {
320
        $purchaser = new Purchaser();
321
322
        return $purchaser;
323
    }
324
325
    /**
326
     * @param $row
327
     * @return Parcels
328
     */
329
    private function createParcels($row)
330
    {
331
        $parcel = new Parcel();
332
        $parcel->setMaturity(DateTime::createFromFormat('dmY', substr($row, 23, 8)));
333
        $parcel->setPrice(substr($row, 14, 9));
0 ignored issues
show
Bug introduced by
substr($row, 14, 9) of type string is incompatible with the type double expected by parameter $price of MrPrompt\ShipmentCommon\Base\Parcel::setPrice(). ( Ignorable by Annotation )

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

333
        $parcel->setPrice(/** @scrutinizer ignore-type */ substr($row, 14, 9));
Loading history...
334
        $parcel->setQuantity(1);
335
        $parcel->setKey(0);
336
337
        $parcels = new Parcels(4);
338
        $parcels->addParcel($parcel);
339
340
        return $parcels;
341
    }
342
343
    /**
344
     * @param $row
345
     * @return Authorization
346
     */
347
    private function createAuthorization($row)
0 ignored issues
show
Unused Code introduced by
The parameter $row is not used and could be removed. ( Ignorable by Annotation )

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

347
    private function createAuthorization(/** @scrutinizer ignore-unused */ $row)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
348
    {
349
        $authorization  = new Authorization();
350
        // $authorization->setNumber(substr($row, 773, 10));
351
352
        return $authorization;
353
    }
354
}
355