CappedBillInterpreter   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 64
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 38
c 2
b 0
f 0
dl 0
loc 64
rs 10
wmc 8

3 Methods

Rating   Name   Duplication   Size   Complexity  
A enforceBoundaries() 0 10 3
A __construct() 0 3 1
A interpret() 0 32 4
1
<?php
2
3
namespace BillingBoss\Interpreter;
4
5
use BillingBoss\AbstractBillInterpreter;
6
use BillingBoss\BillContext;
7
use BillingBoss\Expr;
8
use BillingBoss\RangeHelper;
9
10
/**
11
 * Capped bill interpreter
12
 *
13
 * @package   BillingBoss
14
 * @link      https://github.com/ranskills/billing-boss-php
15
 * @copyright Copyright (c) 2018 Ransford Ako Okpoti
16
 * @license   Refer to the LICENSE distributed with this library
17
 * @since     1.0.0
18
 */
19
final class CappedBillInterpreter extends AbstractBillInterpreter
20
{
21
    private const A =
22
        Expr::PERCENT .
23
        Expr::SPACES .
24
        '\[' .
25
        Expr::SPACES .
26
        Expr::POSITIVE_NUMBER .
27
        Expr::COMMA .
28
        Expr::POSITIVE_NUMBER .
29
        Expr::SPACES .
30
        '\]' .
31
        Expr::COMMA .
32
        Expr::RANGE;
33
34
    public function __construct()
35
    {
36
        parent::__construct(sprintf('/^%1$s(%2$s%1$s)*$/', self::A, Expr::PIPE));
37
    }
38
39
    private function enforceBoundaries($bill, $lowerLimit, $upperLimit)
40
    {
41
        if ($bill > $upperLimit) {
42
            $bill = $upperLimit;
43
        }
44
        if ($bill < $lowerLimit) {
45
            $bill = $lowerLimit;
46
        }
47
48
        return $bill;
49
    }
50
51
    public function interpret(BillContext $context): float
52
    {
53
        $bill = 0.0;
54
55
        if (!$this->isValid($context)) {
56
            return 0.0;
57
        }
58
59
        $parts = preg_split(sprintf('/%s/', Expr::PIPE), $context->getStructure());
60
61
        foreach ($parts as $part) {
62
            $matches = [];
63
64
            \preg_match(sprintf('/^%s$/', self::A), $part, $matches);
65
66
            $percent = $matches[1];
67
            $capMin = $matches[2];
68
            $capMax = $matches[3];
69
            $rangeStart = $matches[4];
70
            $rangeEnd = $matches[5];
71
72
            $amount = $context->getAmount();
73
            if (RangeHelper::isInRange([$rangeStart, $rangeEnd], $amount)) {
74
                $ctxt = new BillContext($amount, $percent . '%' . ', 1 - * ');
75
                $bill = (new PercentageBillInterpreter())->interpret($ctxt);
76
77
                $bill = $this->enforceBoundaries($bill, $capMin, $capMax);
78
                break;
79
            }
80
        }
81
82
        return $bill;
83
    }
84
}
85