Passed
Pull Request — master (#69)
by Dmitry
20:39
created

BillingContext::billWithTime()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 22
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 7
Bugs 0 Features 0
Metric Value
eloc 18
c 7
b 0
f 0
dl 0
loc 22
rs 9.6666
cc 2
nc 2
nop 8

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 * PHP Billing Library
4
 *
5
 * @link      https://github.com/hiqdev/php-billing
6
 * @package   php-billing
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2017-2020, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\php\billing\tests\behat\bootstrap;
12
13
use Behat\Gherkin\Node\TableNode;
14
use BehatExpectException\ExpectException;
15
use DateTimeImmutable;
16
use hiqdev\php\billing\bill\BillInterface;
17
use hiqdev\php\billing\charge\ChargeInterface;
18
use PHPUnit\Framework\Assert;
19
20
class BillingContext extends BaseContext
21
{
22
    use ExpectException {
23
        mayFail as protected;
24
        shouldFail as protected;
25
        assertCaughtExceptionMatches as protected;
26
    }
27
28
    protected $saleTime;
29
30
    protected $bill;
31
32
    protected $charges = [];
33
34
    protected array $progressivePrice = [];
35
36
    /**
37
     * @Given reseller :reseller
38
     */
39
    public function reseller($reseller)
40
    {
41
        $this->builder->buildReseller($reseller);
42
    }
43
44
    /**
45
     * @Given customer :customer
46
     */
47
    public function customer($customer)
48
    {
49
        $this->builder->buildCustomer($customer);
50
    }
51
52
    /**
53
     * @Given manager :manager
54
     */
55
    public function manager($manager)
56
    {
57
        $this->builder->buildManager($manager);
0 ignored issues
show
Bug introduced by
The method buildManager() does not exist on hiqdev\php\billing\tests...tstrap\BuilderInterface. ( Ignorable by Annotation )

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

57
        $this->builder->/** @scrutinizer ignore-call */ 
58
                        buildManager($manager);

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...
58
    }
59
60
    /**
61
     * @Given /^(\S+ )?(\S+) tariff plan (\S+)/
62
     */
63
    public function plan($prefix, $type, $plan)
64
    {
65
        $prefix = strtr($prefix, ' ', '_');
66
        $grouping = $prefix === 'grouping_';
67
        $type = $grouping ? $type : $prefix.$type;
68
        $this->builder->buildPlan($plan, $type, $grouping);
69
    }
70
71
    protected function fullPrice(array $data)
72
    {
73
        if (!empty($data['price'])) {
74
            $data['rate'] = $data['price'];
75
        }
76
        $this->builder->buildPrice($data);
77
    }
78
79
    /**
80
     * @Given /price for (\S+) is +(\S+) (\S+) per (\S+) for target (.+)$/
81
     */
82
    public function priceWithTarget($type, $price, $currency, $unit, $target)
83
    {
84
        return $this->fullPrice(compact('type', 'price', 'currency', 'unit', 'target'));
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->fullPrice(compact...cy', 'unit', 'target')) targeting hiqdev\php\billing\tests...ingContext::fullPrice() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
85
    }
86
87
    /**
88
     * @Given /price for (\S+) is +(\S+) (\S+) per (\S+) prepaid (\S+)$/
89
     */
90
    public function priceWithPrepaid($type, $price, $currency, $unit, $prepaid)
91
    {
92
        return $this->fullPrice(compact('type', 'price', 'currency', 'unit', 'prepaid'));
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->fullPrice(compact...y', 'unit', 'prepaid')) targeting hiqdev\php\billing\tests...ingContext::fullPrice() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
93
    }
94
95
    /**
96
     * @Given /price for (\S+) is +(\S+) (\S+) per (\S+) prepaid (\S+) for target (\S+)$/
97
     */
98
    public function priceWithPrepaidAndTarget($type, $price, $currency, $unit, $prepaid, $target)
99
    {
100
        return $this->fullPrice(compact('type', 'price', 'currency', 'unit', 'prepaid', 'target'));
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->fullPrice(compact..., 'prepaid', 'target')) targeting hiqdev\php\billing\tests...ingContext::fullPrice() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
101
    }
102
103
    /**
104
     * @Given /price for (\S+) is +(\S+) (\S+) per (\S+)$/
105
     */
106
    public function price($type, $price, $currency, $unit)
107
    {
108
        return $this->fullPrice(compact('type', 'price', 'currency', 'unit'));
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->fullPrice(compact...', 'currency', 'unit')) targeting hiqdev\php\billing\tests...ingContext::fullPrice() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
109
    }
110
111
    /**
112
     * @Given /price for (\S+) is +(\S+) (\S+) per 1 (\S+) and (\S+) (\S+) per 2 (\S+) for target (\S+)/
113
     */
114
    public function enumPrice($type, $price, $currency, $unit, $price2, $currency2, $unit2, $target)
0 ignored issues
show
Unused Code introduced by
The parameter $currency2 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

114
    public function enumPrice($type, $price, $currency, $unit, $price2, /** @scrutinizer ignore-unused */ $currency2, $unit2, $target)

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...
Unused Code introduced by
The parameter $unit2 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

114
    public function enumPrice($type, $price, $currency, $unit, $price2, $currency2, /** @scrutinizer ignore-unused */ $unit2, $target)

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...
115
    {
116
        $sums = [1 => $price, 2 => $price2];
117
118
        return $this->fullPrice(compact('type', 'sums', 'currency', 'unit', 'target'));
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->fullPrice(compact...cy', 'unit', 'target')) targeting hiqdev\php\billing\tests...ingContext::fullPrice() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
119
    }
120
121
    /**
122
     * @Given /progressive price for (\S+) is +(\S+) (\S+) per (\S+) (\S+) (\S+) (\S+)$/
123
     */
124
    public function progressivePrice($type, $price, $currency, $unit, $sign, $quantity, $perUnit): void
0 ignored issues
show
Unused Code introduced by
The parameter $perUnit 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

124
    public function progressivePrice($type, $price, $currency, $unit, $sign, $quantity, /** @scrutinizer ignore-unused */ $perUnit): void

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...
Unused Code introduced by
The parameter $sign 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

124
    public function progressivePrice($type, $price, $currency, $unit, /** @scrutinizer ignore-unused */ $sign, $quantity, $perUnit): void

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...
125
    {
126
        if (empty($this->progressivePrice[$type])) {
127
            $this->progressivePrice[$type] = [
128
                'price' => 0,
129
                'currency' => $currency,
130
                'unit' => $unit,
131
                'thresholds' =>[
132
                    [
133
                        'price' => $price,
134
                        'currency' => $currency,
135
                        'quantity' => $quantity,
136
                        'unit' => $unit,
137
                    ],
138
                ] ,
139
            ];
140
        } else {
141
            array_push(
142
                $this->progressivePrice[$type]['thresholds'],
143
                [
144
                    'price' => $price,
145
                    'currency' => $currency,
146
                    'quantity' => $quantity,
147
                    'unit' => $unit,
148
                ]
149
            );
150
        }
151
    }
152
153
    /**
154
     * @Given /^remove and recreate tariff plan (\S+)/
155
     */
156
    public function recreatePlan($plan)
157
    {
158
        $this->builder->recreatePlan($plan);
159
    }
160
161
    /**
162
     * @Given /sale target (\S+) by plan (\S+) at (\S+)/
163
     */
164
    public function sale($target, $plan, $time): void
165
    {
166
        $this->saleTime = $this->prepareTime($time);
167
        $this->builder->buildSale($target, $plan, $this->saleTime);
0 ignored issues
show
Bug introduced by
It seems like $this->saleTime can also be of type null; however, parameter $time of hiqdev\php\billing\tests...rInterface::buildSale() does only seem to accept string, 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

167
        $this->builder->buildSale($target, $plan, /** @scrutinizer ignore-type */ $this->saleTime);
Loading history...
168
    }
169
    /**
170
     * @When /^sale close is requested for target "([^"]*)" at "([^"]*)", assuming current time is "([^"]*)"$/
171
     */
172
    public function saleClose(string $target, string $time, ?string $wallTime)
0 ignored issues
show
Unused Code introduced by
The parameter $wallTime 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

172
    public function saleClose(string $target, string $time, /** @scrutinizer ignore-unused */ ?string $wallTime)

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...
Unused Code introduced by
The parameter $time 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

172
    public function saleClose(string $target, /** @scrutinizer ignore-unused */ string $time, ?string $wallTime)

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...
Unused Code introduced by
The parameter $target 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

172
    public function saleClose(/** @scrutinizer ignore-unused */ string $target, string $time, ?string $wallTime)

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...
173
    {
174
        throw new PendingException();
0 ignored issues
show
Bug introduced by
The type hiqdev\php\billing\tests...tstrap\PendingException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
175
    }
176
177
    /**
178
     * @Then /^target "([^"]*)" has exactly (\d+) sale for customer$/
179
     */
180
    public function targetHasExactlyNSaleForCustomer(string $target, string $count)
0 ignored issues
show
Unused Code introduced by
The parameter $target 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

180
    public function targetHasExactlyNSaleForCustomer(/** @scrutinizer ignore-unused */ string $target, string $count)

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...
181
    {
182
        // TODO: implement
183
        // $sales = $this->builder->findSales(['target-name' => $target]);
184
185
        Assert::assertCount($count, $sales);
0 ignored issues
show
Bug introduced by
$count of type string is incompatible with the type integer expected by parameter $expectedCount of PHPUnit\Framework\Assert::assertCount(). ( Ignorable by Annotation )

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

185
        Assert::assertCount(/** @scrutinizer ignore-type */ $count, $sales);
Loading history...
Comprehensibility Best Practice introduced by
The variable $sales seems to be never defined.
Loading history...
186
    }
187
188
    /**
189
     * @Given /purchase target (\S+) by plan (\S+) at ([-:\w\s]+)$/
190
     */
191
    public function purchaseTarget(string $target, string $plan, string $time): void
192
    {
193
        $time = $this->prepareTime($time);
194
        $this->builder->buildPurchase($target, $plan, $time);
195
    }
196
197
    /**
198
     * @Given /^purchase target "([^"]*)" by plan "([^"]*)" at "([^"]*)" with the following initial uses:$/
199
     */
200
    public function purchaseTargetWithInitialUses(string $target, string $plan, string $time, TableNode $usesTable): void
201
    {
202
        $time = $this->prepareTime($time);
203
        $uses = array_map(static function (array $row) {
204
            return [
205
                'type' => $row['type'],
206
                'unit' => $row['unit'],
207
                'amount' => $row['amount'],
208
            ];
209
        }, $usesTable->getColumnsHash());
210
211
        $this->mayFail(
212
            fn() => $this->builder->buildPurchase($target, $plan, $time, $uses)
213
        );
214
    }
215
216
    /**
217
     * @Given /resource consumption for (\S+) is +(\S+) (\S+) for target (\S+) at (.+)$/
218
     */
219
    public function setConsumption(string $type, int $amount, string $unit, string $target, string $time): void
220
    {
221
        $time = $this->prepareTime($time);
222
        $this->builder->setConsumption($type, $amount, $unit, $target, $time);
0 ignored issues
show
Bug introduced by
The method setConsumption() does not exist on hiqdev\php\billing\tests...tstrap\BuilderInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to hiqdev\php\billing\tests...tstrap\BuilderInterface. ( Ignorable by Annotation )

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

222
        $this->builder->/** @scrutinizer ignore-call */ 
223
                        setConsumption($type, $amount, $unit, $target, $time);
Loading history...
223
    }
224
225
    /**
226
     * @Given /recalculate autotariff for target (\S+)( +at (\S+))?$/
227
     */
228
    public function recalculateAutoTariff(string $target, string $time = null): void
229
    {
230
        $this->builder->clientSetAutoTariff($target, $time);
0 ignored issues
show
Bug introduced by
The method clientSetAutoTariff() does not exist on hiqdev\php\billing\tests...tstrap\BuilderInterface. ( Ignorable by Annotation )

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

230
        $this->builder->/** @scrutinizer ignore-call */ 
231
                        clientSetAutoTariff($target, $time);

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...
231
    }
232
233
    /**
234
     * @Given /perform billing at (\S+)/
235
     */
236
    public function performBilling(string $time): void
237
    {
238
        $this->builder->performBilling($this->prepareTime($time));
239
    }
240
241
    /**
242
     * @Given /action for (\S+) is +(\S+) (\S+) +for target (.+?)( +at (\S+))?$/
243
     */
244
    public function setAction(string $type, int $amount, string $unit, string $target, string $at = null, string $time = null): void
0 ignored issues
show
Unused Code introduced by
The parameter $at 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

244
    public function setAction(string $type, int $amount, string $unit, string $target, /** @scrutinizer ignore-unused */ string $at = null, string $time = null): void

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...
245
    {
246
        $time = $this->prepareTime($time);
247
        $this->builder->setAction($type, $amount, $unit, $target, $time);
0 ignored issues
show
Bug introduced by
It seems like $time can also be of type null; however, parameter $time of hiqdev\php\billing\tests...rInterface::setAction() does only seem to accept string, 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

247
        $this->builder->setAction($type, $amount, $unit, $target, /** @scrutinizer ignore-type */ $time);
Loading history...
248
    }
249
250
    /**
251
     * @Given /perform calculation( at (\S+))?/
252
     */
253
    public function performCalculation(string $at = null, string $time = null): array
0 ignored issues
show
Unused Code introduced by
The parameter $at 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

253
    public function performCalculation(/** @scrutinizer ignore-unused */ string $at = null, string $time = null): array

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...
254
    {
255
        $this->charges = $this->builder->performCalculation($this->prepareTime($time));
0 ignored issues
show
Bug introduced by
It seems like $this->prepareTime($time) can also be of type null; however, parameter $time of hiqdev\php\billing\tests...e::performCalculation() does only seem to accept string, 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

255
        $this->charges = $this->builder->performCalculation(/** @scrutinizer ignore-type */ $this->prepareTime($time));
Loading history...
256
        return $this->charges;
257
    }
258
259
    /**
260
     * @Given /bill +for (\S+) is +(\S+) (\S+) per (\S+) (\S+) for target (.+?)( +at (.+))?$/
261
     */
262
    public function billWithTime($type, $sum, $currency, $quantity, $unit, $target, $at = null, $time = null)
0 ignored issues
show
Unused Code introduced by
The parameter $at 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

262
    public function billWithTime($type, $sum, $currency, $quantity, $unit, $target, /** @scrutinizer ignore-unused */ $at = null, $time = null)

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...
263
    {
264
        $this->builder->flushEntitiesCacheByType('bill');
265
266
        $quantity = $this->prepareQuantity($quantity);
267
        $sum = $this->prepareSum($sum, $quantity);
268
        $time = $this->prepareTime($time);
269
        $bill = $this->findBill([
270
            'type' => $type,
271
            'target' => $target,
272
            'sum' => "$sum $currency",
273
            'quantity' => "$quantity $unit",
274
            'time' => $time,
275
        ]);
276
        Assert::assertSame($type, $bill->getType()->getName(), "Bill type mismatch: expected $type, got {$bill->getType()->getName()}");
277
        Assert::assertSame($target, $bill->getTarget()->getFullName(), "Bill target mismatch: expected $target, got {$bill->getTarget()->getFullName()}");
278
        Assert::assertEquals(bcmul($sum, 100), $bill->getSum()->getAmount(), "Bill sum mismatch: expected $sum, got {$bill->getSum()->getAmount()}");
279
        Assert::assertSame($currency, $bill->getSum()->getCurrency()->getCode(), "Bill currency mismatch: expected $currency, got {$bill->getSum()->getCurrency()->getCode()}");
280
        Assert::assertEquals((float)$quantity, (float)$bill->getQuantity()->getQuantity(), "Bill quantity mismatch: expected $quantity, got {$bill->getQuantity()->getQuantity()}");
281
        Assert::assertEquals(strtolower($unit), strtolower($bill->getQuantity()->getUnit()->getName()), "Bill unit mismatch: expected $unit, got {$bill->getQuantity()->getUnit()->getName()}");
282
        if ($time) {
283
            Assert::assertEquals(new DateTimeImmutable($time), $bill->getTime(), "Bill time mismatch: expected $time, got {$bill->getTime()->format(DATE_ATOM)}");
284
        }
285
    }
286
287
    public function findBill(array $params): BillInterface
288
    {
289
        $bills = $this->builder->findBills($params);
290
        $this->bill = reset($bills);
291
        $this->charges = $this->bill->getCharges();
292
293
        return $this->bill;
294
    }
295
296
    /**
297
     * @Given /bills number is (\d+) for (\S+) for target (.+?)( +at (\S+))?$/
298
     */
299
    public function billsNumberWithTime($number, $type, $target, $at = null, $time = null)
0 ignored issues
show
Unused Code introduced by
The parameter $at 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

299
    public function billsNumberWithTime($number, $type, $target, /** @scrutinizer ignore-unused */ $at = null, $time = null)

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...
300
    {
301
        $count = count($this->builder->findBills(array_filter([
302
            'type' => $type,
303
            'target' => $target,
304
            'time' => $this->prepareTime($time),
305
        ])));
306
307
        Assert::assertEquals($number, $count);
308
    }
309
310
    /**
311
     * @Given /charges number is (\d+)/
312
     */
313
    public function chargesNumber($number)
314
    {
315
        Assert::assertEquals($number, count($this->charges));
316
    }
317
318
    /**
319
     * @Given /charge for (\S+) is +(\S+) (\S+) per (\S+) (\S+)$/
320
     */
321
    public function charge($type, $amount, $currency, $quantity, $unit)
322
    {
323
        $this->chargeWithTarget($type, $amount, $currency, $quantity, $unit, null);
324
    }
325
326
    /**
327
     * @Given /charge for (\S+) is +(\S+) (\S+) per +(\S+) (\S+) +for target (.+?)( +at (\S+))?$/
328
     */
329
    public function chargeWithTarget($type, $amount, $currency, $quantity, $unit, $target, $at = null, $time = null)
0 ignored issues
show
Unused Code introduced by
The parameter $at 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

329
    public function chargeWithTarget($type, $amount, $currency, $quantity, $unit, $target, /** @scrutinizer ignore-unused */ $at = null, $time = null)

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...
Unused Code introduced by
The parameter $time 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

329
    public function chargeWithTarget($type, $amount, $currency, $quantity, $unit, $target, $at = null, /** @scrutinizer ignore-unused */ $time = null)

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...
330
    {
331
        $quantity = $this->prepareQuantity($quantity);
332
        $amount = $this->prepareSum($amount, $quantity);
333
        $charge = $this->findCharge($type, $target);
334
        Assert::assertNotNull($charge);
335
        Assert::assertSame($type, $charge->getType()->getName());
336
        Assert::assertSame($target, $charge->getTarget()->getFullName());
337
        Assert::assertEquals(bcmul($amount, 100), (int)$charge->getSum()->getAmount());
338
        Assert::assertSame($currency, $charge->getSum()->getCurrency()->getCode());
339
        Assert::assertEquals((float)$quantity, (float)$charge->getUsage()->getQuantity());
340
        Assert::assertEquals(strtolower($unit), strtolower($charge->getUsage()->getUnit()->getName()));
341
    }
342
343
    public function findCharge($type, $target): ?ChargeInterface
344
    {
345
        foreach ($this->charges as $charge) {
346
            if ($charge->getType()->getName() !== $type) {
347
                continue;
348
            }
349
            if ($charge->getTarget()->getFullName() !== $target) {
350
                continue;
351
            }
352
353
            return $charge;
354
        }
355
356
        return null;
357
    }
358
359
    public function getNextCharge(): ChargeInterface
360
    {
361
        $charge = current($this->charges);
362
        next($this->charges);
363
364
        return $charge;
365
    }
366
367
    /**
368
     * @return string|false|null
369
     */
370
    protected function prepareTime(string $time = null)
371
    {
372
        if ($time === null) {
373
            return null;
374
        }
375
376
        if ($time === 'midnight second day of this month') {
377
            return date('Y-m-02');
378
        }
379
        if (strncmp($time, 'pY', 1) === 0) {
380
            return date(substr($time, 1), strtotime('-1 year'));
381
        }
382
        if (str_contains($time, 'nm')) {
383
            $format = str_replace('nm', 'm', $time);
384
            return date($format, strtotime('next month'));
385
        }
386
        if (str_contains($time, 'pm')) {
387
            $time = str_replace('pm', 'm', $time);
388
            $time = date($time, strtotime('-1 month'));
389
        }
390
        if (strncmp($time, 'Y', 1) === 0) {
391
            return date($time);
392
        }
393
394
        return $time;
395
    }
396
397
    private function prepareQuantity($quantity)
398
    {
399
        if ($quantity[0] === 's') {
400
            return $this->getSaleQuantity();
401
        }
402
403
        return $quantity;
404
    }
405
406
    private function prepareSum($sum, $quantity)
407
    {
408
        if ($sum[0] === 's') {
409
            $sum = round(substr($sum, 1) * $quantity*100)/100;
410
        }
411
412
        return $sum;
413
    }
414
415
    public function getSaleQuantity()
416
    {
417
        return $this->days2quantity(new DateTimeImmutable($this->saleTime));
418
    }
419
420
    private function days2quantity(DateTimeImmutable $from)
421
    {
422
        $till = new DateTimeImmutable('first day of next month midnight');
423
        $diff = $from->diff($till);
424
        if ($diff->m) {
425
            return 1;
426
        }
427
428
        return $diff->d/date('t');
429
    }
430
431
    /**
432
     * @When /^tariff plan change is requested for target "([^"]*)" to plan "([^"]*)" at "([^"]*)"$/
433
     */
434
    public function tariffPlanChangeIsRequestedForTarget(string $target, string $planName, string $date)
435
    {
436
        $this->mayFail(fn () => $this->builder->targetChangePlan($target, $planName, $this->prepareTime($date)));
437
    }
438
439
    /**
440
     * @When /^tariff plan change is requested for target "([^"]*)" to plan "([^"]*)" at "([^"]*)", assuming current time is "([^"]*)"$/
441
     */
442
    public function tariffPlanChangeIsRequestedForTargetAtSpecificTime(string $target, string $planName, string $date, ?string $wallTime = null)
443
    {
444
        $this->mayFail(fn () => $this->builder->targetChangePlan($target, $planName, $this->prepareTime($date), $this->prepareTime($wallTime)));
445
    }
446
447
    /**
448
     * @Then /^target "([^"]*)" is sold to customer by plan "([^"]*)" since "([^"]*)"(?: till "([^"]*)")?$/
449
     */
450
    public function targetIsSoldToCustomerByPlanSinceTill(string $target, string $planName, string $saleDate, ?string $saleCloseDate = null)
451
    {
452
        $sales = $this->builder->findHistoricalSales([
453
            'target' => $target,
454
        ]);
455
456
        $saleDateTime = new DateTimeImmutable('@' . strtotime($this->prepareTime($saleDate)));
457
        $saleCloseDateTime = $saleCloseDate ? new DateTimeImmutable('@' . strtotime($this->prepareTime($saleCloseDate))) : null;
458
459
        foreach ($sales as $sale) {
460
            /** @noinspection PhpBooleanCanBeSimplifiedInspection */
461
            $saleExists = true
462
                && str_contains($sale->getPlan()->getName(), $planName)
463
                && $sale->getTime()->format(DATE_ATOM) === $saleDateTime->format(DATE_ATOM)
464
                && (
465
                    ($saleCloseDate === null && $sale->getCloseTime() === null)
466
                    ||
467
                    ($saleCloseDate !== null && $sale->getCloseTime()->format(DATE_ATOM) === $saleCloseDateTime->format(DATE_ATOM))
468
                );
469
470
            if ($saleExists) {
471
                return;
472
            }
473
        }
474
475
        Assert::fail('Requested sale does not exist');
476
    }
477
478
    /**
479
     * @Then /^target "([^"]*)" has exactly (\d+) sales for customer$/
480
     */
481
    public function targetHasExactlySalesForCustomer(string $target, int $count)
482
    {
483
        $sales = $this->builder->findHistoricalSales([
484
            'target' => $target,
485
        ]);
486
487
        Assert::assertCount($count, $sales);
488
    }
489
490
    /**
491
     * @Then /^caught error is "([^"]*)"$/
492
     */
493
    public function caughtErrorIs(string $errorMessage): void
494
    {
495
        $this->assertCaughtExceptionMatches(\Throwable::class, $errorMessage);
496
    }
497
498
    /**
499
     * @Given /^target "([^"]*)"$/
500
     */
501
    public function target(string $target)
502
    {
503
        $this->builder->buildTarget($target);
504
    }
505
506
    /**
507
     * @Then /^flush entities cache$/
508
     */
509
    public function flushEntitiesCache()
510
    {
511
        $this->builder->flushEntitiesCache();
512
    }
513
514
    /**
515
     * @Given /^target "([^"]*)" has the following uses:$/
516
     */
517
    public function targetHasTheFollowingUses(string $target, TableNode $usesTable)
518
    {
519
        foreach ($usesTable->getColumnsHash() as $row) {
520
            $uses = $this->builder->findUsage($row['time'], $target, $row['type']);
521
            Assert::assertCount(1, $uses);
522
523
            $use = reset($uses);
524
            Assert::assertSame(
525
                $row['unit'], $use['unit'],
526
                sprintf('Exptected unit to be %s, got %s instead', $row['unit'], $use['unit'])
527
            );
528
            Assert::assertEquals(
529
                $row['amount'], $use['total'],
530
                sprintf('Exptected total to be %s, got %s instead', $row['amount'], $use['total'])
531
            );
532
        }
533
    }
534
}
535